@hyperbridge/sdk 1.3.22 → 1.3.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1606,6 +1606,7 @@ declare class ChainConfigService {
1606
1606
  getUniswapV4QuoterAddress(chain: string): HexString;
1607
1607
  getPermit2Address(chain: string): HexString;
1608
1608
  getCoingeckoId(chain: string): string | undefined;
1609
+ getEtherscanApiKey(): string | undefined;
1609
1610
  }
1610
1611
 
1611
1612
  /**
@@ -1854,6 +1855,16 @@ declare function orderCommitment(order: Order): HexString;
1854
1855
  declare function bytes32ToBytes20(bytes32Address: string): HexString;
1855
1856
  declare function bytes20ToBytes32(bytes20Address: string): HexString;
1856
1857
  declare function hexToString(hex: string): string;
1858
+ /**
1859
+ * Retries a promise-returning operation with exponential backoff.
1860
+ * This function will attempt to execute the operation up to maxRetries times,
1861
+ * with an exponential backoff delay between attempts.
1862
+ *
1863
+ * @param operation The async operation to retry
1864
+ * @param retryConfig Configuration object containing retry parameters
1865
+ * @returns Promise that resolves with the operation result or rejects with the last error
1866
+ */
1867
+ declare function retryPromise<T>(operation: () => Promise<T>, retryConfig: RetryConfig): Promise<T>;
1857
1868
  /**
1858
1869
  * Calculates the commitment hash for a get request.
1859
1870
  * @param get The get request to calculate the commitment hash for.
@@ -1881,6 +1892,11 @@ declare function estimateGasForPost(params: {
1881
1892
  */
1882
1893
  declare function constructRedeemEscrowRequestBody(order: Order, beneficiary: HexString): HexString;
1883
1894
  declare function fetchPrice(identifier: string, chainId?: number, apiKey?: string): Promise<number>;
1895
+ /**
1896
+ * Fetches the current network gas price from an Etherscan-family explorer API.
1897
+ * Returns the ProposeGasPrice (in gwei) converted to wei as bigint.
1898
+ */
1899
+ declare function getGasPriceFromEtherscan(chainId: string, apiKey?: string): Promise<bigint>;
1884
1900
  /**
1885
1901
  * ERC20 method signatures used for storage slot detection
1886
1902
  */
