@hyperbridge/sdk 2.2.2 → 2.3.0

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.
@@ -13,6 +13,7 @@ var api = require('@polkadot/api');
13
13
  var scaleTs = require('scale-ts');
14
14
  var utilCrypto = require('@polkadot/util-crypto');
15
15
  var util = require('@polkadot/util');
16
+ var PQueue = require('p-queue');
16
17
  var stdEnv = require('std-env');
17
18
  var mergeRace = require('@async-generator/merge-race');
18
19
  var graphqlRequest = require('graphql-request');
@@ -25,6 +26,7 @@ var Decimal2 = require('decimal.js');
25
26
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
26
27
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
27
28
 
29
+ var PQueue__default = /*#__PURE__*/_interopDefault(PQueue);
28
30
  var mergeRace__default = /*#__PURE__*/_interopDefault(mergeRace);
29
31
  var inMemoryDriver__default = /*#__PURE__*/_interopDefault(inMemoryDriver);
30
32
  var fsDriver__default = /*#__PURE__*/_interopDefault(fsDriver);
@@ -524,6 +526,11 @@ var ABI = [
524
526
  name: "context",
525
527
  type: "bytes",
526
528
  internalType: "bytes"
529
+ },
530
+ {
531
+ name: "payer",
532
+ type: "address",
533
+ internalType: "address"
527
534
  }
528
535
  ]
529
536
  }
@@ -2579,9 +2586,9 @@ var chainConfigs = {
2579
2586
  USDT: { balanceSlot: 151, allowanceSlot: 152 }
2580
2587
  },
