Skip to content

fix(sdk-coin-soneium): update recoveryBlockchainExplorerQuery #6537

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion modules/sdk-coin-soneium/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
"@bitgo/abstract-eth": "^24.8.1",
"@bitgo/sdk-core": "^35.8.0",
"@bitgo/statics": "^55.2.0",
"@ethereumjs/common": "^2.6.5"
"@ethereumjs/common": "^2.6.5",
"ethereumjs-util": "^7.1.5",
"superagent": "^10.2.3"
},
"devDependencies": {
"@bitgo/sdk-api": "^1.65.1",
Expand Down
70 changes: 69 additions & 1 deletion modules/sdk-coin-soneium/src/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { NetworkType } from '@bitgo/statics';
import EthereumCommon from '@ethereumjs/common';
import { InvalidTransactionError } from '@bitgo/sdk-core';
import { InvalidTransactionError, common } from '@bitgo/sdk-core';
import { mainnetCommon, testnetCommon } from './resources';
import { recoveryBlockchainExplorerQuery as abstractRecoveryQuery } from '@bitgo/abstract-eth';
import request from 'superagent';
import { addHexPrefix } from 'ethereumjs-util';

const RESPONSE_STATUS_ERROR = '0';
const RESPONSE_MESSAGE_NOTOK = 'NOTOK';

const commons: Map<NetworkType, EthereumCommon> = new Map<NetworkType, EthereumCommon>([
[NetworkType.MAINNET, mainnetCommon],
Expand All @@ -19,3 +25,65 @@ export function getCommon(network: NetworkType): EthereumCommon {
}
return common;
}

/**
* Handle standard blockchain explorer query
* @param query Query parameters
* @param bitgoEnv BitGo environment
* @returns Response from soneium.network
*/
async function handleStandardExplorerQuery(query: Record<string, string>, bitgoEnv: string): Promise<any> {
const apiToken = common.Environments[bitgoEnv].soneiumExplorerApiToken;
const explorerUrl = common.Environments[bitgoEnv].soneiumExplorerBaseUrl;
return await abstractRecoveryQuery(query, explorerUrl as string, apiToken);
}

/**
* Handle proxy blockchain explorer query
* @param query Query parameters
* @param bitgoEnv BitGo environment
* @returns Response from soneium.network
*/
async function handleProxyExplorerQuery(query: Record<string, string>, bitgoEnv: string): Promise<any> {
const body = {
jsonrpc: '2.0',
method: query.action,
params: [
{
to: query.to,
data: addHexPrefix(query.data),
},
query.tag || 'latest',
],
id: 1,
};

const response = await request.post(common.Environments[bitgoEnv].soneiumExplorerBaseUrl + '/api/eth-rpc').send(body);

if (!response.ok) {
throw new Error('Could not reach soneium.network');
}

if (response.body.status === RESPONSE_STATUS_ERROR && response.body.message === RESPONSE_MESSAGE_NOTOK) {
throw new Error('Soneium.network rate limit reached');
}

return response.body;
}

/**
* Make a query to soneium.network for information such as balance, token balance, solidity calls
* @param query Query parameters
* @param bitgoEnv BitGo environment
* @returns Response from soneium.network
*/
export async function recoveryBlockchainExplorerQuery(query: Record<string, string>, bitgoEnv: string): Promise<any> {
try {
if (query.module === 'proxy') {
return await handleProxyExplorerQuery(query, bitgoEnv);
}
return await handleStandardExplorerQuery(query, bitgoEnv);
} catch (error) {
throw new Error(`Could not query soneium explorer, error: ${error?.message || 'Unknown error'}`);
}
}
20 changes: 5 additions & 15 deletions modules/sdk-coin-soneium/src/soneium.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,11 @@
* @coinWebsite https://docs.soneium.org/soneium-chain/quick-start/info
*/

import { BaseCoin, BitGoBase, common, MPCAlgorithm, MultisigType, multisigTypes } from '@bitgo/sdk-core';
import { BaseCoin, BitGoBase, MPCAlgorithm, MultisigType, multisigTypes } from '@bitgo/sdk-core';
import { BaseCoin as StaticsBaseCoin, coins, ethGasConfigs } from '@bitgo/statics';
import {
AbstractEthLikeNewCoins,
recoveryBlockchainExplorerQuery,
UnsignedSweepTxMPCv2,
RecoverOptions,
OfflineVaultTxInfo,
} from '@bitgo/abstract-eth';
import { AbstractEthLikeNewCoins, UnsignedSweepTxMPCv2, RecoverOptions, OfflineVaultTxInfo } from '@bitgo/abstract-eth';
import { TransactionBuilder } from './lib';
import * as utils from './lib/utils';

export class Soneium extends AbstractEthLikeNewCoins {
protected constructor(bitgo: BitGoBase, staticsCoin?: Readonly<StaticsBaseCoin>) {
Expand Down Expand Up @@ -56,13 +51,8 @@ export class Soneium extends AbstractEthLikeNewCoins {
* @param {string} apiKey optional API key to use instead of the one from the environment
* @returns {Promise<Object>} response from Soneium explorer
*/
async recoveryBlockchainExplorerQuery(
query: Record<string, string>,
apiKey?: string
): Promise<Record<string, unknown>> {
const apiToken = apiKey || common.Environments[this.bitgo.getEnv()].soneiumExplorerApiToken;
const explorerUrl = common.Environments[this.bitgo.getEnv()].soneiumExplorerBaseUrl;
return await recoveryBlockchainExplorerQuery(query, explorerUrl as string, apiToken);
async recoveryBlockchainExplorerQuery(query: Record<string, any>): Promise<any> {
return await utils.recoveryBlockchainExplorerQuery(query, this.bitgo.getEnv());
}

/**
Expand Down
18 changes: 8 additions & 10 deletions modules/sdk-coin-soneium/src/soneiumToken.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { coins, EthLikeTokenConfig } from '@bitgo/statics';
import { BitGoBase, CoinConstructor, common, MPCAlgorithm, NamedCoinConstructor } from '@bitgo/sdk-core';
import { CoinNames, EthLikeToken, recoveryBlockchainExplorerQuery } from '@bitgo/abstract-eth';

import { BitGoBase, CoinConstructor, MPCAlgorithm, NamedCoinConstructor } from '@bitgo/sdk-core';
import { CoinNames, EthLikeToken } from '@bitgo/abstract-eth';
import { TransactionBuilder } from './lib';
import * as utils from './lib/utils';

export { EthLikeTokenConfig };

Expand Down Expand Up @@ -40,14 +40,12 @@ export class SoneiumToken extends EthLikeToken {
}

/**
* Make a query to Soneium blockchain explorer for information such as balance, token balance, solidity calls
* @param {Object} query key-value pairs of parameters to append after /api
* @returns {Promise<Object>} response Soneium explorer
* Make a query to soneium.network for information such as balance, token balance, solidity calls
* @param {Object} query key-value pairs of parameters to append after /api
* @returns {Promise<Object>} response from soneium.network
*/
async recoveryBlockchainExplorerQuery(query: Record<string, string>): Promise<Record<string, unknown>> {
const apiToken = common.Environments[this.bitgo.getEnv()].soneiumExplorerApiToken;
const explorerUrl = common.Environments[this.bitgo.getEnv()].soneiumExplorerBaseUrl;
return await recoveryBlockchainExplorerQuery(query, explorerUrl as string, apiToken);
async recoveryBlockchainExplorerQuery(query: Record<string, any>): Promise<any> {
return await utils.recoveryBlockchainExplorerQuery(query, this.bitgo.getEnv());
}

getFullName(): string {
Expand Down
2 changes: 1 addition & 1 deletion modules/sdk-core/src/bitgo/environments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ const mainnetBase: EnvironmentTemplate = {
icpNodeUrl: 'https://ic0.app',
worldExplorerBaseUrl: 'https://worldscan.org/',
somniaExplorerBaseUrl: 'https://mainnet.somnia.w3us.site/',
soneiumExplorerBaseUrl: 'https://soneium-minato.blockscout.com',
soneiumExplorerBaseUrl: 'https://soneium.blockscout.com',
monExplorerBaseUrl: 'https://mainnet-beta.monvision.io',
stxNodeUrl: 'https://api.hiro.so',
vetNodeUrl: 'https://rpc-mainnet.vechain.energy',
Expand Down