@hyperbridge/sdk 2.2.3 → 2.3.1

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.
@@ -2,7 +2,7 @@ import { readFileSync } from 'fs';
2
2
  import { join } from 'path';
3
3
  import { TextDecoder as TextDecoder$1, TextEncoder as TextEncoder$1 } from 'util';
4
4
  import { createConsola, LogLevels } from 'consola';
5
- import { defineChain, keccak256, toHex, createPublicClient, http, hexToBytes, toFunctionSelector, bytesToHex, encodeFunctionData, erc20Abi, bytesToBigInt, pad, toBytes, numberToBytes, getAddress, encodeAbiParameters, isHex, maxUint256, parseAbiParameters, encodePacked, parseAbiItem, concat, decodeFunctionData, decodeAbiParameters, hexToString as hexToString$1, decodeEventLog, parseEventLogs, parseUnits, concatHex, zeroAddress, decodeFunctionResult, formatUnits } from 'viem';
5
+ import { defineChain, keccak256, toHex, createPublicClient, http, hexToBytes, toFunctionSelector, bytesToHex, encodeFunctionData, erc20Abi, bytesToBigInt, pad, toBytes, numberToBytes, decodeAbiParameters, getAddress, encodeAbiParameters, isHex, maxUint256, parseAbiParameters, encodePacked, parseAbiItem, concat, decodeFunctionData, hexToString as hexToString$1, decodeEventLog, parseEventLogs, parseUnits, concatHex, zeroAddress, decodeFunctionResult, formatUnits } from 'viem';
6
6
  import { baseSepolia, optimismSepolia, arbitrumSepolia, soneium, gnosis, optimism, polygonAmoy, polygon, base, arbitrum, bsc, mainnet, sepolia, gnosisChiado, bscTestnet, tron, unichain } from 'viem/chains';
7
7
  import { TronWeb } from 'tronweb';
8
8
  import { flatten, zip, capitalize, maxBy, isNil } from 'lodash-es';
@@ -11,6 +11,7 @@ import { WsProvider, ApiPromise, Keyring } from '@polkadot/api';
11
11
  import { Struct, Vector, u8, Bytes, Enum, Tuple, _void, u64, u32, Option, bool, u128 } from 'scale-ts';
12
12
  import { keccakAsU8a, decodeAddress, keccakAsHex, xxhashAsU8a, blake2AsU8a } from '@polkadot/util-crypto';
13
13
  import { hexToU8a, u8aToHex, u8aConcat } from '@polkadot/util';
14
+ import PQueue from 'p-queue';
14
15
  import { hasWindow, isNode, env } from 'std-env';
15
16
  import mergeRace from '@async-generator/merge-race';
16
17
  import { GraphQLClient } from 'graphql-request';
@@ -514,6 +515,11 @@ var ABI = [
514
515
  name: "context",
515
516
  type: "bytes",
516
517
  internalType: "bytes"
518
+ },
519
+ {
520
+ name: "payer",
521
+ type: "address",
522
+ internalType: "address"
517
523
  }
518
524
  ]
519
525
  }