@@ -1938,6 +1954,14 @@ declare function getStorageSlot(client: PublicClient, contractAddress: HexString
1938
1954
  * @returns The adjusted fee amount with the target decimal precision
1939
1955
  */
1940
1956
  declare function adjustFeeDecimals(feeInFeeToken: bigint, fromDecimals: number, toDecimals: number): bigint;
1957
+ /**
1958
+ * Chains that should prefer the Etherscan API for gas price lookup
1959
+ */
1960
+ declare const USE_ETHERSCAN_CHAINS: Set<string>;
1961
+ /**
1962
+ * Testnet chains
1963
+ */
1964
+ declare const TESTNET_CHAINS: Set<string>;
1941
1965
 
1942
1966
  interface SubstrateChainParams {
1943
1967
  ws: string;
@@ -2300,6 +2324,16 @@ declare class IndexerClient {
2300
2324
  commitmentTimestamp: bigint;
2301
2325
  chain: string;
2302
2326
  }): Promise<StateMachineUpdate | undefined>;
2327
+ /**
2328
+ * Query for the latest state machine update height
2329
+ * @params statemachineId - ID of the state machine
2330
+ * @params chain - The identifier for the chain where the state machine update should be queried (corresponds to a stateMachineId)
2331
+ * @returns Latest height or undefined if no updates found
2332
+ */
2333
+ queryLatestStateMachineHeight({ statemachineId, chain, }: {
2334
+ statemachineId: string;
2335
+ chain: string;
2336
+ }): Promise<bigint | undefined>;
2303
2337
  /**
2304
2338
  * Queries a request by CommitmentHash
2305
2339
  *
@@ -3195,4 +3229,4 @@ declare const coingeckoIds: {
3195
3229
  "EVM-130": string;
3196
3230
  };
3197
3231
 
3198
- export { ADDRESS_ZERO, type AllStatusKey, type AssetTeleported, type AssetTeleportedResponse, type BlockMetadata, type CancelOptions, type ChainConfig, ChainConfigService, type ChainId, Chains, type ClientConfig, DEFAULT_ADDRESS, DEFAULT_GRAFFITI, DUMMY_PRIVATE_KEY, type DecodedOrderPlacedLog, type DispatchGet, type DispatchPost, ERC20Method, type EstimateGasCallData, EvmChain, type EvmChainParams, type ExecutionResult, type FillOptions, type FillerConfig, type GetRequestResponse, type GetRequestWithStatus, type GetResponseByRequestIdResponse, type GetResponseStorageValues, type HexString, type HostParams, HyperClientStatus, type HyperbridgeTxEvents, type IChain, type IConfig, type IEvmConfig, type IGetRequest, type IGetRequestMessage, type IGetResponse, type IGetResponseMessage, type IHyperbridgeConfig, type IIsmpMessage, type IMessage, type IPostRequest, type IPostResponse, type IProof, type IRequestMessage, type ISubstrateConfig, type ITimeoutPostRequestMessage, IndexerClient, type IndexerQueryClient, IntentGateway, type IntentGatewayParams, type IsmpRequest, type NewDeployment, type Order, type OrderResponse, OrderStatus, type OrderStatusMetadata, type OrderWithStatus, type Params, type PaymentInfo, type PostRequestStatus, type PostRequestTimeoutStatus, type PostRequestWithStatus, REQUEST_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, RESPONSE_COMMITMENTS_SLOT, RESPONSE_RECEIPTS_SLOT, type RequestBody, type RequestCommitment, RequestKind, type RequestResponse, RequestStatus, type RequestStatusKey, type RequestStatusWithMetadata, type ResponseCommitmentWithValues, type RetryConfig, STATE_COMMITMENTS_SLOT, type StateMachineHeight, type StateMachineIdParams, type StateMachineResponse, type StateMachineUpdate, SubstrateChain, type SubstrateChainParams, TeleportStatus, TimeoutStatus, type TimeoutStatusKey, type TokenGatewayAssetTeleportedResponse, type TokenGatewayAssetTeleportedWithStatus, type TokenInfo, type TokenPrice, type TokenPricesResponse, type TokenRegistry, type TokenRegistryResponse, type Transaction, WrappedNativeDecimals, type XcmGatewayParams, __test, addresses, adjustFeeDecimals, assets, bytes20ToBytes32, bytes32ToBytes20, chainIds, coingeckoIds, consensusStateIds, constructRedeemEscrowRequestBody, convertStateIdToStateMachineId, convertStateMachineIdToEnum, createQueryClient, createRpcUrls, encodeISMPMessage, estimateGasForPost, fetchPrice, generateRootWithProof, getChain, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, hexToString, maxBigInt, orderCommitment, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, requestCommitmentKey, teleport, teleportDot, viemChains };
3232
+ export { ADDRESS_ZERO, type AllStatusKey, type AssetTeleported, type AssetTeleportedResponse, type BlockMetadata, type CancelOptions, type ChainConfig, ChainConfigService, type ChainId, Chains, type ClientConfig, DEFAULT_ADDRESS, DEFAULT_GRAFFITI, DUMMY_PRIVATE_KEY, type DecodedOrderPlacedLog, type DispatchGet, type DispatchPost, ERC20Method, type EstimateGasCallData, EvmChain, type EvmChainParams, type ExecutionResult, type FillOptions, type FillerConfig, type GetRequestResponse, type GetRequestWithStatus, type GetResponseByRequestIdResponse, type GetResponseStorageValues, type HexString, type HostParams, HyperClientStatus, type HyperbridgeTxEvents, type IChain, type IConfig, type IEvmConfig, type IGetRequest, type IGetRequestMessage, type IGetResponse, type IGetResponseMessage, type IHyperbridgeConfig, type IIsmpMessage, type IMessage, type IPostRequest, type IPostResponse, type IProof, type IRequestMessage, type ISubstrateConfig, type ITimeoutPostRequestMessage, IndexerClient, type IndexerQueryClient, IntentGateway, type IntentGatewayParams, type IsmpRequest, type NewDeployment, type Order, type OrderResponse, OrderStatus, type OrderStatusMetadata, type OrderWithStatus, type Params, type PaymentInfo, type PostRequestStatus, type PostRequestTimeoutStatus, type PostRequestWithStatus, REQUEST_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, RESPONSE_COMMITMENTS_SLOT, RESPONSE_RECEIPTS_SLOT, type RequestBody, type RequestCommitment, RequestKind, type RequestResponse, RequestStatus, type RequestStatusKey, type RequestStatusWithMetadata, type ResponseCommitmentWithValues, type RetryConfig, STATE_COMMITMENTS_SLOT, type StateMachineHeight, type StateMachineIdParams, type StateMachineResponse, type StateMachineUpdate, SubstrateChain, type SubstrateChainParams, TESTNET_CHAINS, TeleportStatus, TimeoutStatus, type TimeoutStatusKey, type TokenGatewayAssetTeleportedResponse, type TokenGatewayAssetTeleportedWithStatus, type TokenInfo, type TokenPrice, type TokenPricesResponse, type TokenRegistry, type TokenRegistryResponse, type Transaction, USE_ETHERSCAN_CHAINS, WrappedNativeDecimals, type XcmGatewayParams, __test, addresses, adjustFeeDecimals, assets, bytes20ToBytes32, bytes32ToBytes20, chainIds, coingeckoIds, consensusStateIds, constructRedeemEscrowRequestBody, convertStateIdToStateMachineId, convertStateMachineIdToEnum, createQueryClient, createRpcUrls, encodeISMPMessage, estimateGasForPost, fetchPrice, generateRootWithProof, getChain, getGasPriceFromEtherscan, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, hexToString, maxBigInt, orderCommitment, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, requestCommitmentKey, retryPromise, teleport, teleportDot, viemChains };
@@ -3643,6 +3643,9 @@ var ChainConfigService = class {
3643
3643
  getCoingeckoId(chain) {
3644
3644
  return coingeckoIds[chain];
3645
3645
  }
3646
+ getEtherscanApiKey() {
3647
+ return typeof process !== "undefined" ? process?.env?.ETHERSCAN_API_KEY : void 0;
3648
+ }
3646
3649
  };
3647
3650
  function getPeakPosByHeight(height) {
3648
3651
  return (1n << BigInt(height + 1)) - 2n;
@@ -4525,6 +4528,24 @@ async function fetchPrice(identifier, chainId = 1, apiKey) {
4525
4528
  }
4526
4529
  return data[key].usd;
4527
4530
  }
4531
+ async function getGasPriceFromEtherscan(chainId, apiKey) {
4532
+ let parsedChainId = Number(chainId.split("-")[1]);
4533
+ const url = apiKey ? `https://api.etherscan.io/v2/api?chainid=${parsedChainId}&module=gastracker&action=gasoracle&apikey=${apiKey}` : `https://api.etherscan.io/v2/api?chainid=${parsedChainId}&module=gastracker&action=gasoracle`;
4534
+ const response = await fetch(url);
4535
+ const data = await response.json();
4536
+ return gweiToWei(data.result.ProposeGasPrice);
4537
+ }
4538
+ function gweiToWei(gwei) {
4539
+ if (!gwei || typeof gwei !== "string") {
4540
+ throw new Error(`Invalid gwei value: ${gwei}`);
4541
+ }
4542
+ const [intPart, fracPartRaw] = gwei.split(".");
4543
+ const fracPart = (fracPartRaw || "").slice(0, 9);
4544
+ const fracPadded = fracPart.padEnd(9, "0");
4545
+ const whole = BigInt(intPart || "0") * 1000000000n;
4546
+ const fractional = BigInt(fracPadded || "0");
4547
+ return whole + fractional;
4548
+ }
4528
4549
  var ERC20Method = /* @__PURE__ */ ((ERC20Method2) => {
4529
4550
  ERC20Method2["BALANCE_OF"] = "0x70a08231";
4530
4551
  ERC20Method2["ALLOWANCE"] = "0xdd62ed3e";
@@ -4631,6 +4652,8 @@ function adjustFeeDecimals(feeInFeeToken, fromDecimals, toDecimals) {
4631
4652
  return (feeInFeeToken + scaleFactor - 1n) / scaleFactor;
4632
4653
  }
4633
4654
  }
4655
+ var USE_ETHERSCAN_CHAINS = /* @__PURE__ */ new Set(["EVM-137", "EVM-56", "EVM-1"]);
4656
+ var TESTNET_CHAINS = /* @__PURE__ */ new Set(["EVM-10200", "EVM-97"]);
4634
4657
  function replaceWebsocketWithHttp(url) {
4635
4658
  if (url.startsWith("ws://")) {
4636
4659
  return url.replace("ws://", "http://");
@@ -6716,6 +6739,30 @@ query StateMachineUpdatesByTimestamp($statemachineId: String!, $commitmentTimest
6716
6739
  }
6717
6740
  }
6718
6741
  `;
6742
+ var LATEST_STATE_MACHINE_UPDATE = `
6743
+ query LatestStateMachineUpdate($statemachineId: String!, $chain: String!) {
6744
+ stateMachineUpdateEvents(
6745
+ filter: {
6746
+ and: [
6747
+ { stateMachineId: { equalTo: $statemachineId } }
6748
+ { chain: { equalTo: $chain } }
6749
+ ]
6750
+ }
6751
+ orderBy: HEIGHT_DESC
6752
+ first: 1
6753
+ ) {
6754
+ nodes {
6755
+ height
6756
+ stateMachineId
6757
+ chain
6758
+ blockHash
6759
+ blockNumber
6760
+ transactionHash
6761
+ createdAt
6762
+ }
6763
+ }
6764
+ }
6765
+ `;
6719
6766
  var ASSET_TELEPORTED_BY_PARAMS = `
6720
6767
  query AssetTeleportedByParams($id: String!) {
6721
6768
  assetTeleported(id: $id) {
@@ -7105,6 +7152,32 @@ var IndexerClient = class {
7105
7152
  logger.trace("Response >", first_node);
7106
7153
  return first_node;
7107
7154
  }
7155
+ /**
7156
+ * Query for the latest state machine update height
7157
+ * @params statemachineId - ID of the state machine
7158
+ * @params chain - The identifier for the chain where the state machine update should be queried (corresponds to a stateMachineId)
7159
+ * @returns Latest height or undefined if no updates found
7160
+ */
7161
+ async queryLatestStateMachineHeight({
7162
+ statemachineId,
7163
+ chain
7164
+ }) {
7165
+ const logger = this.logger.withTag("[queryLatestStateMachineHeight]()");
7166
+ const message = `querying latest StateMachineId(${statemachineId}) height in chain Chain(${chain})`;
7167
+ const response = await this.withRetry(
7168
+ () => {
7169
+ return this.client.request(LATEST_STATE_MACHINE_UPDATE, {
7170
+ statemachineId,
7171
+ chain
7172
+ });
7173
+ },
7174
+ { logger, logMessage: message }
7175
+ );
7176
+ const first_node = response?.stateMachineUpdateEvents?.nodes[0];
7177
+ if (!first_node) return void 0;
7178
+ logger.trace("Latest height >", first_node.height);
7179
+ return BigInt(first_node.height);
7180
+ }
7108
7181
  /**
7109
7182
  * Queries a request by CommitmentHash
7110
7183
  *
@@ -11026,7 +11099,15 @@ var IntentGateway = class {
11026
11099
  */
11027
11100
  async convertGasToFeeToken(gasEstimate, gasEstimateIn, evmChainID) {
11028
11101
  const client = this[gasEstimateIn].client;
11029
- const gasPrice = await client.getGasPrice();
11102
+ const useEtherscan = USE_ETHERSCAN_CHAINS.has(evmChainID);
11103
+ const etherscanApiKey = useEtherscan ? this[gasEstimateIn].config.getEtherscanApiKey() : void 0;
11104
+ const gasPrice = useEtherscan && etherscanApiKey ? await retryPromise(() => getGasPriceFromEtherscan(evmChainID, etherscanApiKey), {
11105
+ maxRetries: 3,
11106
+ backoffMs: 250
11107
+ }).catch(async () => {
11108
+ console.warn({ evmChainID }, "Error getting gas price from etherscan, using client's gas price");
11109
+ return await client.getGasPrice();
11110
+ }) : await client.getGasPrice();
11030
11111
  const gasCostInWei = gasEstimate * gasPrice;
11031
11112
  const wethAddr = this[gasEstimateIn].config.getWrappedNativeAssetWithDecimals(evmChainID).asset;
11032
11113
  const feeToken = await this[gasEstimateIn].getFeeTokenWithDecimals();
@@ -12239,13 +12320,17 @@ var IntentGateway = class {
12239
12320
  let lastFailedHeight = null;
12240
12321
  let proofHex = null;
12241
12322
  while (!proofHex) {
12242
- latestHeight = await retryPromise(
12243
- () => hyperbridge.latestStateMachineHeight({
12244
- stateId: parseStateMachineId(destStateMachine).stateId,
12245
- consensusStateId: destConsensusStateId
12323
+ const height = await retryPromise(
12324
+ () => indexerClient.queryLatestStateMachineHeight({
12325
+ statemachineId: destStateMachine,
12326
+ chain: hyperbridgeConfig.stateMachineId
12246
12327
  }),
12247
12328
  { maxRetries: 5, backoffMs: 500, logMessage: "Failed to fetch latest state machine height" }
12248
12329
  );
12330
+ if (!height) {
12331
+ throw new Error("No state machine updates found for destination chain");
12332
+ }
12333
+ latestHeight = height;
12249
12334
  const shouldFetchProof = lastFailedHeight === null ? latestHeight > order.deadline : latestHeight > lastFailedHeight;
12250
12335
  if (!shouldFetchProof) {
12251
12336
  yield {
@@ -12317,9 +12402,9 @@ var IntentGateway = class {
12317
12402
  break;
12318
12403
  }
12319
12404
  const nextHeight = await retryPromise(
12320
- () => hyperbridge.latestStateMachineHeight({
12321
- stateId: parseStateMachineId(sourceStateMachine).stateId,
12322
- consensusStateId: sourceConsensusStateId
12405
+ () => indexerClient.queryLatestStateMachineHeight({
12406
+ statemachineId: sourceStateMachine,
12407
+ chain: hyperbridgeConfig.stateMachineId
12323
12408
  }),
12324
12409
  {
12325
12410
  maxRetries: 5,
@@ -12327,6 +12412,11 @@ var IntentGateway = class {
12327
12412
  logMessage: "Failed to fetch latest state machine height (post-source-proof failure)"
12328
12413
  }
12329
12414
  );
12415
+ if (!nextHeight) {
12416
+ throw new Error(
12417
+ `No state machine updates found for ${sourceStateMachine} on chain ${hyperbridgeConfig.stateMachineId}`
12418
+ );
12419
+ }
12330
12420
  if (nextHeight <= failedHeight) {
12331
12421
  await sleep(1e4);
12332
12422
  continue;
@@ -12746,6 +12836,6 @@ async function teleportDot(param_) {
12746
12836
  return stream;
12747
12837
  }
12748
12838
 
12749
- export { ADDRESS_ZERO, ChainConfigService, Chains, DEFAULT_ADDRESS, DEFAULT_GRAFFITI, DUMMY_PRIVATE_KEY, ERC20Method, EvmChain, HyperClientStatus, IndexerClient, IntentGateway, OrderStatus, REQUEST_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, RESPONSE_COMMITMENTS_SLOT, RESPONSE_RECEIPTS_SLOT, RequestKind, RequestStatus, STATE_COMMITMENTS_SLOT, SubstrateChain, TeleportStatus, TimeoutStatus, WrappedNativeDecimals, __test, addresses, adjustFeeDecimals, assets, bytes20ToBytes32, bytes32ToBytes20, chainIds, coingeckoIds, consensusStateIds, constructRedeemEscrowRequestBody, convertStateIdToStateMachineId, convertStateMachineIdToEnum, createQueryClient, createRpcUrls, encodeISMPMessage, estimateGasForPost, fetchPrice, generateRootWithProof, getChain, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, hexToString, maxBigInt, orderCommitment, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, requestCommitmentKey, teleport, teleportDot, viemChains };
12839
+ export { ADDRESS_ZERO, ChainConfigService, Chains, DEFAULT_ADDRESS, DEFAULT_GRAFFITI, DUMMY_PRIVATE_KEY, ERC20Method, EvmChain, HyperClientStatus, IndexerClient, IntentGateway, OrderStatus, REQUEST_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, RESPONSE_COMMITMENTS_SLOT, RESPONSE_RECEIPTS_SLOT, RequestKind, RequestStatus, STATE_COMMITMENTS_SLOT, SubstrateChain, TESTNET_CHAINS, TeleportStatus, TimeoutStatus, USE_ETHERSCAN_CHAINS, WrappedNativeDecimals, __test, addresses, adjustFeeDecimals, assets, bytes20ToBytes32, bytes32ToBytes20, chainIds, coingeckoIds, consensusStateIds, constructRedeemEscrowRequestBody, convertStateIdToStateMachineId, convertStateMachineIdToEnum, createQueryClient, createRpcUrls, encodeISMPMessage, estimateGasForPost, fetchPrice, generateRootWithProof, getChain, getGasPriceFromEtherscan, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, hexToString, maxBigInt, orderCommitment, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, requestCommitmentKey, retryPromise, teleport, teleportDot, viemChains };
12750
12840
  //# sourceMappingURL=index.js.map
12751
12841
  //# sourceMappingURL=index.js.map