2581
2588
  addresses: {
2582
- IntentGateway: "0xE13fB34CAe12505ae51BaC8C405AF8EB27AC8058",
2589
+ IntentGateway: "0x6CF42FA9BecbC5b6a26884964956b113530f7cFA",
2583
2590
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
2584
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
2591
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
2585
2592
  UniswapRouter02: "0x9639379819420704457B07A0C33B678D9E0F8Df0",
2586
2593
  UniswapV2Factory: "0x12e036669DA18F4A2777853d6e2136b32AceEC86",
2587
2594
  UniswapV3Factory: "0x0000000000000000000000000000000000000000",
@@ -2589,7 +2596,7 @@ var chainConfigs = {
2589
2596
  UniswapV3Quoter: "0x0000000000000000000000000000000000000000",
2590
2597
  UniswapV4Quoter: "0x0000000000000000000000000000000000000000",
2591
2598
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
2592
- SolverAccount: "0x0b5cfBc16ef60AD6930ba5A90Bb09475B7BF3815"
2599
+ SolverAccount: "0x07FeC66d967800998060194EaECDd7C66dA4a1B1"
2593
2600
  },
2594
2601
  rpcEnvKey: "BSC_CHAPEL",
2595
2602
  defaultRpcUrl: "https://bnb-testnet.api.onfinality.io/public",
@@ -2620,7 +2627,7 @@ var chainConfigs = {
2620
2627
  addresses: {
2621
2628
  IntentGateway: "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509",
2622
2629
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
2623
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
2630
+ Host: "0x58A41B89F4871725E5D898d98eF4BF917601c5eB",
2624
2631
  UniswapRouter02: "0x0000000000000000000000000000000000000000",
2625
2632
  UniswapV2Factory: "0x0000000000000000000000000000000000000000",
2626
2633
  UniswapV3Factory: "0x0000000000000000000000000000000000000000",
@@ -2659,7 +2666,7 @@ var chainConfigs = {
2659
2666
  addresses: {
2660
2667
  IntentGateway: "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509",
2661
2668
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
2662
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
2669
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
2663
2670
  UniswapRouter02: "0x0000000000000000000000000000000000000000",
2664
2671
  UniswapV2Factory: "0x0000000000000000000000000000000000000000",
2665
2672
  UniswapV3Factory: "0x0000000000000000000000000000000000000000",
@@ -3005,13 +3012,13 @@ var chainConfigs = {
3005
3012
  USDC: { balanceSlot: 1, allowanceSlot: 2 }
3006
3013
  },
3007
3014
  addresses: {
3008
- IntentGateway: "0xE13fB34CAe12505ae51BaC8C405AF8EB27AC8058",
3015
+ IntentGateway: "0x6CF42FA9BecbC5b6a26884964956b113530f7cFA",
3009
3016
  TokenGateway: "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E",
3010
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3017
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3011
3018
  Calldispatcher: "0x876F1891982E260026630c233A4897160A281Fb8",
3012
3019
  Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
3013
3020
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
3014
- SolverAccount: "0x0b5cfBc16ef60AD6930ba5A90Bb09475B7BF3815"
3021
+ SolverAccount: "0x07FeC66d967800998060194EaECDd7C66dA4a1B1"
3015
3022
  },
3016
3023
  rpcEnvKey: "POLYGON_AMOY",
3017
3024
  defaultRpcUrl: "https://rpc-amoy.polygon.technology",
@@ -3127,7 +3134,7 @@ var chainConfigs = {
3127
3134
  },
3128
3135
  addresses: {
3129
3136
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
3130
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3137
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3131
3138
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
3132
3139
  },
3133
3140
  defaultRpcUrl: "https://sepolia-rollup.arbitrum.io/rpc",
@@ -3151,7 +3158,7 @@ var chainConfigs = {
3151
3158
  },
3152
3159
  addresses: {
3153
3160
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
3154
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3161
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3155
3162
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
3156
3163
  },
3157
3164
  defaultRpcUrl: "https://sepolia.optimism.io",
@@ -3175,7 +3182,7 @@ var chainConfigs = {
3175
3182
  },
3176
3183
  addresses: {
3177
3184
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
3178
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3185
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3179
3186
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
3180
3187
  },
3181
3188
  defaultRpcUrl: "https://sepolia.base.org",
@@ -3201,7 +3208,7 @@ var chainConfigs = {
3201
3208
  addresses: {
3202
3209
  IntentGateway: "0x606ba811aa6cb424ce2108e8977c5284686f0d1f",
3203
3210
  TokenGateway: "0x1c1e5be83df4a54c7a2230c337e4a3e8b7354b1c",
3204
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3211
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3205
3212
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
3206
3213
  },
3207
3214
  defaultRpcUrl: "https://testnet-asset-hub-eth-rpc.polkadot.io",
@@ -3251,7 +3258,7 @@ var chainConfigs = {
3251
3258
  wrappedNativeDecimals: 18,
3252
3259
  addresses: {
3253
3260
  TokenGateway: "0x451bDd8273839AD0Ec7F4Fa798E8B3DABb223fD8",
3254
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3261
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3255
3262
  IntentGateway: "0xb8039832c6c9266F928d038eA49A8a169300C670"
3256
3263
  },
3257
3264
  consensusStateId: "PHAR",
@@ -4383,6 +4390,11 @@ var ABI3 = [
4383
4390
  name: "context",
4384
4391
  type: "bytes",
4385
4392
  internalType: "bytes"
4393
+ },
4394
+ {
4395
+ name: "payer",
4396
+ type: "address",
4397
+ internalType: "address"
4386
4398
  }
4387
4399
  ]
4388
4400
  }
@@ -7543,6 +7555,7 @@ function encodeISMPMessage(message) {
7543
7555
  }
7544
7556
  }
7545
7557
  var OFFCHAIN_BID_PREFIX = new TextEncoder().encode("intents::bid::");
7558
+ var OFFCHAIN_PHANTOM_PREFIX = new TextEncoder().encode("intents::phantom::order::");
7546
7559
  var BidCodec = scaleTs.Struct({ filler: scaleTs.Bytes(32), user_op: scaleTs.Vector(scaleTs.u8) });
7547
7560
  var PackedUserOperationCodec = scaleTs.Struct({
7548
7561
  sender: scaleTs.Bytes(20),
@@ -7603,6 +7616,11 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7603
7616
  ownsConnection;
7604
7617
  /** Cached result of whether the node exposes intents_* RPC methods */
7605
7618
  hasIntentsRpc = null;
7619
+ // Serialises every extrinsic submission on this instance's substrate account. All submit/retract
7620
+ // methods funnel through signAndSendExtrinsic, each using the API's auto-nonce; fired in parallel
7621
+ // (bids for orders on different chains, or several phantom orders in one interval) they would grab
7622
+ // the same nonce and all but one would fail. Concurrency 1 sequences them.
7623
+ submissionQueue = new PQueue__default.default({ concurrency: 1 });
7606
7624
  /**
7607
7625
  * Creates and connects an IntentsCoprocessor to a Hyperbridge node.
7608
7626
  * This creates and manages its own API connection.
@@ -7655,14 +7673,17 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7655
7673
  }
7656
7674
  }
7657
7675
  /**
7658
- * Creates a Substrate keypair from the configured private key
7659
- * Supports both hex seed (without 0x prefix) and mnemonic phrases
7676
+ * Creates a Substrate keypair from the configured private key.
7677
+ * Supports hex seed (with or without 0x), mnemonic phrases, and URI derivation paths (//Alice).
7660
7678
  */
7661
7679
  getKeyPair() {
7662
7680
  if (!this.substratePrivateKey) {
7663
7681
  throw new Error("Substrate PrivateKey Required");
7664
7682
  }
7665
7683
  const keyring = new api.Keyring({ type: "sr25519" });
7684
+ if (this.substratePrivateKey.startsWith("//")) {
7685
+ return keyring.addFromUri(this.substratePrivateKey);
7686
+ }
7666
7687
  if (this.substratePrivateKey.includes(" ")) {
7667
7688
  return keyring.addFromMnemonic(this.substratePrivateKey);
7668
7689
  }
@@ -7671,10 +7692,19 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7671
7692
  return keyring.addFromSeed(seedBytes);
7672
7693
  }
7673
7694
  /**
7674
- * Signs and sends an extrinsic, handling status updates and errors
7675
- * Implements retry logic with progressive tip increases for stuck transactions
7695
+ * Signs and sends an extrinsic. Submissions are serialised through {@link submissionQueue} so
7696
+ * concurrent calls never collide on the substrate account nonce — each extrinsic reaches a block
7697
+ * before the next is signed.
7676
7698
  */
7677
7699
  async signAndSendExtrinsic(extrinsic, maxRetries = 3, timeoutMs = 3e4) {
7700
+ const result = await this.submissionQueue.add(() => this.sendExtrinsicWithRetries(extrinsic, maxRetries, timeoutMs));
7701
+ return result ?? { success: false, error: "Submission queue returned no result" };
7702
+ }
7703
+ /**
7704
+ * Signs and sends an extrinsic, handling status updates and errors.
7705
+ * Implements retry logic with progressive tip increases for stuck transactions.
7706
+ */
7707
+ async sendExtrinsicWithRetries(extrinsic, maxRetries, timeoutMs) {
7678
7708
  const keyPair = this.getKeyPair();
7679
7709
  let baseTip = 500000000000n;
7680
7710
  let attempt = 0;
@@ -7719,20 +7749,34 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7719
7749
  }, timeoutMs);
7720
7750
  extrinsic.signAndSend(keyPair, { tip }, (result) => {
7721
7751
  if (resolved) return;
7722
- if (result.status.isInBlock || result.status.isFinalized) {
7752
+ if (result.dispatchError && (result.status.isInBlock || result.status.isFinalized)) {
7723
7753
  resolved = true;
7724
7754
  clearTimeout(timeoutId);
7755
+ let errorMsg;
7756
+ if (result.dispatchError.isModule) {
7757
+ const decoded = this.api.registry.findMetaError(result.dispatchError.asModule);
7758
+ errorMsg = `Dispatch error: ${decoded.section}::${decoded.name}`;
7759
+ } else {
7760
+ errorMsg = `Dispatch error: ${result.dispatchError.toString()}`;
7761
+ }
7725
7762
  resolve({
7726
- success: true,
7727
- blockHash: result.status.asInBlock.toHex(),
7728
- extrinsicHash: extrinsic.hash.toHex()
7763
+ success: false,
7764
+ error: errorMsg
7729
7765
  });
7730
- } else if (result.dispatchError) {
7766
+ } else if (result.status.isDropped || result.status.isInvalid || result.status.isUsurped || result.status.isFinalityTimeout) {
7731
7767
  resolved = true;
7732
7768
  clearTimeout(timeoutId);
7733
7769
  resolve({
7734
7770
  success: false,
7735
- error: `Dispatch error: ${result.dispatchError.toString()}`
7771
+ error: `Transaction ${result.status.type.toLowerCase()}`
7772
+ });
7773
+ } else if (result.status.isInBlock || result.status.isFinalized) {
7774
+ resolved = true;
7775
+ clearTimeout(timeoutId);
7776
+ resolve({
7777
+ success: true,
7778
+ blockHash: (result.status.isInBlock ? result.status.asInBlock : result.status.asFinalized).toHex(),
7779
+ extrinsicHash: extrinsic.hash.toHex()
7736
7780
  });
7737
7781
  }
7738
7782
  }).then((unsub) => {
@@ -7787,6 +7831,31 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7787
7831
  };
7788
7832
  }
7789
7833
  }
7834
+ /**
7835
+ * Retracts a previous bid and places a new one in a single transaction via utility.batch.
7836
+ * The retraction runs first, so the old deposit is reclaimed even if the new bid then fails
7837
+ * (batch is non-atomic — a failing call interrupts the batch without reverting the calls that
7838
+ * already succeeded, unlike batchAll which would roll the retraction back too).
7839
+ *
7840
+ * @param retractCommitment - The order commitment of the bid to retract (bytes32)
7841
+ * @param bidCommitment - The order commitment of the new bid (bytes32)
7842
+ * @param userOp - The encoded PackedUserOperation as hex string
7843
+ * @returns BidSubmissionResult with success status and block/extrinsic hash
7844
+ */
7845
+ async submitBidWithRetraction(retractCommitment, bidCommitment, userOp) {
7846
+ try {
7847
+ const batch = this.api.tx.utility.batch([
7848
+ this.api.tx.intentsCoprocessor.retractBid(retractCommitment),
7849
+ this.api.tx.intentsCoprocessor.placeBid(bidCommitment, userOp)
7850
+ ]);
7851
+ return await this.signAndSendExtrinsic(batch);
7852
+ } catch (error) {
7853
+ return {
7854
+ success: false,
7855
+ error: error instanceof Error ? error.message : "Unknown error"
7856
+ };
7857
+ }
7858
+ }
7790
7859
  /**
7791
7860
  * Fetches all bid storage entries for a given order commitment.
7792
7861
  * Returns the on-chain data only (filler addresses and deposits).
@@ -7871,6 +7940,80 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7871
7940
  buildOffchainBidKey(commitment, filler) {
7872
7941
  return util.u8aConcat(OFFCHAIN_BID_PREFIX, util.hexToU8a(commitment), utilCrypto.decodeAddress(filler));
7873
7942
  }
7943
+ /**
7944
+ * Fetches the ABI-encoded phantom order from offchain storage and decodes it
7945
+ * into an `Order` object. The pallet writes the order bytes under the key
7946
+ * `intents::phantom::order::<commitment>` when it calls `on_initialize`.
7947
+ *
7948
+ * Returns `null` if the key is absent (e.g. the node is not an offchain worker
7949
+ * or the commitment has expired and been cleared).
7950
+ */
7951
+ async fetchPhantomOrder(commitment) {
7952
+ const key = util.u8aConcat(OFFCHAIN_PHANTOM_PREFIX, util.hexToU8a(commitment));
7953
+ const result = await this.api.rpc.offchain.localStorageGet("PERSISTENT", util.u8aToHex(key));
7954
+ if (!result || result.isNone) return null;
7955
+ const rawHex = result.unwrap().toHex();
7956
+ if (rawHex === "0x" || rawHex === "0x00") return null;
7957
+ const placeOrderAbi = IntentGatewayV2_default.ABI.find(
7958
+ (item) => item.type === "function" && item.name === "placeOrder"
7959
+ );
7960
+ const orderType = placeOrderAbi?.inputs?.[0];
7961
+ if (!orderType) return null;
7962
+ const [decoded] = viem.decodeAbiParameters([orderType], rawHex);
7963
+ const d = decoded;
7964
+ const textDecoder = new TextDecoder();
7965
+ return {
7966
+ id: commitment,
7967
+ user: d.user,
7968
+ source: textDecoder.decode(viem.hexToBytes(d.source)),
7969
+ destination: textDecoder.decode(viem.hexToBytes(d.destination)),
7970
+ deadline: d.deadline,
7971
+ nonce: d.nonce,
7972
+ fees: d.fees,
7973
+ session: d.session,
7974
+ predispatch: {
7975
+ assets: d.predispatch.assets.map((a) => ({
7976
+ token: a.token,
7977
+ amount: a.amount
7978
+ })),
7979
+ call: d.predispatch.call
7980
+ },
7981
+ inputs: d.inputs.map((i) => ({
7982
+ token: i.token,
7983
+ amount: i.amount
7984
+ })),
7985
+ output: {
7986
+ beneficiary: d.output.beneficiary,
7987
+ assets: d.output.assets.map((a) => ({
7988
+ token: a.token,
7989
+ amount: a.amount
7990
+ })),
7991
+ call: d.output.call
7992
+ }
7993
+ };
7994
+ }
7995
+ /**
7996
+ * Subscribes to PhantomOrderRegistered events from the intents coprocessor pallet.
7997
+ * Calls the callback for each new phantom order as blocks arrive.
7998
+ * Returns an unsubscribe function to stop the subscription.
7999
+ */
8000
+ async subscribePhantomOrders(callback) {
8001
+ const unsub = await this.api.query.system.events((records) => {
8002
+ for (const { event } of records) {
8003
+ if (event.section !== "intentsCoprocessor" || event.method !== "PhantomOrderRegistered") continue;
8004
+ const [commitment, chain, createdAt, tokenA, tokenB, standardAmount] = event.data;
8005
+ callback({
8006
+ commitment: commitment.toHex(),
8007
+ chain: new TextDecoder().decode(util.hexToU8a(chain.toHex())),
8008
+ createdAt: createdAt.toNumber(),
8009
+ tokenA: tokenA.toHex(),
8010
+ tokenB: tokenB.toHex(),
8011
+ standardAmount: BigInt(standardAmount.toString())
8012
+ });
8013
+ }
8014
+ });
8015
+ return unsub;
8016
+ }
7874
8017
  };
7875
8018
  var TronChain = class _TronChain {
7876
8019
  constructor(params, evm) {
@@ -10272,26 +10415,27 @@ var PostRequestClient = class {
10272
10415
  * accompanying timeout-proof calldata.
10273
10416
  */
10274
10417
  async addTimeoutFinalityEvents(request) {
10275
- const destChain = this.ctx.config.dest;
10276
- const hyperbridge = this.ctx.config.hyperbridge;
10277
10418
  const events = [];
10278
- const commitment = postRequestCommitment(request).commitment;
10279
- const receipt = await destChain.queryRequestReceipt(commitment);
10280
- const destTimestamp = await destChain.timestamp();
10281
10419
  const commit = (req) => {
10282
10420
  this.logger.trace(`Added ${events.length} timeout events`, events);
10283
10421
  request.statuses = [...req.statuses, ...events];
10284
10422
  return request;
10285
10423
  };
10286
10424
  if (request.timeoutTimestamp === 0n) return commit(request);
10425
+ if (request.statuses.some(
10426
+ (item) => item.status === RequestStatus.DESTINATION || item.status === TimeoutStatus.TIMED_OUT
10427
+ ))
10428
+ return commit(request);
10429
+ const destChain = this.ctx.config.dest;
10430
+ const hyperbridge = this.ctx.config.hyperbridge;
10431
+ const commitment = postRequestCommitment(request).commitment;
10432
+ const receipt = await destChain.queryRequestReceipt(commitment);
10433
+ const destTimestamp = await destChain.timestamp();
10287
10434
  if (receipt || request.timeoutTimestamp > destTimestamp) return commit(request);
10288
- const is_finished = request.statuses.find((item) => item.status === RequestStatus.DESTINATION);
10289
- if (!is_finished) {
10290
- events.push({
10291
- status: TimeoutStatus.PENDING_TIMEOUT,
10292
- metadata: { blockHash: "0x", blockNumber: 0, transactionHash: "0x" }
10293
- });
10294
- }
10435
+ events.push({
10436
+ status: TimeoutStatus.PENDING_TIMEOUT,
10437
+ metadata: { blockHash: "0x", blockNumber: 0, transactionHash: "0x" }
10438
+ });
10295
10439
  const delivered = request.statuses.find((item) => item.status === RequestStatus.HYPERBRIDGE_DELIVERED);
10296
10440
  let hyperbridgeFinalized;
10297
10441
  if (!delivered) {
@@ -14612,16 +14756,6 @@ var CryptoUtils = class _CryptoUtils {
14612
14756
  }
14613
14757
  }
14614
14758
  };
14615
- var FEE_TOKEN_CACHE_TTL_MS = 5 * 60 * 1e3;
14616
- async function getFeeToken(ctx, chainId, chain) {
14617
- const cached = ctx.feeTokenCache.get(chainId);
14618
- if (cached && Date.now() - cached.cachedAt < FEE_TOKEN_CACHE_TTL_MS) {
14619
- return cached;
14620
- }
14621
- const fresh = await chain.getFeeTokenWithDecimals();
14622
- ctx.feeTokenCache.set(chainId, { ...fresh, cachedAt: Date.now() });
14623
- return fresh;
14624
- }
14625
14759
  function encodeERC7821ExecuteBatch(calls) {
14626
14760
  const executionData = viem.encodeAbiParameters(
14627
14761
  [{ type: "tuple[]", components: erc7281_default.ABI[1].components }],
@@ -14633,6 +14767,36 @@ function encodeERC7821ExecuteBatch(calls) {
14633
14767
  args: [ERC7821_BATCH_MODE, executionData]
14634
14768
  });
14635
14769
  }
14770
+ function decodeERC7821ExecuteBatch(callData) {
14771
+ try {
14772
+ const decoded = viem.decodeFunctionData({ abi: erc7281_default.ABI, data: callData });
14773
+ if (decoded.functionName !== "execute" || !decoded.args || decoded.args.length < 2) return null;
14774
+ const executionData = decoded.args[1];
14775
+ const [calls] = viem.decodeAbiParameters(
14776
+ [{ type: "tuple[]", components: erc7281_default.ABI[1].components }],
14777
+ executionData
14778
+ );
14779
+ return calls.map((call) => ({
14780
+ target: call.target,
14781
+ value: call.value,
14782
+ data: call.data
14783
+ }));
14784
+ } catch {
14785
+ return null;
14786
+ }
14787
+ }
14788
+
14789
+ // src/protocols/intents/utils.ts
14790
+ var FEE_TOKEN_CACHE_TTL_MS = 5 * 60 * 1e3;
14791
+ async function getFeeToken(ctx, chainId, chain) {
14792
+ const cached = ctx.feeTokenCache.get(chainId);
14793
+ if (cached && Date.now() - cached.cachedAt < FEE_TOKEN_CACHE_TTL_MS) {
14794
+ return cached;
14795
+ }
14796
+ const fresh = await chain.getFeeTokenWithDecimals();
14797
+ ctx.feeTokenCache.set(chainId, { ...fresh, cachedAt: Date.now() });
14798
+ return fresh;
14799
+ }
14636
14800
  async function fetchSourceProof(commitment, source, sourceStateMachine, sourceConsensusStateId, sourceHeight) {
14637
14801
  const { slot1, slot2 } = requestCommitmentKey(commitment);
14638
14802
  const proofHex = await source.queryStateProof(sourceHeight, [slot1, slot2]);
@@ -18512,6 +18676,11 @@ var HyperFungibleTokenABI = [
18512
18676
  name: "context",
18513
18677
  type: "bytes",
18514
18678
  internalType: "bytes"
18679
+ },
18680
+ {
18681
+ name: "payer",
18682
+ type: "address",
18683
+ internalType: "address"
18515
18684
  }
18516
18685
  ]
18517
18686
  }
@@ -19633,6 +19802,11 @@ var WrappedHyperFungibleTokenABI = [
19633
19802
  name: "context",
19634
19803
  type: "bytes",
19635
19804
  internalType: "bytes"
19805
+ },
19806
+ {
19807
+ name: "payer",
19808
+ type: "address",
19809
+ internalType: "address"
19636
19810
  }
19637
19811
  ]
19638
19812
  }
@@ -21470,6 +21644,11 @@ var ABI8 = [
21470
21644
  internalType: "bytes",
21471
21645
  name: "context",
21472
21646
  type: "bytes"
21647
+ },
21648
+ {
21649
+ internalType: "address",
21650
+ name: "payer",
21651
+ type: "address"
21473
21652
  }
21474
21653
  ],
21475
21654
  internalType: "struct DispatchGet",
@@ -21738,6 +21917,11 @@ var ABI8 = [
21738
21917
  internalType: "bytes",
21739
21918
  name: "context",
21740
21919
  type: "bytes"
21920
+ },
21921
+ {
21922
+ internalType: "address",
21923
+ name: "payer",
21924
+ type: "address"
21741
21925
  }
21742
21926
  ],
21743
21927
  internalType: "struct DispatchGet",
@@ -22167,6 +22351,7 @@ exports.convertStateMachineEnumToString = convertStateMachineEnumToString;
22167
22351
  exports.convertStateMachineIdToEnum = convertStateMachineIdToEnum;
22168
22352
  exports.createEvmChain = createEvmChain;
22169
22353
  exports.createQueryClient = createQueryClient;
22354
+ exports.decodeERC7821ExecuteBatch = decodeERC7821ExecuteBatch;
22170
22355
  exports.decodeUserOpScale = decodeUserOpScale;
22171
22356
  exports.encodeERC7821ExecuteBatch = encodeERC7821ExecuteBatch;
22172
22357
  exports.encodeISMPMessage = encodeISMPMessage;