@@ -2094,7 +2100,7 @@ var ABI2 = [
2094
2100
  { internalType: "bytes", name: "source", type: "bytes" },
2095
2101
  { internalType: "bytes", name: "dest", type: "bytes" },
2096
2102
  { internalType: "uint64", name: "nonce", type: "uint64" },
2097
- { internalType: "address", name: "from", type: "address" },
2103
+ { internalType: "bytes", name: "from", type: "bytes" },
2098
2104
  { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" },
2099
2105
  { internalType: "bytes[]", name: "keys", type: "bytes[]" },
2100
2106
  { internalType: "uint64", name: "height", type: "uint64" },
@@ -2161,7 +2167,7 @@ var ABI2 = [
2161
2167
  { internalType: "bytes", name: "source", type: "bytes" },
2162
2168
  { internalType: "bytes", name: "dest", type: "bytes" },
2163
2169
  { internalType: "uint64", name: "nonce", type: "uint64" },
2164
- { internalType: "address", name: "from", type: "address" },
2170
+ { internalType: "bytes", name: "from", type: "bytes" },
2165
2171
  { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" },
2166
2172
  { internalType: "bytes[]", name: "keys", type: "bytes[]" },
2167
2173
  { internalType: "uint64", name: "height", type: "uint64" },
@@ -2569,9 +2575,9 @@ var chainConfigs = {
2569
2575
  USDT: { balanceSlot: 151, allowanceSlot: 152 }
2570
2576
  },
2571
2577
  addresses: {
2572
- IntentGateway: "0xE13fB34CAe12505ae51BaC8C405AF8EB27AC8058",
2578
+ IntentGateway: "0x6CF42FA9BecbC5b6a26884964956b113530f7cFA",
2573
2579
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
2574
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
2580
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
2575
2581
  UniswapRouter02: "0x9639379819420704457B07A0C33B678D9E0F8Df0",
2576
2582
  UniswapV2Factory: "0x12e036669DA18F4A2777853d6e2136b32AceEC86",
2577
2583
  UniswapV3Factory: "0x0000000000000000000000000000000000000000",
@@ -2579,7 +2585,7 @@ var chainConfigs = {
2579
2585
  UniswapV3Quoter: "0x0000000000000000000000000000000000000000",
2580
2586
  UniswapV4Quoter: "0x0000000000000000000000000000000000000000",
2581
2587
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
2582
- SolverAccount: "0x0b5cfBc16ef60AD6930ba5A90Bb09475B7BF3815"
2588
+ SolverAccount: "0x07FeC66d967800998060194EaECDd7C66dA4a1B1"
2583
2589
  },
2584
2590
  rpcEnvKey: "BSC_CHAPEL",
2585
2591
  defaultRpcUrl: "https://bnb-testnet.api.onfinality.io/public",
@@ -2610,7 +2616,7 @@ var chainConfigs = {
2610
2616
  addresses: {
2611
2617
  IntentGateway: "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509",
2612
2618
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
2613
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
2619
+ Host: "0x58A41B89F4871725E5D898d98eF4BF917601c5eB",
2614
2620
  UniswapRouter02: "0x0000000000000000000000000000000000000000",
2615
2621
  UniswapV2Factory: "0x0000000000000000000000000000000000000000",
2616
2622
  UniswapV3Factory: "0x0000000000000000000000000000000000000000",
@@ -2649,7 +2655,7 @@ var chainConfigs = {
2649
2655
  addresses: {
2650
2656
  IntentGateway: "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509",
2651
2657
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
2652
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
2658
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
2653
2659
  UniswapRouter02: "0x0000000000000000000000000000000000000000",
2654
2660
  UniswapV2Factory: "0x0000000000000000000000000000000000000000",
2655
2661
  UniswapV3Factory: "0x0000000000000000000000000000000000000000",
@@ -2995,13 +3001,13 @@ var chainConfigs = {
2995
3001
  USDC: { balanceSlot: 1, allowanceSlot: 2 }
2996
3002
  },
2997
3003
  addresses: {
2998
- IntentGateway: "0xE13fB34CAe12505ae51BaC8C405AF8EB27AC8058",
3004
+ IntentGateway: "0x6CF42FA9BecbC5b6a26884964956b113530f7cFA",
2999
3005
  TokenGateway: "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E",
3000
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3006
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3001
3007
  Calldispatcher: "0x876F1891982E260026630c233A4897160A281Fb8",
3002
3008
  Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
3003
3009
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
3004
- SolverAccount: "0x0b5cfBc16ef60AD6930ba5A90Bb09475B7BF3815"
3010
+ SolverAccount: "0x07FeC66d967800998060194EaECDd7C66dA4a1B1"
3005
3011
  },
3006
3012
  rpcEnvKey: "POLYGON_AMOY",
3007
3013
  defaultRpcUrl: "https://rpc-amoy.polygon.technology",
@@ -3117,7 +3123,7 @@ var chainConfigs = {
3117
3123
  },
3118
3124
  addresses: {
3119
3125
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
3120
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3126
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3121
3127
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
3122
3128
  },
3123
3129
  defaultRpcUrl: "https://sepolia-rollup.arbitrum.io/rpc",
@@ -3141,7 +3147,7 @@ var chainConfigs = {
3141
3147
  },
3142
3148
  addresses: {
3143
3149
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
3144
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3150
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3145
3151
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
3146
3152
  },
3147
3153
  defaultRpcUrl: "https://sepolia.optimism.io",
@@ -3165,7 +3171,7 @@ var chainConfigs = {
3165
3171
  },
3166
3172
  addresses: {
3167
3173
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
3168
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3174
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3169
3175
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
3170
3176
  },
3171
3177
  defaultRpcUrl: "https://sepolia.base.org",
@@ -3191,7 +3197,7 @@ var chainConfigs = {
3191
3197
  addresses: {
3192
3198
  IntentGateway: "0x606ba811aa6cb424ce2108e8977c5284686f0d1f",
3193
3199
  TokenGateway: "0x1c1e5be83df4a54c7a2230c337e4a3e8b7354b1c",
3194
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3200
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3195
3201
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108"
3196
3202
  },
3197
3203
  defaultRpcUrl: "https://testnet-asset-hub-eth-rpc.polkadot.io",
@@ -3241,7 +3247,7 @@ var chainConfigs = {
3241
3247
  wrappedNativeDecimals: 18,
3242
3248
  addresses: {
3243
3249
  TokenGateway: "0x451bDd8273839AD0Ec7F4Fa798E8B3DABb223fD8",
3244
- Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3250
+ Host: "0x9AA003594d59C62EE17A73A569Fd7B1DbdBd71E1",
3245
3251
  IntentGateway: "0xb8039832c6c9266F928d038eA49A8a169300C670"
3246
3252
  },
3247
3253
  consensusStateId: "PHAR",
@@ -4373,6 +4379,11 @@ var ABI3 = [
4373
4379
  name: "context",
4374
4380
  type: "bytes",
4375
4381
  internalType: "bytes"
4382
+ },
4383
+ {
4384
+ name: "payer",
4385
+ type: "address",
4386
+ internalType: "address"
4376
4387
  }
4377
4388
  ]
4378
4389
  }
@@ -6381,28 +6392,60 @@ var EvmChain = class _EvmChain {
6381
6392
  }
6382
6393
  /**
6383
6394
  * Query and return the encoded storage proof for the provided keys at the given height.
6395
+ *
6396
+ * Keys may be either:
6397
+ * - 32-byte storage slots — read from `address` (or the host contract when omitted), or
6398
+ * - 52-byte cross-chain GET keys encoded as `address(20) || slot(32)`, where the target
6399
+ * contract is embedded in the key. These may span multiple contracts.
6400
+ *
6384
6401
  * @param {bigint} at - The block height at which to query the storage proof.
6385
6402
  * @param {HexString[]} keys - The keys for which to query the storage proof.
6386
- * @param {HexString} address - Optional contract address to fetch storage proof else default to host contract
6403
+ * @param {HexString} address - Optional contract address; forces all keys to be read as slots
6404
+ * of this contract. Omit to let 52-byte keys carry their own contract address.
6387
6405
  * @returns {Promise<HexString>} The encoded storage proof.
6388
6406
  */
6389
6407
  async queryStateProof(at, keys, address) {
6390
- const config = {
6391
- address: address ?? this.params.host,
6392
- storageKeys: keys
6393
- };
6394
- if (!at) {
6395
- config.blockTag = "latest";
6396
- } else {
6397
- config.blockNumber = at;
6398
- }
6399
- const proof = await this.publicClient.getProof(config);
6400
- const flattenedProof = Array.from(new Set(flatten(proof.storageProof.map((item) => item.proof))));
6408
+ const slotsByContract = /* @__PURE__ */ new Map();
6409
+ for (const key of keys) {
6410
+ let contract;
6411
+ let slot;
6412
+ if (address) {
6413
+ contract = address.toLowerCase();
6414
+ slot = key;
6415
+ } else if ((key.length - 2) / 2 === 52) {
6416
+ contract = key.slice(0, 42).toLowerCase();
6417
+ slot = `0x${key.slice(42)}`;
6418
+ } else {
6419
+ contract = this.params.host.toLowerCase();
6420
+ slot = key;
6421
+ }
6422
+ const slots = slotsByContract.get(contract) ?? [];
6423
+ slots.push(slot);
6424
+ slotsByContract.set(contract, slots);
6425
+ }
6426
+ const contracts = Array.from(slotsByContract.entries());
6427
+ const proofs = await Promise.all(
6428
+ contracts.map(([contract, slots]) => {
6429
+ const config = { address: contract, storageKeys: slots };
6430
+ if (!at) {
6431
+ config.blockTag = "latest";
6432
+ } else {
6433
+ config.blockNumber = at;
6434
+ }
6435
+ return this.publicClient.getProof(config);
6436
+ })
6437
+ );
6438
+ const contractProof = Array.from(new Set(flatten(proofs.map((proof) => proof.accountProof))));
6439
+ const storageProof = contracts.map(([contract], i) => {
6440
+ const flattened = Array.from(new Set(flatten(proofs[i].storageProof.map((item) => item.proof))));
6441
+ return [
6442
+ Array.from(hexToBytes(contract)),
6443
+ flattened.map((item) => Array.from(hexToBytes(item)))
6444
+ ];
6445
+ });
6401
6446
  const encoded = EvmStateProof.enc({
6402
- contractProof: proof.accountProof.map((item) => Array.from(hexToBytes(item))),
6403
- storageProof: [
6404
- [Array.from(hexToBytes(config.address)), flattenedProof.map((item) => Array.from(hexToBytes(item)))]
6405
- ]
6447
+ contractProof: contractProof.map((item) => Array.from(hexToBytes(item))),
6448
+ storageProof
6406
6449
  });
6407
6450
  return toHex(encoded);
6408
6451
  }
@@ -7124,6 +7167,49 @@ var SubstrateChain = class _SubstrateChain {
7124
7167
  const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7125
7168
  return item;
7126
7169
  }
7170
+ /**
7171
+ * Returns the storage key for a response receipt in the child trie.
7172
+ * A response receipt is keyed by the originating *request* commitment.
7173
+ * @param {HexString} key - The request commitment (0x-prefixed H256 hex string)
7174
+ * @returns {HexString} The storage key as a hex string
7175
+ */
7176
+ responseReceiptKey(key) {
7177
+ const prefix = new TextEncoder().encode("ResponseReceipts");
7178
+ const keyBytes = hexToBytes(key);
7179
+ return bytesToHex(new Uint8Array([...prefix, ...keyBytes]));
7180
+ }
7181
+ /**
7182
+ * Queries the response receipt for a request commitment. For a GET, Hyperbridge
7183
+ * produces the response as it processes the request, so the presence of a response
7184
+ * receipt indicates the request has already been delivered and handled.
7185
+ * @param {HexString} commitment - The originating request commitment to query.
7186
+ * @returns {Promise<HexString | undefined>} The receipt data if present, otherwise undefined.
7187
+ */
7188
+ async queryResponseReceipt(commitment) {
7189
+ const prefix = toHex(":child_storage:default:ISMP");
7190
+ const key = this.responseReceiptKey(commitment);
7191
+ const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7192
+ return item;
7193
+ }
7194
+ /**
7195
+ * Queries the state-machine commitment Hyperbridge holds for a counterparty chain at an
7196
+ * exact height — the `BoundedStateCommitments` map that `state_machine_commitment` (and thus
7197
+ * proof verification) reads. Returns the committed `stateRoot`, or undefined if Hyperbridge
7198
+ * has not finalized that chain at exactly that height.
7199
+ * @param {StateMachineHeight} height - The counterparty state machine id + height.
7200
+ * @returns {Promise<HexString | undefined>} The committed state root, or undefined if absent.
7201
+ */
7202
+ async queryStateMachineCommitment(height) {
7203
+ if (!this.api) throw new Error("API not initialized");
7204
+ const id = {
7205
+ stateId: height.id.stateId,
7206
+ // on-chain StateMachineId encodes consensusStateId as [u8; 4]
7207
+ consensusStateId: toHex(toBytes(height.id.consensusStateId))
7208
+ };
7209
+ const commitment = await this.api.query.ismp.boundedStateCommitments(id, Number(height.height));
7210
+ if (commitment.isNone) return void 0;
7211
+ return commitment.toJSON()?.stateRoot;
7212
+ }
7127
7213
  /**
7128
7214
  * Returns the current timestamp of the chain.
7129
7215
  * @returns {Promise<bigint>} The current timestamp.
@@ -7533,6 +7619,7 @@ function encodeISMPMessage(message) {
7533
7619
  }
7534
7620
  }
7535
7621
  var OFFCHAIN_BID_PREFIX = new TextEncoder().encode("intents::bid::");
7622
+ var OFFCHAIN_PHANTOM_PREFIX = new TextEncoder().encode("intents::phantom::order::");
7536
7623
  var BidCodec = Struct({ filler: Bytes(32), user_op: Vector(u8) });
7537
7624
  var PackedUserOperationCodec = Struct({
7538
7625
  sender: Bytes(20),
@@ -7593,6 +7680,11 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7593
7680
  ownsConnection;
7594
7681
  /** Cached result of whether the node exposes intents_* RPC methods */
7595
7682
  hasIntentsRpc = null;
7683
+ // Serialises every extrinsic submission on this instance's substrate account. All submit/retract
7684
+ // methods funnel through signAndSendExtrinsic, each using the API's auto-nonce; fired in parallel
7685
+ // (bids for orders on different chains, or several phantom orders in one interval) they would grab
7686
+ // the same nonce and all but one would fail. Concurrency 1 sequences them.
7687
+ submissionQueue = new PQueue({ concurrency: 1 });
7596
7688
  /**
7597
7689
  * Creates and connects an IntentsCoprocessor to a Hyperbridge node.
7598
7690
  * This creates and manages its own API connection.
@@ -7645,14 +7737,17 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7645
7737
  }
7646
7738
  }
7647
7739
  /**
7648
- * Creates a Substrate keypair from the configured private key
7649
- * Supports both hex seed (without 0x prefix) and mnemonic phrases
7740
+ * Creates a Substrate keypair from the configured private key.
7741
+ * Supports hex seed (with or without 0x), mnemonic phrases, and URI derivation paths (//Alice).
7650
7742
  */
7651
7743
  getKeyPair() {
7652
7744
  if (!this.substratePrivateKey) {
7653
7745
  throw new Error("Substrate PrivateKey Required");
7654
7746
  }
7655
7747
  const keyring = new Keyring({ type: "sr25519" });
7748
+ if (this.substratePrivateKey.startsWith("//")) {
7749
+ return keyring.addFromUri(this.substratePrivateKey);
7750
+ }
7656
7751
  if (this.substratePrivateKey.includes(" ")) {
7657
7752
  return keyring.addFromMnemonic(this.substratePrivateKey);
7658
7753
  }
@@ -7661,10 +7756,19 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7661
7756
  return keyring.addFromSeed(seedBytes);
7662
7757
  }
7663
7758
  /**
7664
- * Signs and sends an extrinsic, handling status updates and errors
7665
- * Implements retry logic with progressive tip increases for stuck transactions
7759
+ * Signs and sends an extrinsic. Submissions are serialised through {@link submissionQueue} so
7760
+ * concurrent calls never collide on the substrate account nonce — each extrinsic reaches a block
7761
+ * before the next is signed.
7666
7762
  */
7667
7763
  async signAndSendExtrinsic(extrinsic, maxRetries = 3, timeoutMs = 3e4) {
7764
+ const result = await this.submissionQueue.add(() => this.sendExtrinsicWithRetries(extrinsic, maxRetries, timeoutMs));
7765
+ return result ?? { success: false, error: "Submission queue returned no result" };
7766
+ }
7767
+ /**
7768
+ * Signs and sends an extrinsic, handling status updates and errors.
7769
+ * Implements retry logic with progressive tip increases for stuck transactions.
7770
+ */
7771
+ async sendExtrinsicWithRetries(extrinsic, maxRetries, timeoutMs) {
7668
7772
  const keyPair = this.getKeyPair();
7669
7773
  let baseTip = 500000000000n;
7670
7774
  let attempt = 0;
@@ -7709,20 +7813,51 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7709
7813
  }, timeoutMs);
7710
7814
  extrinsic.signAndSend(keyPair, { tip }, (result) => {
7711
7815
  if (resolved) return;
7712
- if (result.status.isInBlock || result.status.isFinalized) {
7816
+ if (result.dispatchError && (result.status.isInBlock || result.status.isFinalized)) {
7713
7817
  resolved = true;
7714
7818
  clearTimeout(timeoutId);
7819
+ let errorMsg;
7820
+ if (result.dispatchError.isModule) {
7821
+ const decoded = this.api.registry.findMetaError(result.dispatchError.asModule);
7822
+ errorMsg = `Dispatch error: ${decoded.section}::${decoded.name}`;
7823
+ } else {
7824
+ errorMsg = `Dispatch error: ${result.dispatchError.toString()}`;
7825
+ }
7715
7826
  resolve({
7716
- success: true,
7717
- blockHash: result.status.asInBlock.toHex(),
7718
- extrinsicHash: extrinsic.hash.toHex()
7827
+ success: false,
7828
+ error: errorMsg
7719
7829
  });
7720
- } else if (result.dispatchError) {
7830
+ } else if (result.status.isDropped || result.status.isInvalid || result.status.isUsurped || result.status.isFinalityTimeout) {
7721
7831
  resolved = true;
7722
7832
  clearTimeout(timeoutId);
7723
7833
  resolve({
7724
7834
  success: false,
7725
- error: `Dispatch error: ${result.dispatchError.toString()}`
7835
+ error: `Transaction ${result.status.type.toLowerCase()}`
7836
+ });
7837
+ } else if (result.status.isInBlock || result.status.isFinalized) {
7838
+ resolved = true;
7839
+ clearTimeout(timeoutId);
7840
+ const interrupted = result.events.find(
7841
+ ({ event }) => event.section === "utility" && event.method === "BatchInterrupted"
7842
+ );
7843
+ if (interrupted) {
7844
+ const [indexCodec, dispatchError] = interrupted.event.data;
7845
+ if (Number(indexCodec.toString()) === 0) {
7846
+ let errorMsg;
7847
+ if (dispatchError?.isModule) {
7848
+ const decoded = this.api.registry.findMetaError(dispatchError.asModule);
7849
+ errorMsg = `Dispatch error: ${decoded.section}::${decoded.name}`;
7850
+ } else {
7851
+ errorMsg = `Dispatch error: batch interrupted (${dispatchError?.toString()})`;
7852
+ }
7853
+ resolve({ success: false, error: errorMsg });
7854
+ return;
7855
+ }
7856
+ }
7857
+ resolve({
7858
+ success: true,
7859
+ blockHash: (result.status.isInBlock ? result.status.asInBlock : result.status.asFinalized).toHex(),
7860
+ extrinsicHash: extrinsic.hash.toHex()
7726
7861
  });
7727
7862
  }
7728
7863
  }).then((unsub) => {
@@ -7777,6 +7912,40 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7777
7912
  };
7778
7913
  }
7779
7914
  }
7915
+ /**
7916
+ * Places a new bid and retracts a previous one in a single transaction via utility.batch.
7917
+ *
7918
+ * The new bid is the primary operation, so `placeBid` MUST run first. `utility.batch` is
7919
+ * non-atomic: a failing call interrupts the batch (via a BatchInterrupted event) without
7920
+ * reverting the calls that already succeeded. Placing first guarantees the new bid lands even
7921
+ * when the retraction then fails — which it routinely does, because a previous commitment's bid
7922
+ * may already be gone (or was itself never placed), making `retractBid` return `BidNotFound`.
7923
+ *
7924
+ * Ordering retraction first (the previous behaviour) caused a self-sustaining cascade: a
7925
+ * `BidNotFound` on the leading retract skipped the trailing `placeBid`, so the current bid never
7926
+ * landed, so the *next* interval's retract of that never-placed commitment also failed, and so
7927
+ * on — silently, because the batch extrinsic itself reports success. The deposit reclaim is
7928
+ * best-effort; landing the bid is not.
7929
+ *
7930
+ * @param retractCommitment - The order commitment of the bid to retract (bytes32)
7931
+ * @param bidCommitment - The order commitment of the new bid (bytes32)
7932
+ * @param userOp - The encoded PackedUserOperation as hex string
7933
+ * @returns BidSubmissionResult with success status and block/extrinsic hash
7934
+ */
7935
+ async submitBidWithRetraction(retractCommitment, bidCommitment, userOp) {
7936
+ try {
7937
+ const batch = this.api.tx.utility.batch([
7938
+ this.api.tx.intentsCoprocessor.placeBid(bidCommitment, userOp),
7939
+ this.api.tx.intentsCoprocessor.retractBid(retractCommitment)
7940
+ ]);
7941
+ return await this.signAndSendExtrinsic(batch);
7942
+ } catch (error) {
7943
+ return {
7944
+ success: false,
7945
+ error: error instanceof Error ? error.message : "Unknown error"
7946
+ };
7947
+ }
7948
+ }
7780
7949
  /**
7781
7950
  * Fetches all bid storage entries for a given order commitment.
7782
7951
  * Returns the on-chain data only (filler addresses and deposits).
@@ -7861,6 +8030,80 @@ var IntentsCoprocessor = class _IntentsCoprocessor {
7861
8030
  buildOffchainBidKey(commitment, filler) {
7862
8031
  return u8aConcat(OFFCHAIN_BID_PREFIX, hexToU8a(commitment), decodeAddress(filler));
7863
8032
  }
8033
+ /**
8034
+ * Fetches the ABI-encoded phantom order from offchain storage and decodes it
8035
+ * into an `Order` object. The pallet writes the order bytes under the key
8036
+ * `intents::phantom::order::<commitment>` when it calls `on_initialize`.
8037
+ *
8038
+ * Returns `null` if the key is absent (e.g. the node is not an offchain worker
8039
+ * or the commitment has expired and been cleared).
8040
+ */
8041
+ async fetchPhantomOrder(commitment) {
8042
+ const key = u8aConcat(OFFCHAIN_PHANTOM_PREFIX, hexToU8a(commitment));
8043
+ const result = await this.api.rpc.offchain.localStorageGet("PERSISTENT", u8aToHex(key));
8044
+ if (!result || result.isNone) return null;
8045
+ const rawHex = result.unwrap().toHex();
8046
+ if (rawHex === "0x" || rawHex === "0x00") return null;
8047
+ const placeOrderAbi = IntentGatewayV2_default.ABI.find(
8048
+ (item) => item.type === "function" && item.name === "placeOrder"
8049
+ );
8050
+ const orderType = placeOrderAbi?.inputs?.[0];
8051
+ if (!orderType) return null;
8052
+ const [decoded] = decodeAbiParameters([orderType], rawHex);
8053
+ const d = decoded;
8054
+ const textDecoder = new TextDecoder();
8055
+ return {
8056
+ id: commitment,
8057
+ user: d.user,
8058
+ source: textDecoder.decode(hexToBytes(d.source)),
8059
+ destination: textDecoder.decode(hexToBytes(d.destination)),
8060
+ deadline: d.deadline,
8061
+ nonce: d.nonce,
8062
+ fees: d.fees,
8063
+ session: d.session,
8064
+ predispatch: {
8065
+ assets: d.predispatch.assets.map((a) => ({
8066
+ token: a.token,
8067
+ amount: a.amount
8068
+ })),
8069
+ call: d.predispatch.call
8070
+ },
8071
+ inputs: d.inputs.map((i) => ({
8072
+ token: i.token,
8073
+ amount: i.amount
8074
+ })),
8075
+ output: {
8076
+ beneficiary: d.output.beneficiary,
8077
+ assets: d.output.assets.map((a) => ({
8078
+ token: a.token,
8079
+ amount: a.amount
8080
+ })),
8081
+ call: d.output.call
8082
+ }
8083
+ };
8084
+ }
8085
+ /**
8086
+ * Subscribes to PhantomOrderRegistered events from the intents coprocessor pallet.
8087
+ * Calls the callback for each new phantom order as blocks arrive.
8088
+ * Returns an unsubscribe function to stop the subscription.
8089
+ */
8090
+ async subscribePhantomOrders(callback) {
8091
+ const unsub = await this.api.query.system.events((records) => {
8092
+ for (const { event } of records) {
8093
+ if (event.section !== "intentsCoprocessor" || event.method !== "PhantomOrderRegistered") continue;
8094
+ const [commitment, chain, createdAt, tokenA, tokenB, standardAmount] = event.data;
8095
+ callback({
8096
+ commitment: commitment.toHex(),
8097
+ chain: new TextDecoder().decode(hexToU8a(chain.toHex())),
8098
+ createdAt: createdAt.toNumber(),
8099
+ tokenA: tokenA.toHex(),
8100
+ tokenB: tokenB.toHex(),
8101
+ standardAmount: BigInt(standardAmount.toString())
8102
+ });
8103
+ }
8104
+ });
8105
+ return unsub;
8106
+ }
7864
8107
  };
7865
8108
  var TronChain = class _TronChain {
7866
8109
  constructor(params, evm) {
@@ -9799,6 +10042,7 @@ var GetRequestClient = class {
9799
10042
  const latestMetadata = request.statuses[request.statuses.length - 1];
9800
10043
  status = maxBy([status, latestMetadata.status], (item) => REQUEST_STATUS_WEIGHTS[item]);
9801
10044
  if (!status) return;
10045
+ let sourceFinalizedHeight;
9802
10046
  while (true) {
9803
10047
  switch (status) {
9804
10048
  case RequestStatus.SOURCE: {
@@ -9810,6 +10054,7 @@ var GetRequestClient = class {
9810
10054
  chain: this.ctx.config.hyperbridge.config.stateMachineId
9811
10055
  })
9812
10056
  });
10057
+ sourceFinalizedHeight = BigInt(sourceUpdate.height);
9813
10058
  yield {
9814
10059
  status: RequestStatus.SOURCE_FINALIZED,
9815
10060
  metadata: {
@@ -9823,6 +10068,15 @@ var GetRequestClient = class {
9823
10068
  break;
9824
10069
  }
9825
10070
  case RequestStatus.SOURCE_FINALIZED: {
10071
+ if (request.source !== this.ctx.config.hyperbridge.config.stateMachineId && sourceFinalizedHeight !== void 0) {
10072
+ try {
10073
+ await this.deliverToHyperbridge(request, sourceFinalizedHeight);
10074
+ } catch (error) {
10075
+ this.logger.warn(
10076
+ `Self-delivery to Hyperbridge failed; waiting for a relayer instead: ${error instanceof Error ? error.message : error}`
10077
+ );
10078
+ }
10079
+ }
9826
10080
  request = await waitOrAbort(this.ctx, {
9827
10081
  signal,
9828
10082
  promise: () => this.queries.queryGetRequest(hash),
@@ -9843,7 +10097,10 @@ var GetRequestClient = class {
9843
10097
  }
9844
10098
  case RequestStatus.HYPERBRIDGE_DELIVERED: {
9845
10099
  if (request.source === this.ctx.config.hyperbridge.config.stateMachineId) return;
9846
- const response = await this.queries.queryResponseByRequestId(hash);
10100
+ const response = await waitOrAbort(this.ctx, {
10101
+ signal,
10102
+ promise: () => this.queries.queryResponseByRequestId(hash)
10103
+ });
9847
10104
  yield await this.streamFinalized(signal, request, 1, response);
9848
10105
  status = RequestStatus.HYPERBRIDGE_FINALIZED;
9849
10106
  break;
@@ -9873,6 +10130,102 @@ var GetRequestClient = class {
9873
10130
  }
9874
10131
  }
9875
10132
  }
10133
+ /**
10134
+ * Self-delivers a GET request to Hyperbridge — the request→Hyperbridge hop that would
10135
+ * otherwise require an external relayer.
10136
+ *
10137
+ * Mirrors the relayer path (and {@link OrderCanceller}): prove the request commitment on
10138
+ * the source chain at the Hyperbridge-finalized source height, prove the requested keys on
10139
+ * the destination chain at the request's height, wait out the source challenge period, then
10140
+ * submit an unsigned `GetRequest` message. Source and destination may each be EVM or
10141
+ * substrate — proofs are built via the chain-agnostic {@link IChain} methods.
10142
+ *
10143
+ * Idempotent: returns early if Hyperbridge already holds the response receipt. The caller
10144
+ * wraps this best-effort, so a failure leaves the stream observing as before.
10145
+ */
10146
+ async deliverToHyperbridge(request, sourceFinalizedHeight) {
10147
+ const sourceChain = this.ctx.config.source;
10148
+ const destChain = this.ctx.config.dest;
10149
+ const hyperbridge = this.ctx.config.hyperbridge;
10150
+ const commitment = getRequestCommitment({ ...request, keys: [...request.keys] });
10151
+ const retry = { maxRetries: 5, backoffMs: 2e3 };
10152
+ if (await withRetry(this.ctx, () => hyperbridge.queryResponseReceipt(commitment), retry)) return;
10153
+ this.logger.info(
10154
+ `Delivering GET ${commitment} to Hyperbridge (${request.source}@${sourceFinalizedHeight} \u2192 ${request.dest}@${request.height})`
10155
+ );
10156
+ const sourceProof = {
10157
+ height: sourceFinalizedHeight,
10158
+ stateMachine: request.source,
10159
+ consensusStateId: sourceChain.config.consensusStateId,
10160
+ proof: await withRetry(
10161
+ this.ctx,
10162
+ () => sourceChain.queryProof(
10163
+ { Requests: [commitment] },
10164
+ this.ctx.config.hyperbridge.config.stateMachineId,
10165
+ sourceFinalizedHeight
10166
+ ),
10167
+ retry
10168
+ )
10169
+ };
10170
+ this.logger.info(` \u2713 built source proof: ${(sourceProof.proof.length - 2) / 2} bytes @ ${request.source}#${sourceFinalizedHeight}`);
10171
+ const destCommitment = await withRetry(
10172
+ this.ctx,
10173
+ () => hyperbridge.queryStateMachineCommitment({
10174
+ id: {
10175
+ stateId: parseStateMachineId(request.dest).stateId,
10176
+ consensusStateId: destChain.config.consensusStateId
10177
+ },
10178
+ height: request.height
10179
+ }),
10180
+ retry
10181
+ );
10182
+ if (!destCommitment) {
10183
+ throw new Error(`Hyperbridge has no state commitment for ${request.dest} at height ${request.height}`);
10184
+ }
10185
+ const responseProof = {
10186
+ height: request.height,
10187
+ stateMachine: request.dest,
10188
+ consensusStateId: destChain.config.consensusStateId,
10189
+ proof: await withRetry(this.ctx, () => destChain.queryStateProof(request.height, [...request.keys]), retry)
10190
+ };
10191
+ this.logger.info(
10192
+ ` \u2713 built response proof: ${(responseProof.proof.length - 2) / 2} bytes (${request.keys.length} key(s) @ ${request.dest}#${request.height})`
10193
+ );
10194
+ await withRetry(
10195
+ this.ctx,
10196
+ () => waitForChallengePeriod(hyperbridge, {
10197
+ height: sourceFinalizedHeight,
10198
+ id: {
10199
+ stateId: parseStateMachineId(request.source).stateId,
10200
+ consensusStateId: sourceChain.config.consensusStateId
10201
+ }
10202
+ }),
10203
+ retry
10204
+ );
10205
+ const message = {
10206
+ kind: "GetRequest",
10207
+ requests: [
10208
+ {
10209
+ source: request.source,
10210
+ dest: request.dest,
10211
+ nonce: request.nonce,
10212
+ from: request.from,
10213
+ timeoutTimestamp: request.timeoutTimestamp,
10214
+ keys: [...request.keys],
10215
+ height: request.height,
10216
+ context: request.context
10217
+ }
10218
+ ],
10219
+ source: sourceProof,
10220
+ response: responseProof,
10221
+ signer: pad("0x")
10222
+ };
10223
+ this.logger.info(" \u2192 submitting GetRequest message (source + response proofs) to Hyperbridge\u2026");
10224
+ const result = await withRetry(this.ctx, () => hyperbridge.submitUnsigned(message), retry);
10225
+ this.logger.info(
10226
+ ` \u2713 delivered GET ${commitment} in Hyperbridge block #${result.blockNumber} (tx ${result.transactionHash})`
10227
+ );
10228
+ }
9876
10229
  /**
9877
10230
  * Snapshot helper: returns the `HYPERBRIDGE_FINALIZED` event with source-chain
9878
10231
  * calldata if prerequisites are met, or `undefined` if we're still waiting
@@ -9886,7 +10239,7 @@ var GetRequestClient = class {
9886
10239
  const finality = await this.queries.queryStateMachineUpdateByHeight({
9887
10240
  statemachineId: config.stateMachineId,
9888
10241
  height: hyperbridgeDelivered.metadata.blockNumber,
9889
- chain: config.stateMachineId
10242
+ chain: request.source
9890
10243
  });
9891
10244
  if (finality) {
9892
10245
  const proof = await hyperbridge.queryProof(
@@ -9957,14 +10310,19 @@ var GetRequestClient = class {
9957
10310
  ],
9958
10311
  signer: pad("0x")
9959
10312
  });
10313
+ const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
10314
+ statemachineId: config.stateMachineId,
10315
+ height: hyperbridgeDelivered.metadata.blockNumber,
10316
+ chain: config.stateMachineId
10317
+ });
10318
+ if (!hyperbridgeFinality) return void 0;
9960
10319
  return {
9961
10320
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
9962
10321
  metadata: {
9963
- blockHash: hyperbridgeDelivered.metadata.blockHash,
9964
- blockNumber: Number(consensusResult.provenHeight),
9965
- transactionHash: hyperbridgeDelivered.metadata.transactionHash,
9966
- // @ts-ignore
9967
- timestamp: hyperbridgeDelivered.metadata.timestamp,
10322
+ blockHash: hyperbridgeFinality.blockHash,
10323
+ blockNumber: hyperbridgeFinality.height,
10324
+ transactionHash: hyperbridgeFinality.transactionHash,
10325
+ timestamp: hyperbridgeFinality.timestamp,
9968
10326
  calldata
9969
10327
  }
9970
10328
  };
@@ -9984,12 +10342,44 @@ var GetRequestClient = class {
9984
10342
  const hyperbridge = this.ctx.config.hyperbridge;
9985
10343
  const stateMachineId = this.ctx.config.hyperbridge.config.stateMachineId;
9986
10344
  const neededHeight = BigInt(request.statuses[hyperbridgeDeliveredIndex].metadata.blockNumber);
10345
+ const consensusStateId = this.ctx.config.hyperbridge.config.consensusStateId;
10346
+ const encodeGetResponse = (height, proof2) => sourceChain.encode({
10347
+ kind: "GetResponse",
10348
+ proof: { stateMachine: stateMachineId, consensusStateId, proof: proof2, height },
10349
+ responses: [
10350
+ {
10351
+ get: request,
10352
+ values: request.keys.map((key, index) => ({
10353
+ key,
10354
+ value: response?.values[index] || "0x"
10355
+ }))
10356
+ }
10357
+ ],
10358
+ signer: pad("0x")
10359
+ });
9987
10360
  let finality = await this.queries.queryStateMachineUpdateByHeight({
9988
10361
  statemachineId: stateMachineId,
9989
10362
  height: Number(neededHeight),
9990
- chain: stateMachineId
10363
+ chain: request.source
9991
10364
  });
9992
- if (!finality && sourceChain instanceof EvmChain) {
10365
+ if (finality) {
10366
+ const proof2 = await hyperbridge.queryProof(
10367
+ { Responses: [response?.commitment] },
10368
+ request.source,
10369
+ BigInt(finality.height)
10370
+ );
10371
+ return {
10372
+ status: RequestStatus.HYPERBRIDGE_FINALIZED,
10373
+ metadata: {
10374
+ blockHash: finality.blockHash,
10375
+ blockNumber: finality.height,
10376
+ transactionHash: finality.transactionHash,
10377
+ timestamp: finality.timestamp,
10378
+ calldata: encodeGetResponse(BigInt(finality.height), proof2)
10379
+ }
10380
+ };
10381
+ }
10382
+ if (sourceChain instanceof EvmChain) {
9993
10383
  const hyperbridgeSubstrate = hyperbridge;
9994
10384
  const currentEpoch = await sourceChain.currentEpoch();
9995
10385
  const consensusResult = await waitOrAbort(this.ctx, {
@@ -10001,12 +10391,12 @@ var GetRequestClient = class {
10001
10391
  request.source,
10002
10392
  consensusResult.provenHeight
10003
10393
  );
10004
- const calldata2 = sourceChain.encode({
10394
+ const calldata = sourceChain.encode({
10005
10395
  kind: "BatchConsensusAndGetResponse",
10006
10396
  consensusProofs: consensusResult.proofs,
10007
10397
  proof: {
10008
10398
  stateMachine: stateMachineId,
10009
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10399
+ consensusStateId,
10010
10400
  proof: proof2,
10011
10401
  height: consensusResult.provenHeight
10012
10402
  },
@@ -10021,20 +10411,7 @@ var GetRequestClient = class {
10021
10411
  ],
10022
10412
  signer: pad("0x")
10023
10413
  });
10024
- return {
10025
- status: RequestStatus.HYPERBRIDGE_FINALIZED,
10026
- metadata: {
10027
- blockHash: request.statuses[hyperbridgeDeliveredIndex].metadata.blockHash,
10028
- blockNumber: Number(consensusResult.provenHeight),
10029
- transactionHash: request.statuses[hyperbridgeDeliveredIndex].metadata.transactionHash,
10030
- // @ts-ignore
10031
- timestamp: request.statuses[hyperbridgeDeliveredIndex].metadata.timestamp,
10032
- calldata: calldata2
10033
- }
10034
- };
10035
- }
10036
- if (!finality) {
10037
- finality = await waitOrAbort(this.ctx, {
10414
+ const hyperbridgeFinality = await waitOrAbort(this.ctx, {
10038
10415
  signal,
10039
10416
  promise: () => this.queries.queryStateMachineUpdateByHeight({
10040
10417
  statemachineId: stateMachineId,
@@ -10042,31 +10419,30 @@ var GetRequestClient = class {
10042
10419
  chain: stateMachineId
10043
10420
  })
10044
10421
  });
10422
+ return {
10423
+ status: RequestStatus.HYPERBRIDGE_FINALIZED,
10424
+ metadata: {
10425
+ blockHash: hyperbridgeFinality.blockHash,
10426
+ blockNumber: hyperbridgeFinality.height,
10427
+ transactionHash: hyperbridgeFinality.transactionHash,
10428
+ timestamp: hyperbridgeFinality.timestamp,
10429
+ calldata
10430
+ }
10431
+ };
10045
10432
  }
10433
+ finality = await waitOrAbort(this.ctx, {
10434
+ signal,
10435
+ promise: () => this.queries.queryStateMachineUpdateByHeight({
10436
+ statemachineId: stateMachineId,
10437
+ height: Number(neededHeight),
10438
+ chain: request.source
10439
+ })
10440
+ });
10046
10441
  const proof = await hyperbridge.queryProof(
10047
10442
  { Responses: [response?.commitment] },
10048
10443
  request.source,
10049
10444
  BigInt(finality.height)
10050
10445
  );
10051
- const calldata = sourceChain.encode({
10052
- kind: "GetResponse",
10053
- proof: {
10054
- stateMachine: stateMachineId,
10055
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10056
- proof,
10057
- height: BigInt(finality.height)
10058
- },
10059
- responses: [
10060
- {
10061
- get: request,
10062
- values: request.keys.map((key, index) => ({
10063
- key,
10064
- value: response?.values[index] || "0x"
10065
- }))
10066
- }
10067
- ],
10068
- signer: pad("0x")
10069
- });
10070
10446
  return {
10071
10447
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10072
10448
  metadata: {
@@ -10074,7 +10450,7 @@ var GetRequestClient = class {
10074
10450
  blockNumber: finality.height,
10075
10451
  transactionHash: finality.transactionHash,
10076
10452
  timestamp: finality.timestamp,
10077
- calldata
10453
+ calldata: encodeGetResponse(BigInt(finality.height), proof)
10078
10454
  }
10079
10455
  };
10080
10456
  }
@@ -10577,7 +10953,7 @@ var PostRequestClient = class {
10577
10953
  const finality = await this.queries.queryStateMachineUpdateByHeight({
10578
10954
  statemachineId: config.stateMachineId,
10579
10955
  height: hyperbridgeDelivered.metadata.blockNumber,
10580
- chain: config.stateMachineId
10956
+ chain: request.dest
10581
10957
  });
10582
10958
  if (finality) {
10583
10959
  const proof = await hyperbridge.queryProof(
@@ -10632,14 +11008,19 @@ var PostRequestClient = class {
10632
11008
  requests: [request],
10633
11009
  signer: pad("0x")
10634
11010
  });
11011
+ const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
11012
+ statemachineId: config.stateMachineId,
11013
+ height: hyperbridgeDelivered.metadata.blockNumber,
11014
+ chain: config.stateMachineId
11015
+ });
11016
+ if (!hyperbridgeFinality) return void 0;
10635
11017
  return {
10636
11018
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10637
11019
  metadata: {
10638
- blockHash: hyperbridgeDelivered.metadata.blockHash,
10639
- blockNumber: Number(consensusResult.provenHeight),
10640
- transactionHash: hyperbridgeDelivered.metadata.transactionHash,
10641
- // @ts-ignore
10642
- timestamp: hyperbridgeDelivered.metadata.timestamp,
11020
+ blockHash: hyperbridgeFinality.blockHash,
11021
+ blockNumber: hyperbridgeFinality.height,
11022
+ transactionHash: hyperbridgeFinality.transactionHash,
11023
+ timestamp: hyperbridgeFinality.timestamp,
10643
11024
  calldata
10644
11025
  }
10645
11026
  };
@@ -10662,7 +11043,7 @@ var PostRequestClient = class {
10662
11043
  let finality = await this.queries.queryStateMachineUpdateByHeight({
10663
11044
  statemachineId: stateMachineId,
10664
11045
  height: Number(neededHeight),
10665
- chain: stateMachineId
11046
+ chain: request.dest
10666
11047
  });
10667
11048
  if (!finality && destChain instanceof EvmChain) {
10668
11049
  const hyperbridgeSubstrate = hyperbridge;
@@ -10690,14 +11071,21 @@ var PostRequestClient = class {
10690
11071
  requests: [request],
10691
11072
  signer: pad("0x")
10692
11073
  });
11074
+ const hyperbridgeFinality = await waitOrAbort(this.ctx, {
11075
+ signal,
11076
+ promise: () => this.queries.queryStateMachineUpdateByHeight({
11077
+ statemachineId: stateMachineId,
11078
+ height: Number(neededHeight),
11079
+ chain: stateMachineId
11080
+ })
11081
+ });
10693
11082
  return {
10694
11083
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10695
11084
  metadata: {
10696
- blockHash: request.statuses[hyperbridgeDeliveredIndex].metadata.blockHash,
10697
- blockNumber: Number(consensusResult.provenHeight),
10698
- transactionHash: request.statuses[hyperbridgeDeliveredIndex].metadata.transactionHash,
10699
- // @ts-ignore
10700
- timestamp: request.statuses[hyperbridgeDeliveredIndex].metadata.timestamp,
11085
+ blockHash: hyperbridgeFinality.blockHash,
11086
+ blockNumber: hyperbridgeFinality.height,
11087
+ transactionHash: hyperbridgeFinality.transactionHash,
11088
+ timestamp: hyperbridgeFinality.timestamp,
10701
11089
  calldata: calldata2
10702
11090
  }
10703
11091
  };
@@ -10708,7 +11096,7 @@ var PostRequestClient = class {
10708
11096
  promise: () => this.queries.queryStateMachineUpdateByHeight({
10709
11097
  statemachineId: stateMachineId,
10710
11098
  height: Number(neededHeight),
10711
- chain: stateMachineId
11099
+ chain: request.dest
10712
11100
  })
10713
11101
  });
10714
11102
  }
@@ -14603,16 +14991,6 @@ var CryptoUtils = class _CryptoUtils {
14603
14991
  }
14604
14992
  }
14605
14993
  };
14606
- var FEE_TOKEN_CACHE_TTL_MS = 5 * 60 * 1e3;
14607
- async function getFeeToken(ctx, chainId, chain) {
14608
- const cached = ctx.feeTokenCache.get(chainId);
14609
- if (cached && Date.now() - cached.cachedAt < FEE_TOKEN_CACHE_TTL_MS) {
14610
- return cached;
14611
- }
14612
- const fresh = await chain.getFeeTokenWithDecimals();
14613
- ctx.feeTokenCache.set(chainId, { ...fresh, cachedAt: Date.now() });
14614
- return fresh;
14615
- }
14616
14994
  function encodeERC7821ExecuteBatch(calls) {
14617
14995
  const executionData = encodeAbiParameters(
14618
14996
  [{ type: "tuple[]", components: erc7281_default.ABI[1].components }],
@@ -14624,6 +15002,36 @@ function encodeERC7821ExecuteBatch(calls) {
14624
15002
  args: [ERC7821_BATCH_MODE, executionData]
14625
15003
  });
14626
15004
  }
15005
+ function decodeERC7821ExecuteBatch(callData) {
15006
+ try {
15007
+ const decoded = decodeFunctionData({ abi: erc7281_default.ABI, data: callData });
15008
+ if (decoded.functionName !== "execute" || !decoded.args || decoded.args.length < 2) return null;
15009
+ const executionData = decoded.args[1];
15010
+ const [calls] = decodeAbiParameters(
15011
+ [{ type: "tuple[]", components: erc7281_default.ABI[1].components }],
15012
+ executionData
15013
+ );
15014
+ return calls.map((call) => ({
15015
+ target: call.target,
15016
+ value: call.value,
15017
+ data: call.data
15018
+ }));
15019
+ } catch {
15020
+ return null;
15021
+ }
15022
+ }
15023
+
15024
+ // src/protocols/intents/utils.ts
15025
+ var FEE_TOKEN_CACHE_TTL_MS = 5 * 60 * 1e3;
15026
+ async function getFeeToken(ctx, chainId, chain) {
15027
+ const cached = ctx.feeTokenCache.get(chainId);
15028
+ if (cached && Date.now() - cached.cachedAt < FEE_TOKEN_CACHE_TTL_MS) {
15029
+ return cached;
15030
+ }
15031
+ const fresh = await chain.getFeeTokenWithDecimals();
15032
+ ctx.feeTokenCache.set(chainId, { ...fresh, cachedAt: Date.now() });
15033
+ return fresh;
15034
+ }
14627
15035
  async function fetchSourceProof(commitment, source, sourceStateMachine, sourceConsensusStateId, sourceHeight) {
14628
15036
  const { slot1, slot2 } = requestCommitmentKey(commitment);
14629
15037
  const proofHex = await source.queryStateProof(sourceHeight, [slot1, slot2]);
@@ -18503,6 +18911,11 @@ var HyperFungibleTokenABI = [
18503
18911
  name: "context",
18504
18912
  type: "bytes",
18505
18913
  internalType: "bytes"
18914
+ },
18915
+ {
18916
+ name: "payer",
18917
+ type: "address",
18918
+ internalType: "address"
18506
18919
  }
18507
18920
  ]
18508
18921
  }
@@ -19624,6 +20037,11 @@ var WrappedHyperFungibleTokenABI = [
19624
20037
  name: "context",
19625
20038
  type: "bytes",
19626
20039
  internalType: "bytes"
20040
+ },
20041
+ {
20042
+ name: "payer",
20043
+ type: "address",
20044
+ internalType: "address"
19627
20045
  }
19628
20046
  ]
19629
20047
  }
@@ -21461,6 +21879,11 @@ var ABI8 = [
21461
21879
  internalType: "bytes",
21462
21880
  name: "context",
21463
21881
  type: "bytes"
21882
+ },
21883
+ {
21884
+ internalType: "address",
21885
+ name: "payer",
21886
+ type: "address"
21464
21887
  }
21465
21888
  ],
21466
21889
  internalType: "struct DispatchGet",
@@ -21729,6 +22152,11 @@ var ABI8 = [
21729
22152
  internalType: "bytes",
21730
22153
  name: "context",
21731
22154
  type: "bytes"
22155
+ },
22156
+ {
22157
+ internalType: "address",
22158
+ name: "payer",
22159
+ type: "address"
21732
22160
  }
21733
22161
  ],
21734
22162
  internalType: "struct DispatchGet",
@@ -22091,6 +22519,6 @@ async function teleportDot(param_) {
22091
22519
  return stream;
22092
22520
  }
22093
22521
 
22094
- export { ADDRESS_ZERO2 as ADDRESS_ZERO, BundlerMethod, ChainConfigService, Chains, CryptoUtils, DEFAULT_ADDRESS, DEFAULT_GRAFFITI, DOMAIN_TYPEHASH, DUMMY_PRIVATE_KEY, ERC20Method, ERC7821_BATCH_MODE, EvmChain, ABI as EvmHostABI, EvmLanguage, HyperClientStatus, HyperFungibleToken, HyperFungibleTokenABI, IntentGateway, ABI3 as IntentGatewayABI, IntentOrderStatus, IntentsCoprocessor, IsmpClient, MOCK_ADDRESS, ORDER_V2_PARAM_TYPE, OrderStatus, OrderStatusChecker, PACKED_USEROP_TYPEHASH, PLACE_ORDER_SELECTOR, PharosChain, PolkadotHubChain, REQUEST_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, RESPONSE_COMMITMENTS_SLOT, RESPONSE_RECEIPTS_SLOT, RequestKind, RequestStatus, SELECT_SOLVER_TYPEHASH, STATE_COMMITMENTS_SLOT, SubstrateChain, Swap, TESTNET_CHAINS, TeleportStatus, TimeoutStatus, TokenGateway, TronChain, USE_ETHERSCAN_CHAINS, UnsupportedIntentQuotePairError, UnsupportedIntentQuoteStrategyError, WrappedHyperFungibleTokenABI, __test, adjustDecimals, bytes20ToBytes32, bytes32ToBytes20, calculateAllowanceMappingLocation, calculateBalanceMappingLocation, chainConfigs, constructRedeemEscrowRequestBody, constructRefundEscrowRequestBody, convertCodecToIGetRequest, convertCodecToIProof, convertIGetRequestToCodec, convertIProofToCodec, convertStateIdToStateMachineId, convertStateMachineEnumToString, convertStateMachineIdToEnum, createEvmChain, createQueryClient, decodeUserOpScale, encodeERC7821ExecuteBatch, encodeISMPMessage, encodeStateMachineId, encodeUserOpScale, encodeWithdrawalRequest, estimateGasForPost, fetchPrice, fetchSourceProof, generateRootWithProof, getChainId, getConfigByStateMachineId, getContractCallInput, getContractCallInputs, getGasPriceFromEtherscan, getOrFetchStorageSlot, getOrderPlacedFromTx, getPostRequestEventFromTx, getPostResponseEventFromTx, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, getViemChain, hexToString, hyperbridgeAddress, maxBigInt, normalizeAddressForEvmBytes32, normalizeAddressForStateMachine, normalizeEvmChainId, normalizeStateMachineId, orderCommitment, parseStateMachineId, pharosAtlantic, pharosMainnet, polkadotAssetHubPaseo, polkadotHubMainnet, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, quoteUniswap, requestCommitmentKey, responseCommitmentKey, retryPromise, teleport, teleportDot, transformOrderForContract, tronChainIds, tronNile };
22522
+ export { ADDRESS_ZERO2 as ADDRESS_ZERO, BundlerMethod, ChainConfigService, Chains, CryptoUtils, DEFAULT_ADDRESS, DEFAULT_GRAFFITI, DOMAIN_TYPEHASH, DUMMY_PRIVATE_KEY, ERC20Method, ERC7821_BATCH_MODE, EvmChain, ABI as EvmHostABI, EvmLanguage, HyperClientStatus, HyperFungibleToken, HyperFungibleTokenABI, IntentGateway, ABI3 as IntentGatewayABI, IntentOrderStatus, IntentsCoprocessor, IsmpClient, MOCK_ADDRESS, ORDER_V2_PARAM_TYPE, OrderStatus, OrderStatusChecker, PACKED_USEROP_TYPEHASH, PLACE_ORDER_SELECTOR, PharosChain, PolkadotHubChain, REQUEST_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, RESPONSE_COMMITMENTS_SLOT, RESPONSE_RECEIPTS_SLOT, RequestKind, RequestStatus, SELECT_SOLVER_TYPEHASH, STATE_COMMITMENTS_SLOT, SubstrateChain, Swap, TESTNET_CHAINS, TeleportStatus, TimeoutStatus, TokenGateway, TronChain, USE_ETHERSCAN_CHAINS, UnsupportedIntentQuotePairError, UnsupportedIntentQuoteStrategyError, WrappedHyperFungibleTokenABI, __test, adjustDecimals, bytes20ToBytes32, bytes32ToBytes20, calculateAllowanceMappingLocation, calculateBalanceMappingLocation, chainConfigs, constructRedeemEscrowRequestBody, constructRefundEscrowRequestBody, convertCodecToIGetRequest, convertCodecToIProof, convertIGetRequestToCodec, convertIProofToCodec, convertStateIdToStateMachineId, convertStateMachineEnumToString, convertStateMachineIdToEnum, createEvmChain, createQueryClient, decodeERC7821ExecuteBatch, decodeUserOpScale, encodeERC7821ExecuteBatch, encodeISMPMessage, encodeStateMachineId, encodeUserOpScale, encodeWithdrawalRequest, estimateGasForPost, fetchPrice, fetchSourceProof, generateRootWithProof, getChainId, getConfigByStateMachineId, getContractCallInput, getContractCallInputs, getGasPriceFromEtherscan, getOrFetchStorageSlot, getOrderPlacedFromTx, getPostRequestEventFromTx, getPostResponseEventFromTx, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, getViemChain, hexToString, hyperbridgeAddress, maxBigInt, normalizeAddressForEvmBytes32, normalizeAddressForStateMachine, normalizeEvmChainId, normalizeStateMachineId, orderCommitment, parseStateMachineId, pharosAtlantic, pharosMainnet, polkadotAssetHubPaseo, polkadotHubMainnet, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, quoteUniswap, requestCommitmentKey, responseCommitmentKey, retryPromise, teleport, teleportDot, transformOrderForContract, tronChainIds, tronNile };
22095
22523
  //# sourceMappingURL=index.js.map
22096
22524
  //# sourceMappingURL=index.js.map