@hyperbridge/sdk 1.4.9 → 1.5.0-rc0000000001

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.
package/README.md CHANGED
@@ -141,6 +141,104 @@ const hyperbridge = new SubstrateChain({
141
141
  const proof = await hyperbridge.queryStateProof(blockNumber, keys)
142
142
  ```
143
143
 
144
+ ### TokenGateway - Cross-Chain Token Transfers
145
+
146
+ The TokenGateway class provides methods for estimating fees and managing cross-chain token teleports via Hyperbridge. Supports both EVM and Substrate chains as destination.
147
+
148
+ ```ts
149
+ import { TokenGateway, EvmChain, SubstrateChain } from "@hyperbridge/sdk"
150
+ import { keccak256, toHex, pad, parseEther } from "viem"
151
+
152
+ // Create chain instances
153
+ const sourceChain = new EvmChain({
154
+ chainId: 97, // BSC Testnet
155
+ rpcUrl: "https://data-seed-prebsc-1-s1.binance.org:8545",
156
+ host: "0x...", // IsmpHost contract address
157
+ consensusStateId: "BSC0"
158
+ })
159
+
160
+ const destChain = new EvmChain({
161
+ chainId: 10200, // Gnosis Chiado
162
+ rpcUrl: "https://rpc.chiadochain.net",
163
+ host: "0x...", // IsmpHost contract address
164
+ consensusStateId: "GNO0"
165
+ })
166
+
167
+ // Initialize TokenGateway (destination can be EvmChain or SubstrateChain)
168
+ const tokenGateway = new TokenGateway({
169
+ source: sourceChain,
170
+ dest: destChain // EvmChain or SubstrateChain
171
+ })
172
+
173
+ // Estimate fees for a teleport
174
+ const assetId = keccak256(toHex("USDC")) // Asset identifier
175
+ const recipientAddress = pad("0xRecipientAddress", { size: 32 })
176
+
177
+ const teleportParams = {
178
+ amount: parseEther("100"), // Amount to teleport
179
+ assetId: assetId,
180
+ redeem: true, // Redeem as ERC20 on destination
181
+ to: recipientAddress,
182
+ dest: "EVM-10200", // Destination chain
183
+ timeout: 3600n, // Timeout in seconds
184
+ data: "0x" // Optional call data
185
+ }
186
+
187
+ // Get native cost estimate (protocol + relayer fees)
188
+ // For EVM destination chains, the relayer fee is automatically estimated by:
189
+ // 1. Creating a dummy post request with 191 bytes of random data
190
+ // 2. Estimating gas for delivery on the destination chain
191
+ // 3. Converting gas cost to native tokens and adding 1% buffer
192
+ // 4. Converting relayer fee to source fee token using getAmountsOut
193
+ // For Substrate destination chains, relayer fee is set to zero
194
+ // Returns: totalNativeCost (protocol fee with 1% buffer) and relayerFeeInSourceFeeToken
195
+ const { totalNativeCost, relayerFeeInSourceFeeToken } = await tokenGateway.quoteNative(teleportParams)
196
+ console.log(`Total native cost: ${totalNativeCost} wei`)
197
+ console.log(`Relayer fee in fee token: ${relayerFeeInSourceFeeToken}`)
198
+
199
+ // Example with Substrate destination
200
+ const substrateDestChain = new SubstrateChain({
201
+ stateMachineId: "KUSAMA-4009",
202
+ wsUrl: "wss://gargantua.polytope.technology",
203
+ hasher: "Keccak",
204
+ consensusStateId: "PAS0"
205
+ })
206
+
207
+ const tokenGatewayToSubstrate = new TokenGateway({
208
+ source: sourceChain,
209
+ dest: substrateDestChain // SubstrateChain destination
210
+ })
211
+
212
+ // For Substrate destinations, relayer fee will be 0
213
+ const { totalNativeCost: substrateCost, relayerFeeInSourceFeeToken: substrateRelayerFee } =
214
+ await tokenGatewayToSubstrate.quoteNative({
215
+ amount: parseEther("100"),
216
+ assetId: assetId,
217
+ redeem: true,
218
+ to: recipientAddress,
219
+ dest: "KUSAMA-4009",
220
+ timeout: 3600n
221
+ })
222
+ console.log(`Substrate destination - Native cost: ${substrateCost} wei`)
223
+ console.log(`Substrate destination - Relayer fee: ${substrateRelayerFee}`) // Will be 0
224
+
225
+ // Get token addresses
226
+ const erc20Address = await tokenGateway.getErc20Address(assetId)
227
+ const erc6160Address = await tokenGateway.getErc6160Address(assetId)
228
+
229
+ // Get gateway parameters
230
+ const params = await tokenGateway.getParams()
231
+ console.log(`Host: ${params.host}, Dispatcher: ${params.dispatcher}`)
232
+ ```
233
+
234
+ **TokenGateway Methods:**
235
+
236
+ - `quoteNative(params)` - Estimate native token cost for a teleport operation. For EVM destination chains, the relayer fee is automatically estimated by generating a dummy post request with 191 bytes of random data, estimating gas on the destination chain, converting to native tokens, and adding a 1% buffer to the relayer fee. The relayer fee is then converted to source chain fee token using Uniswap V2's `getAmountsOut`. For Substrate destinations, relayer fee is set to zero. Returns an object with `totalNativeCost` (relayer fee + protocol fee, both with 1% buffers) and `relayerFeeInSourceFeeToken` (relayer fee converted to source chain fee token).
237
+ - `getErc20Address(assetId)` - Get the ERC20 contract address for an asset
238
+ - `getErc6160Address(assetId)` - Get the ERC6160 (hyper-fungible) contract address for an asset
239
+ - `getInstanceAddress(destination)` - Get the TokenGateway address on the destination chain
240
+ - `getParams()` - Get the TokenGateway contract parameters (host and dispatcher addresses)
241
+
144
242
  ## Vite Integration
145
243
 
146
244
  If you're using Vite in your project, Hyperbridge SDK includes a plugin to handle WebAssembly dependencies correctly.
@@ -169,9 +267,10 @@ The plugin automatically copies the necessary WebAssembly files to the correct l
169
267
 
170
268
  ### Classes
171
269
 
172
- - IndexerClient - Main client for interacting with the indexer
173
- - EvmChain - Utilities for EVM chain interaction
174
- - SubstrateChain - Utilities for Substrate chain interaction
270
+ - **IndexerClient** - Main client for interacting with the indexer
271
+ - **EvmChain** - Utilities for EVM chain interaction
272
+ - **SubstrateChain** - Utilities for Substrate chain interaction
273
+ - **TokenGateway** - Utilities for cross-chain token transfers and fee estimation
175
274
 
176
275
  ### Types
177
276
 
@@ -2,7 +2,8 @@ import { ConsolaInstance } from 'consola';
2
2
  import { GraphQLClient } from 'graphql-request';
3
3
  import { PublicClient, Hex, ContractFunctionArgs, Log } from 'viem';
4
4
  import { ApiPromise } from '@polkadot/api';
5
- import { SignerOptions } from '@polkadot/api/types';
5
+ import { SignerOptions, SubmittableExtrinsic } from '@polkadot/api/types';
6
+ import { ISubmittableResult } from '@polkadot/types/types';
6
7
  import { Chain } from 'viem/chains';
7
8
 
8
9
  declare const _default: {
@@ -590,6 +591,7 @@ declare class ChainConfigService {
590
591
  constructor(env?: NodeJS.ProcessEnv);
591
592
  getChainConfig(chain: string): ChainConfig;
592
593
  getIntentGatewayAddress(chain: string): `0x${string}`;
594
+ getTokenGatewayAddress(chain: string): `0x${string}`;
593
595
  getHostAddress(chain: string): `0x${string}`;
594
596
  getWrappedNativeAssetWithDecimals(chain: string): {
595
597
  asset: HexString;
@@ -3079,6 +3081,15 @@ declare class IntentGateway {
3079
3081
  * @returns True if the order has been filled, false otherwise
3080
3082
  */
3081
3083
  isOrderFilled(order: Order): Promise<boolean>;
3084
+ /**
3085
+ * Checks if an order has been refunded by verifying the escrowed token amounts on-chain.
3086
+ * Reads the storage slots for the `_orders` mapping on the source chain (where the escrow is held).
3087
+ * An order is considered refunded when all input token amounts in the `_orders` mapping are 0.
3088
+ *
3089
+ * @param order - The order to check
3090
+ * @returns True if the order has been refunded (all token amounts are 0), false otherwise
3091
+ */
3092
+ isOrderRefunded(order: Order): Promise<boolean>;
3082
3093
  private submitAndConfirmReceipt;
3083
3094
  /**
3084
3095
  * Returns the native token amount required to dispatch a cancellation GET request for the given order.
@@ -3170,6 +3181,124 @@ type CancelEvent = {
3170
3181
  };
3171
3182
  }[keyof CancelEventMap];
3172
3183
 
3184
+ /**
3185
+ * Result of the quoteNative fee estimation
3186
+ */
3187
+ interface QuoteNativeResult {
3188
+ /** Total native token cost including relayer fee and protocol fee with 1% buffer */
3189
+ totalNativeCost: bigint;
3190
+ /** Relayer fee converted to source chain fee token */
3191
+ relayerFeeInSourceFeeToken: bigint;
3192
+ }
3193
+ /**
3194
+ * Parameters for token gateway teleport operations
3195
+ */
3196
+ interface TeleportParams {
3197
+ /** Amount to be sent */
3198
+ amount: bigint;
3199
+ /** The token identifier to send */
3200
+ assetId: HexString;
3201
+ /** Redeem ERC20 on the destination? */
3202
+ redeem: boolean;
3203
+ /** Recipient address */
3204
+ to: HexString;
3205
+ /** Recipient state machine */
3206
+ dest: string | Uint8Array;
3207
+ /** Request timeout in seconds */
3208
+ timeout: bigint;
3209
+ /** Destination contract call data */
3210
+ data?: HexString | Uint8Array;
3211
+ }
3212
+ /**
3213
+ * TokenGateway class for managing cross-chain token transfers via Hyperbridge
3214
+ *
3215
+ * This class provides methods to interact with the TokenGateway contract, including
3216
+ * estimating fees for cross-chain token teleports.
3217
+ *
3218
+ * Supports both EVM and Substrate chains as destination.
3219
+ *
3220
+ * @example
3221
+ * ```typescript
3222
+ * const tokenGateway = new TokenGateway({
3223
+ * source: sourceChain,
3224
+ * dest: destChain // Can be EvmChain or SubstrateChain
3225
+ * })
3226
+ *
3227
+ * const teleportParams: TeleportParams = {
3228
+ * amount: parseEther("1.0"),
3229
+ * assetId: keccak256(toHex("USDC")),
3230
+ * redeem: true,
3231
+ * to: pad("0xRecipientAddress", { size: 32 }),
3232
+ * dest: "EVM-1",
3233
+ * timeout: 3600n,
3234
+ * }
3235
+ *
3236
+ * // Estimate native cost (relayer fee + protocol fee with 1% buffer)
3237
+ * const { totalNativeCost, relayerFeeInSourceFeeToken } = await tokenGateway.quoteNative(teleportParams)
3238
+ * console.log(`Total native cost: ${formatEther(totalNativeCost)} ETH`)
3239
+ * console.log(`Relayer fee in fee token: ${relayerFeeInSourceFeeToken}`)
3240
+ * ```
3241
+ */
3242
+ declare class TokenGateway {
3243
+ private readonly source;
3244
+ private readonly dest;
3245
+ constructor(params: {
3246
+ source: EvmChain;
3247
+ dest: EvmChain | SubstrateChain;
3248
+ });
3249
+ /**
3250
+ * Get the TokenGateway contract address for a given chain
3251
+ *
3252
+ * @param chain - The chain identifier (e.g., "EVM-1", "EVM-56")
3253
+ * @returns The TokenGateway contract address
3254
+ */
3255
+ private getTokenGatewayAddress;
3256
+ /**
3257
+ * Estimate the native token cost for a token gateway teleport operation.
3258
+ * This includes both relayer fees and protocol fees for cross-chain delivery.
3259
+ *
3260
+ * The relayer fee is automatically estimated for EVM destination chains by:
3261
+ * 1. Creating a dummy post request with 191 bytes of random data in the body
3262
+ * 2. Estimating gas for delivery on the destination chain
3263
+ * 3. Converting the gas estimate to native tokens
3264
+ * 4. Adding a 1% buffer to the relayer fee for safety margin
3265
+ *
3266
+ * For non-EVM destination chains, the relayer fee is set to zero.
3267
+ *
3268
+ * The function then constructs a proper post request and calls quoteNative on the
3269
+ * source chain to get protocol fees (with 1% buffer), converts the relayer fee to
3270
+ * source chain fee token using Uniswap V2's getAmountsOut, and returns both values.
3271
+ *
3272
+ * @param params - The teleport parameters
3273
+ * @returns Object containing totalNativeCost (with 1% buffer) and relayerFeeInSourceFeeToken
3274
+ *
3275
+ * @throws Will throw an error if the contract call fails
3276
+ *
3277
+ * @example
3278
+ * ```typescript
3279
+ * const params: TeleportParams = {
3280
+ * amount: parseEther("1.0"),
3281
+ * assetId: keccak256(toHex("USDC")),
3282
+ * redeem: true,
3283
+ * to: pad("0xRecipientAddress", { size: 32 }),
3284
+ * dest: "EVM-1",
3285
+ * timeout: 3600n,
3286
+ * data: "0x"
3287
+ * }
3288
+ *
3289
+ * const { totalNativeCost, relayerFeeInSourceFeeToken } = await tokenGateway.quoteNative(params)
3290
+ * console.log(`Total native cost: ${formatEther(totalNativeCost)} ETH`)
3291
+ * console.log(`Relayer fee in fee token: ${relayerFeeInSourceFeeToken}`)
3292
+ * ```
3293
+ */
3294
+ quoteNative(params: TeleportParams): Promise<QuoteNativeResult>;
3295
+ /**
3296
+ * Convert native token amount to fee token amount using Uniswap V2 router
3297
+ * @private
3298
+ */
3299
+ private convertNativeToFeeToken;
3300
+ }
3301
+
3173
3302
  /**
3174
3303
  * Extracts the IntentGateway OrderPlaced event from a transaction hash.
3175
3304
  * @param client - A viem PublicClient-compatible instance
@@ -3364,6 +3493,44 @@ declare function teleport(teleport_param: {
3364
3493
  apiPromise: ApiPromise;
3365
3494
  options: Partial<SignerOptions>;
3366
3495
  }): Promise<ReadableStream<HyperbridgeTxEvents>>;
3496
+ /**
3497
+ * Teleports assets from Substrate to other chains via the token gateway
3498
+ *
3499
+ * Note: There is no guarantee that both Dispatched and Finalized events will be yielded.
3500
+ * Consumers should listen for either one of these events instead of expecting both.
3501
+ *
3502
+ *
3503
+ * @param apiPromise - Polkadot API instance
3504
+ * @param params - Teleport parameters
3505
+ * @param params.symbol - Asset symbol
3506
+ * @param params.destination - Target state machine ID
3507
+ * @param params.recipient - Recipient address
3508
+ * @param params.amount - Amount to teleport
3509
+ * @param params.timeout - Operation timeout
3510
+ * @param params.tokenGatewayAddress - Gateway contract address
3511
+ * @param params.relayerFee - Fee for the relayer
3512
+ * @param params.redeem - Whether to redeem on arrival
3513
+ * @param params.callData - Optional additional call data
3514
+ * @yields {HyperbridgeTxEvents} Stream of events indicating transaction status
3515
+ * @throws Error when asset ID is unknown or transaction fails
3516
+ */
3517
+ declare function makeTeleportExtrinsics(teleport_param: {
3518
+ params: Params;
3519
+ apiPromise: ApiPromise;
3520
+ }): Promise<SubmittableExtrinsic<"promise", ISubmittableResult>>;
3521
+ /**
3522
+ *
3523
+ * @param extrinsic - SubmittableExtrinsic
3524
+ * @param who - SS58Address
3525
+ * @param options - Signer options
3526
+ * @returns
3527
+ */
3528
+ declare function submitExtrinsics({ extrinsics: tx, who, options, apiPromise, }: {
3529
+ extrinsics: SubmittableExtrinsic<"promise", any>;
3530
+ apiPromise: ApiPromise;
3531
+ who: string;
3532
+ options: Partial<SignerOptions>;
3533
+ }): ReadableStream<HyperbridgeTxEvents>;
3367
3534
 
3368
3535
  declare enum Chains {
3369
3536
  BSC_CHAPEL = "EVM-97",
@@ -3502,4 +3669,4 @@ declare const popularTokens: {
3502
3669
  "EVM-130": string[];
3503
3670
  };
3504
3671
 
3505
- 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 DecodedPostRequestEvent, type DecodedPostResponseEvent, 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, type StorageFacade, SubstrateChain, 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, convertCodecToIGetRequest, convertCodecToIProof, convertIGetRequestToCodec, convertIProofToCodec, convertStateIdToStateMachineId, convertStateMachineEnumToString, convertStateMachineIdToEnum, createChain, createEvmChain, createIndexerClient, createQueryClient, createRpcUrls, encodeISMPMessage, estimateGasForPost, fetchPrice, generateRootWithProof, getChain, getGasPriceFromEtherscan, getOrderPlacedFromTx, getPostRequestEventFromTx, getPostResponseEventFromTx, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, hexToString, maxBigInt, orderCommitment, popularTokens, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, requestCommitmentKey, retryPromise, teleport, teleportDot, viemChains };
3672
+ 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 DecodedPostRequestEvent, type DecodedPostResponseEvent, 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, type QuoteNativeResult, 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, type StorageFacade, SubstrateChain, TESTNET_CHAINS, type TeleportParams, TeleportStatus, TimeoutStatus, type TimeoutStatusKey, TokenGateway, 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, convertCodecToIGetRequest, convertCodecToIProof, convertIGetRequestToCodec, convertIProofToCodec, convertStateIdToStateMachineId, convertStateMachineEnumToString, convertStateMachineIdToEnum, createChain, createEvmChain, createIndexerClient, createQueryClient, createRpcUrls, encodeISMPMessage, estimateGasForPost, fetchPrice, generateRootWithProof, getChain, getGasPriceFromEtherscan, getOrderPlacedFromTx, getPostRequestEventFromTx, getPostResponseEventFromTx, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, hexToString, makeTeleportExtrinsics, maxBigInt, orderCommitment, popularTokens, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, requestCommitmentKey, retryPromise, submitExtrinsics, teleport, teleportDot, viemChains };
@@ -3471,6 +3471,17 @@ var addresses = {
3471
3471
  ["EVM-137" /* POLYGON_MAINNET */]: "0x1a4ee689a004b10210a1df9f24a387ea13359acf",
3472
3472
  ["EVM-130" /* UNICHAIN_MAINNET */]: "0x1a4ee689a004b10210a1df9f24a387ea13359acf"
3473
3473
  },
3474
+ TokenGateway: {
3475
+ ["EVM-97" /* BSC_CHAPEL */]: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
3476
+ ["EVM-10200" /* GNOSIS_CHIADO */]: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
3477
+ ["EVM-11155111" /* SEPOLIA */]: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
3478
+ ["EVM-1" /* MAINNET */]: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
3479
+ ["EVM-56" /* BSC_MAINNET */]: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
3480
+ ["EVM-42161" /* ARBITRUM_MAINNET */]: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
3481
+ ["EVM-8453" /* BASE_MAINNET */]: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
3482
+ ["EVM-137" /* POLYGON_MAINNET */]: "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E",
3483
+ ["EVM-130" /* UNICHAIN_MAINNET */]: "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E"
3484
+ },
3474
3485
  Host: {
3475
3486
  ["EVM-97" /* BSC_CHAPEL */]: "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7",
3476
3487
  ["EVM-10200" /* GNOSIS_CHIADO */]: "0x58a41b89f4871725e5d898d98ef4bf917601c5eb",
@@ -3662,6 +3673,9 @@ var ChainConfigService = class {
3662
3673
  getIntentGatewayAddress(chain) {
3663
3674
  return addresses.IntentGateway[chain];
3664
3675
  }
3676
+ getTokenGatewayAddress(chain) {
3677
+ return addresses.TokenGateway[chain];
3678
+ }
3665
3679
  getHostAddress(chain) {
3666
3680
  return addresses.Host[chain];
3667
3681
  }
@@ -12883,6 +12897,40 @@ var IntentGateway = class {
12883
12897
  });
12884
12898
  return filledStatus !== "0x0000000000000000000000000000000000000000000000000000000000000000";
12885
12899
  }
12900
+ /**
12901
+ * Checks if an order has been refunded by verifying the escrowed token amounts on-chain.
12902
+ * Reads the storage slots for the `_orders` mapping on the source chain (where the escrow is held).
12903
+ * An order is considered refunded when all input token amounts in the `_orders` mapping are 0.
12904
+ *
12905
+ * @param order - The order to check
12906
+ * @returns True if the order has been refunded (all token amounts are 0), false otherwise
12907
+ */
12908
+ async isOrderRefunded(order) {
12909
+ order = transformOrder(order);
12910
+ const intentGatewayAddress = this.destIntentGatewayAddress ?? this.source.configService.getIntentGatewayAddress(order.sourceChain);
12911
+ const commitment = order.id;
12912
+ const ORDERS_MAPPING_SLOT = 4n;
12913
+ const firstLevelSlot = keccak256(
12914
+ encodeAbiParameters([{ type: "bytes32" }, { type: "uint256" }], [commitment, ORDERS_MAPPING_SLOT])
12915
+ );
12916
+ for (const input of order.inputs) {
12917
+ const tokenAddress = bytes32ToBytes20(input.token);
12918
+ const storageSlot = keccak256(
12919
+ encodeAbiParameters(
12920
+ [{ type: "address" }, { type: "bytes32" }],
12921
+ [tokenAddress, firstLevelSlot]
12922
+ )
12923
+ );
12924
+ const escrowedAmount = await this.source.client.getStorageAt({
12925
+ address: intentGatewayAddress,
12926
+ slot: storageSlot
12927
+ });
12928
+ if (escrowedAmount !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
12929
+ return false;
12930
+ }
12931
+ }
12932
+ return true;
12933
+ }
12886
12934
  async submitAndConfirmReceipt(hyperbridge, commitment, message) {
12887
12935
  let storageValue = await hyperbridge.queryRequestReceipt(commitment);
12888
12936
  if (!storageValue) {
@@ -13163,6 +13211,140 @@ async function fetchSourceProof(commitment, source, sourceStateMachine, sourceCo
13163
13211
  proof: proofHex
13164
13212
  };
13165
13213
  }
13214
+ var TokenGateway = class {
13215
+ source;
13216
+ dest;
13217
+ constructor(params) {
13218
+ this.source = params.source;
13219
+ this.dest = params.dest;
13220
+ }
13221
+ /**
13222
+ * Get the TokenGateway contract address for a given chain
13223
+ *
13224
+ * @param chain - The chain identifier (e.g., "EVM-1", "EVM-56")
13225
+ * @returns The TokenGateway contract address
13226
+ */
13227
+ getTokenGatewayAddress(chain) {
13228
+ const chainStr = typeof chain === "string" ? chain : new TextDecoder().decode(chain);
13229
+ return this.source.configService.getTokenGatewayAddress(chainStr);
13230
+ }
13231
+ /**
13232
+ * Estimate the native token cost for a token gateway teleport operation.
13233
+ * This includes both relayer fees and protocol fees for cross-chain delivery.
13234
+ *
13235
+ * The relayer fee is automatically estimated for EVM destination chains by:
13236
+ * 1. Creating a dummy post request with 191 bytes of random data in the body
13237
+ * 2. Estimating gas for delivery on the destination chain
13238
+ * 3. Converting the gas estimate to native tokens
13239
+ * 4. Adding a 1% buffer to the relayer fee for safety margin
13240
+ *
13241
+ * For non-EVM destination chains, the relayer fee is set to zero.
13242
+ *
13243
+ * The function then constructs a proper post request and calls quoteNative on the
13244
+ * source chain to get protocol fees (with 1% buffer), converts the relayer fee to
13245
+ * source chain fee token using Uniswap V2's getAmountsOut, and returns both values.
13246
+ *
13247
+ * @param params - The teleport parameters
13248
+ * @returns Object containing totalNativeCost (with 1% buffer) and relayerFeeInSourceFeeToken
13249
+ *
13250
+ * @throws Will throw an error if the contract call fails
13251
+ *
13252
+ * @example
13253
+ * ```typescript
13254
+ * const params: TeleportParams = {
13255
+ * amount: parseEther("1.0"),
13256
+ * assetId: keccak256(toHex("USDC")),
13257
+ * redeem: true,
13258
+ * to: pad("0xRecipientAddress", { size: 32 }),
13259
+ * dest: "EVM-1",
13260
+ * timeout: 3600n,
13261
+ * data: "0x"
13262
+ * }
13263
+ *
13264
+ * const { totalNativeCost, relayerFeeInSourceFeeToken } = await tokenGateway.quoteNative(params)
13265
+ * console.log(`Total native cost: ${formatEther(totalNativeCost)} ETH`)
13266
+ * console.log(`Relayer fee in fee token: ${relayerFeeInSourceFeeToken}`)
13267
+ * ```
13268
+ */
13269
+ async quoteNative(params) {
13270
+ const dataHex = params.data ? typeof params.data === "string" ? params.data : toHex(params.data) : "0x";
13271
+ const sourceTokenGatewayAddress = this.getTokenGatewayAddress(this.source.config.stateMachineId);
13272
+ const destTokenGatewayAddress = this.getTokenGatewayAddress(params.dest);
13273
+ let relayerFee = 0n;
13274
+ const destChainId = typeof params.dest === "string" ? params.dest : new TextDecoder().decode(params.dest);
13275
+ const isEvmDest = destChainId.startsWith("EVM-") && this.dest instanceof EvmChain;
13276
+ if (isEvmDest) {
13277
+ const randomHex = "0x" + Array.from({ length: 191 * 2 }, () => Math.floor(Math.random() * 16).toString(16)).join("");
13278
+ const randomBody = randomHex;
13279
+ const dummyPostRequest = {
13280
+ source: this.source.config.stateMachineId,
13281
+ dest: destChainId,
13282
+ from: sourceTokenGatewayAddress,
13283
+ to: destTokenGatewayAddress,
13284
+ nonce: 0n,
13285
+ body: randomBody,
13286
+ timeoutTimestamp: params.timeout
13287
+ };
13288
+ const { gas } = await this.dest.estimateGas(dummyPostRequest);
13289
+ const gasPrice = await this.dest.client.getGasPrice();
13290
+ const gasCostInNative = gas * gasPrice;
13291
+ relayerFee = gasCostInNative * 101n / 100n;
13292
+ }
13293
+ const teleportBody = encodeAbiParameters(
13294
+ parseAbiParameters("uint256, uint256, bytes32, bool, bytes32, bytes"),
13295
+ [
13296
+ params.amount,
13297
+ relayerFee,
13298
+ // Use the calculated relayer fee (0 for non-EVM destinations)
13299
+ params.assetId,
13300
+ params.redeem,
13301
+ params.to,
13302
+ dataHex
13303
+ ]
13304
+ );
13305
+ const postRequest = {
13306
+ source: this.source.config.stateMachineId,
13307
+ dest: destChainId,
13308
+ from: sourceTokenGatewayAddress,
13309
+ to: destTokenGatewayAddress,
13310
+ nonce: 0n,
13311
+ body: teleportBody,
13312
+ timeoutTimestamp: params.timeout
13313
+ };
13314
+ const protocolFeeInNative = await this.source.quoteNative(postRequest, relayerFee);
13315
+ const protocolFeeWithBuffer = protocolFeeInNative * 101n / 100n;
13316
+ let relayerFeeInSourceFeeToken = 0n;
13317
+ if (relayerFee > 0n) {
13318
+ const feeToken = await this.source.getFeeTokenWithDecimals();
13319
+ relayerFeeInSourceFeeToken = await this.convertNativeToFeeToken(
13320
+ relayerFee,
13321
+ feeToken.address,
13322
+ this.source.config.stateMachineId
13323
+ );
13324
+ }
13325
+ return {
13326
+ totalNativeCost: protocolFeeWithBuffer,
13327
+ relayerFeeInSourceFeeToken
13328
+ };
13329
+ }
13330
+ /**
13331
+ * Convert native token amount to fee token amount using Uniswap V2 router
13332
+ * @private
13333
+ */
13334
+ async convertNativeToFeeToken(nativeAmount, feeTokenAddress, chain) {
13335
+ const v2Router = this.source.configService.getUniswapRouterV2Address(chain);
13336
+ const WETH = this.source.configService.getWrappedNativeAssetWithDecimals(chain).asset;
13337
+ const v2AmountOut = await this.source.client.simulateContract({
13338
+ address: v2Router,
13339
+ abi: uniswapRouterV2_default.ABI,
13340
+ // @ts-ignore
13341
+ functionName: "getAmountsOut",
13342
+ // @ts-ignore
13343
+ args: [nativeAmount, [WETH, feeTokenAddress]]
13344
+ });
13345
+ return v2AmountOut.result[1];
13346
+ }
13347
+ };
13166
13348
  async function getOrderPlacedFromTx(client, txHash) {
13167
13349
  const receipt = await client.getTransactionReceipt({ hash: txHash });
13168
13350
  const events = parseEventLogs({
@@ -13318,6 +13500,107 @@ function readIsmpCommitmentHash(events) {
13318
13500
  }
13319
13501
  }
13320
13502
  }
13503
+ async function makeTeleportExtrinsics(teleport_param) {
13504
+ const { params, apiPromise } = teleport_param;
13505
+ const substrateComplianceAddr = (address, stateMachine) => {
13506
+ if (stateMachine.startsWith("EVM-")) return pad(address, { size: 32, dir: "left" });
13507
+ return address;
13508
+ };
13509
+ const assetId = keccakAsU8a(params.symbol);
13510
+ const scaleEncodedAssetId = await fetchLocalAssetId({ api: apiPromise, assetId });
13511
+ if (scaleEncodedAssetId === null) {
13512
+ throw new Error("Unknown asset id provided");
13513
+ }
13514
+ const destination = convertStateMachineIdToEnum(params.destination);
13515
+ const recipient = hexToBytes(substrateComplianceAddr(params.recipient, params.destination));
13516
+ const teleportParams = {
13517
+ destination,
13518
+ recepient: Array.from(recipient),
13519
+ amount: params.amount,
13520
+ timeout: BigInt(params.timeout),
13521
+ tokenGatewayAddress: Array.from(params.tokenGatewayAddress),
13522
+ relayerFee: BigInt(params.relayerFee),
13523
+ redeem: params.redeem,
13524
+ callData: params.callData ? Array.from(params.callData) : void 0
13525
+ };
13526
+ const encoded = TeleportParams.enc(teleportParams);
13527
+ const fullCallData = new Uint8Array([...scaleEncodedAssetId, ...encoded]);
13528
+ return apiPromise.tx.tokenGateway.teleport(fullCallData);
13529
+ }
13530
+ function submitExtrinsics({
13531
+ extrinsics: tx,
13532
+ who,
13533
+ options,
13534
+ apiPromise
13535
+ }) {
13536
+ let unsub = () => {
13537
+ };
13538
+ let closed = false;
13539
+ const stream = new ReadableStream(
13540
+ {
13541
+ async start(controller) {
13542
+ unsub = await tx.signAndSend(who, options, async (result) => {
13543
+ try {
13544
+ const { isInBlock, isError, dispatchError, txHash, isFinalized, status } = result;
13545
+ const events = result.events;
13546
+ if (isError) {
13547
+ console.error("Transaction failed: ", dispatchError);
13548
+ controller.enqueue({ kind: "Error", error: dispatchError });
13549
+ unsub?.();
13550
+ controller.close();
13551
+ closed = true;
13552
+ return;
13553
+ }
13554
+ if (status.type === "Ready") {
13555
+ controller.enqueue({
13556
+ kind: "Ready",
13557
+ transaction_hash: txHash.toHex()
13558
+ });
13559
+ }
13560
+ if (isInBlock || isFinalized) {
13561
+ const commitment_hash = readIsmpCommitmentHash(events);
13562
+ const blockHash = isInBlock ? status.asInBlock.toHex() : status.asFinalized.toHex();
13563
+ if (!commitment_hash) {
13564
+ controller.enqueue({
13565
+ kind: "Error",
13566
+ error: new Error("Commitment Hash missing")
13567
+ });
13568
+ return controller.close();
13569
+ }
13570
+ const header = await apiPromise.rpc.chain.getHeader(blockHash);
13571
+ controller.enqueue({
13572
+ kind: isInBlock ? "Dispatched" : "Finalized",
13573
+ transaction_hash: txHash.toHex(),
13574
+ block_number: header.number.toBigInt(),
13575
+ commitment: commitment_hash
13576
+ });
13577
+ if (isFinalized) {
13578
+ unsub?.();
13579
+ controller.close();
13580
+ closed = true;
13581
+ return;
13582
+ }
13583
+ }
13584
+ } catch (err) {
13585
+ if (closed) {
13586
+ return;
13587
+ }
13588
+ controller.enqueue({
13589
+ kind: "Error",
13590
+ error: String(err)
13591
+ });
13592
+ }
13593
+ });
13594
+ },
13595
+ cancel: () => unsub?.()
13596
+ },
13597
+ {
13598
+ highWaterMark: 3,
13599
+ size: () => 1
13600
+ }
13601
+ );
13602
+ return stream;
13603
+ }
13321
13604
  var MultiAccount = Struct({
13322
13605
  substrate_account: Bytes(32),
13323
13606
  evm_account: Bytes(20),
@@ -13478,6 +13761,6 @@ async function teleportDot(param_) {
13478
13761
  return stream;
13479
13762
  }
13480
13763
 
13481
- 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, convertCodecToIGetRequest, convertCodecToIProof, convertIGetRequestToCodec, convertIProofToCodec, convertStateIdToStateMachineId, convertStateMachineEnumToString, convertStateMachineIdToEnum, createChain, createEvmChain, createIndexerClient, createQueryClient, createRpcUrls, encodeISMPMessage, estimateGasForPost, fetchPrice, generateRootWithProof, getChain, getGasPriceFromEtherscan, getOrderPlacedFromTx, getPostRequestEventFromTx, getPostResponseEventFromTx, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, hexToString, maxBigInt, orderCommitment, popularTokens, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, requestCommitmentKey, retryPromise, teleport, teleportDot, viemChains };
13764
+ 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, TokenGateway, USE_ETHERSCAN_CHAINS, WrappedNativeDecimals, __test, addresses, adjustFeeDecimals, assets, bytes20ToBytes32, bytes32ToBytes20, chainIds, coingeckoIds, consensusStateIds, constructRedeemEscrowRequestBody, convertCodecToIGetRequest, convertCodecToIProof, convertIGetRequestToCodec, convertIProofToCodec, convertStateIdToStateMachineId, convertStateMachineEnumToString, convertStateMachineIdToEnum, createChain, createEvmChain, createIndexerClient, createQueryClient, createRpcUrls, encodeISMPMessage, estimateGasForPost, fetchPrice, generateRootWithProof, getChain, getGasPriceFromEtherscan, getOrderPlacedFromTx, getPostRequestEventFromTx, getPostResponseEventFromTx, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, hexToString, makeTeleportExtrinsics, maxBigInt, orderCommitment, popularTokens, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, requestCommitmentKey, retryPromise, submitExtrinsics, teleport, teleportDot, viemChains };
13482
13765
  //# sourceMappingURL=index.js.map
13483
13766
  //# sourceMappingURL=index.js.map