@hyperbridge/sdk 2.2.0 → 2.2.2

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, formatUnits } from 'viem';
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';
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';
@@ -2569,7 +2569,7 @@ var chainConfigs = {
2569
2569
  USDT: { balanceSlot: 151, allowanceSlot: 152 }
2570
2570
  },
2571
2571
  addresses: {
2572
- IntentGateway: "0xFbF50B2b32768127603cC9eF4b871574b881b8eD",
2572
+ IntentGateway: "0xE13fB34CAe12505ae51BaC8C405AF8EB27AC8058",
2573
2573
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
2574
2574
  Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
2575
2575
  UniswapRouter02: "0x9639379819420704457B07A0C33B678D9E0F8Df0",
@@ -2579,7 +2579,7 @@ var chainConfigs = {
2579
2579
  UniswapV3Quoter: "0x0000000000000000000000000000000000000000",
2580
2580
  UniswapV4Quoter: "0x0000000000000000000000000000000000000000",
2581
2581
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
2582
- SolverAccount: "0xCDFcFeD7A14154846808FddC8Ba971A2f8a830a3"
2582
+ SolverAccount: "0x0b5cfBc16ef60AD6930ba5A90Bb09475B7BF3815"
2583
2583
  },
2584
2584
  rpcEnvKey: "BSC_CHAPEL",
2585
2585
  defaultRpcUrl: "https://bnb-testnet.api.onfinality.io/public",
@@ -2686,8 +2686,8 @@ var chainConfigs = {
2686
2686
  DAI: { balanceSlot: 0, allowanceSlot: 0 }
2687
2687
  },
2688
2688
  addresses: {
2689
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
2690
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
2689
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2690
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2691
2691
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2692
2692
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2693
2693
  UniswapRouter02: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
@@ -2741,8 +2741,8 @@ var chainConfigs = {
2741
2741
  DAI: { balanceSlot: 0, allowanceSlot: 0 }
2742
2742
  },
2743
2743
  addresses: {
2744
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
2745
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
2744
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2745
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2746
2746
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2747
2747
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2748
2748
  UniswapRouter02: "0x10ED43C718714eb63d5aA57B78B54704E256024E",
@@ -2797,8 +2797,8 @@ var chainConfigs = {
2797
2797
  DAI: { balanceSlot: 0, allowanceSlot: 0 }
2798
2798
  },
2799
2799
  addresses: {
2800
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
2801
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
2800
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2801
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2802
2802
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2803
2803
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2804
2804
  UniswapRouter02: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
@@ -2854,8 +2854,8 @@ var chainConfigs = {
2854
2854
  DAI: { balanceSlot: 0, allowanceSlot: 0 }
2855
2855
  },
2856
2856
  addresses: {
2857
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
2858
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
2857
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2858
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2859
2859
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2860
2860
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2861
2861
  UniswapRouter02: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
@@ -2879,6 +2879,7 @@ var chainConfigs = {
2879
2879
  consensusStateId: "ETH0",
2880
2880
  coingeckoId: "base",
2881
2881
  layerZeroEid: 30184,
2882
+ uniswapV4Pools: [{ tokens: ["USDC", "cNGN"], fee: 1500, tickSpacing: 30 }],
2882
2883
  popularTokens: [
2883
2884
  "0x4200000000000000000000000000000000000006",
2884
2885
  "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
@@ -2912,8 +2913,8 @@ var chainConfigs = {
2912
2913
  DAI: { balanceSlot: 0, allowanceSlot: 0 }
2913
2914
  },
2914
2915
  addresses: {
2915
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
2916
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
2916
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2917
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2917
2918
  TokenGateway: "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E",
2918
2919
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2919
2920
  UniswapRouter02: "0xd2f9496824951D5237cC71245D659E48d0d5f9E8",
@@ -2983,7 +2984,7 @@ var chainConfigs = {
2983
2984
  //wmatic, change it to wpol
2984
2985
  DAI: "0x0000000000000000000000000000000000000000",
2985
2986
  USDC: "0x693b854d6965ffeaae21c74049dea644b56fcacb",
2986
- USDT: "0x693b854d6965ffeaae21c74049dea644b56fcacb"
2987
+ USDT: "0x0000000000000000000000000000000000000000"
2987
2988
  },
2988
2989
  tokenDecimals: {
2989
2990
  USDC: 18,
@@ -2994,13 +2995,13 @@ var chainConfigs = {
2994
2995
  USDC: { balanceSlot: 1, allowanceSlot: 2 }
2995
2996
  },
2996
2997
  addresses: {
2997
- IntentGateway: "0xFbF50B2b32768127603cC9eF4b871574b881b8eD",
2998
+ IntentGateway: "0xE13fB34CAe12505ae51BaC8C405AF8EB27AC8058",
2998
2999
  TokenGateway: "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E",
2999
3000
  Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3000
3001
  Calldispatcher: "0x876F1891982E260026630c233A4897160A281Fb8",
3001
3002
  Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
3002
3003
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
3003
- SolverAccount: "0xCDFcFeD7A14154846808FddC8Ba971A2f8a830a3"
3004
+ SolverAccount: "0x0b5cfBc16ef60AD6930ba5A90Bb09475B7BF3815"
3004
3005
  },
3005
3006
  rpcEnvKey: "POLYGON_AMOY",
3006
3007
  defaultRpcUrl: "https://rpc-amoy.polygon.technology",
@@ -3023,8 +3024,8 @@ var chainConfigs = {
3023
3024
  USDT: 6
3024
3025
  },
3025
3026
  addresses: {
3026
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
3027
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
3027
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
3028
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
3028
3029
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
3029
3030
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
3030
3031
  UniswapRouter02: "0x4A7b5Da61326A6379179b40d00F57E5bbDC962c2",
@@ -3058,8 +3059,8 @@ var chainConfigs = {
3058
3059
  USDT: 6
3059
3060
  },
3060
3061
  addresses: {
3061
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
3062
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
3062
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
3063
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
3063
3064
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
3064
3065
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
3065
3066
  UniswapRouter02: "0xB2e26652e4BAd1e56055A051f922E06760cA0BFE",
@@ -3213,8 +3214,8 @@ var chainConfigs = {
3213
3214
  USDT: 6
3214
3215
  },
3215
3216
  addresses: {
3216
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
3217
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
3217
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
3218
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
3218
3219
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
3219
3220
  Calldispatcher: "0xE2C7e576E26E0bE7aC97c6fE925bcDAbD87c4bEd"
3220
3221
  },
@@ -5092,6 +5093,9 @@ var ChainConfigService = class {
5092
5093
  getDaiAsset(chain) {
5093
5094
  return this.getConfig(chain)?.assets?.DAI ?? "0x";
5094
5095
  }
5096
+ getAssetAddress(chain, symbol) {
5097
+ return this.getConfig(chain)?.assets?.[symbol];
5098
+ }
5095
5099
  getUsdtAsset(chain) {
5096
5100
  return this.getConfig(chain)?.assets?.USDT ?? "0x";
5097
5101
  }
@@ -5160,6 +5164,9 @@ var ChainConfigService = class {
5160
5164
  getUniswapV4StateViewAddress(chain) {
5161
5165
  return this.getConfig(chain)?.addresses.UniswapV4StateView ?? "0x";
5162
5166
  }
5167
+ getUniswapV4PoolConfigs(chain) {
5168
+ return this.getConfig(chain)?.uniswapV4Pools ?? [];
5169
+ }
5163
5170
  getPermit2Address(chain) {
5164
5171
  return this.getConfig(chain)?.addresses.Permit2 ?? "0x";
5165
5172
  }
@@ -5170,7 +5177,7 @@ var ChainConfigService = class {
5170
5177
  return this.getConfig(chain)?.coingeckoId;
5171
5178
  }
5172
5179
  getEtherscanApiKey() {
5173
- return typeof process !== "undefined" ? process?.env?.ETHERSCAN_API_KEY : void 0;
5180
+ return typeof process !== "undefined" ? process.env?.ETHERSCAN_API_KEY : void 0;
5174
5181
  }
5175
5182
  getCalldispatcherAddress(chain) {
5176
5183
  return this.getConfig(chain)?.addresses.Calldispatcher ?? "0x";
@@ -9539,7 +9546,28 @@ function adjustDecimals(feeInFeeToken, fromDecimals, toDecimals) {
9539
9546
  }
9540
9547
  }
9541
9548
  var USE_ETHERSCAN_CHAINS = /* @__PURE__ */ new Set(["EVM-137", "EVM-56", "EVM-1"]);
9542
- var TESTNET_CHAINS = /* @__PURE__ */ new Set(["EVM-10200", "EVM-97"]);
9549
+ var TESTNET_CHAINS = /* @__PURE__ */ new Set([
9550
+ "EVM-97",
9551
+ // BSC Chapel
9552
+ "EVM-10200",
9553
+ // Gnosis Chiado
9554
+ "EVM-11155111",
9555
+ // Sepolia
9556
+ "EVM-421614",
9557
+ // Arbitrum Sepolia
9558
+ "EVM-84532",
9559
+ // Base Sepolia
9560
+ "EVM-11155420",
9561
+ // Optimism Sepolia
9562
+ "EVM-80002",
9563
+ // Polygon Amoy
9564
+ "EVM-420420417",
9565
+ // Polkadot Asset Hub Paseo
9566
+ "EVM-3448148188",
9567
+ // Tron Nile
9568
+ "EVM-688689"
9569
+ // Pharos Atlantic
9570
+ ]);
9543
9571
  function collectCallInputsByAddress(call, targetContractAddress, acc) {
9544
9572
  const normalizedTarget = targetContractAddress.toLowerCase();
9545
9573
  if (call.calls && Array.isArray(call.calls)) {
@@ -9854,6 +9882,48 @@ var GetRequestClient = class {
9854
9882
  async buildFinalized(request, hyperbridgeDelivered, response) {
9855
9883
  const sourceChain = this.ctx.config.source;
9856
9884
  const hyperbridge = this.ctx.config.hyperbridge;
9885
+ const { config } = hyperbridge;
9886
+ const finality = await this.queries.queryStateMachineUpdateByHeight({
9887
+ statemachineId: config.stateMachineId,
9888
+ height: hyperbridgeDelivered.metadata.blockNumber,
9889
+ chain: config.stateMachineId
9890
+ });
9891
+ if (finality) {
9892
+ const proof = await hyperbridge.queryProof(
9893
+ { Responses: [response.commitment] },
9894
+ request.source,
9895
+ BigInt(finality.height)
9896
+ );
9897
+ const calldata = sourceChain.encode({
9898
+ kind: "GetResponse",
9899
+ proof: {
9900
+ stateMachine: config.stateMachineId,
9901
+ consensusStateId: config.consensusStateId,
9902
+ proof,
9903
+ height: BigInt(finality.height)
9904
+ },
9905
+ responses: [
9906
+ {
9907
+ get: request,
9908
+ values: request.keys.map((key, index) => ({
9909
+ key,
9910
+ value: response.values[index] || "0x"
9911
+ }))
9912
+ }
9913
+ ],
9914
+ signer: pad("0x")
9915
+ });
9916
+ return {
9917
+ status: RequestStatus.HYPERBRIDGE_FINALIZED,
9918
+ metadata: {
9919
+ blockHash: finality.blockHash,
9920
+ blockNumber: finality.height,
9921
+ transactionHash: finality.transactionHash,
9922
+ timestamp: finality.timestamp,
9923
+ calldata
9924
+ }
9925
+ };
9926
+ }
9857
9927
  if (sourceChain instanceof EvmChain) {
9858
9928
  const hyperbridgeSubstrate = hyperbridge;
9859
9929
  const currentEpoch = await sourceChain.currentEpoch();
@@ -9862,18 +9932,18 @@ var GetRequestClient = class {
9862
9932
  currentEpoch
9863
9933
  );
9864
9934
  if (!consensusResult) return void 0;
9865
- const proof2 = await hyperbridge.queryProof(
9935
+ const proof = await hyperbridge.queryProof(
9866
9936
  { Responses: [response.commitment] },
9867
9937
  request.source,
9868
9938
  consensusResult.provenHeight
9869
9939
  );
9870
- const calldata2 = sourceChain.encode({
9940
+ const calldata = sourceChain.encode({
9871
9941
  kind: "BatchConsensusAndGetResponse",
9872
9942
  consensusProofs: consensusResult.proofs,
9873
9943
  proof: {
9874
- stateMachine: this.ctx.config.hyperbridge.config.stateMachineId,
9875
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
9876
- proof: proof2,
9944
+ stateMachine: config.stateMachineId,
9945
+ consensusStateId: config.consensusStateId,
9946
+ proof,
9877
9947
  height: consensusResult.provenHeight
9878
9948
  },
9879
9949
  responses: [
@@ -9895,50 +9965,11 @@ var GetRequestClient = class {
9895
9965
  transactionHash: hyperbridgeDelivered.metadata.transactionHash,
9896
9966
  // @ts-ignore
9897
9967
  timestamp: hyperbridgeDelivered.metadata.timestamp,
9898
- calldata: calldata2
9968
+ calldata
9899
9969
  }
9900
9970
  };
9901
9971
  }
9902
- const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
9903
- statemachineId: this.ctx.config.hyperbridge.config.stateMachineId,
9904
- height: hyperbridgeDelivered.metadata.blockNumber,
9905
- chain: request.source
9906
- });
9907
- if (!hyperbridgeFinality) return void 0;
9908
- const proof = await hyperbridge.queryProof(
9909
- { Responses: [response.commitment] },
9910
- request.source,
9911
- BigInt(hyperbridgeFinality.height)
9912
- );
9913
- const calldata = sourceChain.encode({
9914
- kind: "GetResponse",
9915
- proof: {
9916
- stateMachine: this.ctx.config.hyperbridge.config.stateMachineId,
9917
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
9918
- proof,
9919
- height: BigInt(hyperbridgeFinality.height)
9920
- },
9921
- responses: [
9922
- {
9923
- get: request,
9924
- values: request.keys.map((key, index) => ({
9925
- key,
9926
- value: response.values[index] || "0x"
9927
- }))
9928
- }
9929
- ],
9930
- signer: pad("0x")
9931
- });
9932
- return {
9933
- status: RequestStatus.HYPERBRIDGE_FINALIZED,
9934
- metadata: {
9935
- blockHash: hyperbridgeFinality.blockHash,
9936
- blockNumber: hyperbridgeFinality.height,
9937
- transactionHash: hyperbridgeFinality.transactionHash,
9938
- timestamp: hyperbridgeFinality.timestamp,
9939
- calldata
9940
- }
9941
- };
9972
+ return void 0;
9942
9973
  }
9943
9974
  /**
9944
9975
  * Streaming helper: waits (via `waitOrAbort`) for the consensus proof or
@@ -9953,7 +9984,12 @@ var GetRequestClient = class {
9953
9984
  const hyperbridge = this.ctx.config.hyperbridge;
9954
9985
  const stateMachineId = this.ctx.config.hyperbridge.config.stateMachineId;
9955
9986
  const neededHeight = BigInt(request.statuses[hyperbridgeDeliveredIndex].metadata.blockNumber);
9956
- if (sourceChain instanceof EvmChain) {
9987
+ let finality = await this.queries.queryStateMachineUpdateByHeight({
9988
+ statemachineId: stateMachineId,
9989
+ height: Number(neededHeight),
9990
+ chain: stateMachineId
9991
+ });
9992
+ if (!finality && sourceChain instanceof EvmChain) {
9957
9993
  const hyperbridgeSubstrate = hyperbridge;
9958
9994
  const currentEpoch = await sourceChain.currentEpoch();
9959
9995
  const consensusResult = await waitOrAbort(this.ctx, {
@@ -9997,18 +10033,20 @@ var GetRequestClient = class {
9997
10033
  }
9998
10034
  };
9999
10035
  }
10000
- const hyperbridgeFinalized = await waitOrAbort(this.ctx, {
10001
- signal,
10002
- promise: () => this.queries.queryStateMachineUpdateByHeight({
10003
- statemachineId: stateMachineId,
10004
- height: Number(neededHeight),
10005
- chain: request.source
10006
- })
10007
- });
10036
+ if (!finality) {
10037
+ finality = await waitOrAbort(this.ctx, {
10038
+ signal,
10039
+ promise: () => this.queries.queryStateMachineUpdateByHeight({
10040
+ statemachineId: stateMachineId,
10041
+ height: Number(neededHeight),
10042
+ chain: stateMachineId
10043
+ })
10044
+ });
10045
+ }
10008
10046
  const proof = await hyperbridge.queryProof(
10009
10047
  { Responses: [response?.commitment] },
10010
10048
  request.source,
10011
- BigInt(hyperbridgeFinalized.height)
10049
+ BigInt(finality.height)
10012
10050
  );
10013
10051
  const calldata = sourceChain.encode({
10014
10052
  kind: "GetResponse",
@@ -10016,7 +10054,7 @@ var GetRequestClient = class {
10016
10054
  stateMachine: stateMachineId,
10017
10055
  consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10018
10056
  proof,
10019
- height: BigInt(hyperbridgeFinalized.height)
10057
+ height: BigInt(finality.height)
10020
10058
  },
10021
10059
  responses: [
10022
10060
  {
@@ -10032,10 +10070,10 @@ var GetRequestClient = class {
10032
10070
  return {
10033
10071
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10034
10072
  metadata: {
10035
- blockHash: hyperbridgeFinalized.blockHash,
10036
- blockNumber: hyperbridgeFinalized.height,
10037
- transactionHash: hyperbridgeFinalized.transactionHash,
10038
- timestamp: hyperbridgeFinalized.timestamp,
10073
+ blockHash: finality.blockHash,
10074
+ blockNumber: finality.height,
10075
+ transactionHash: finality.transactionHash,
10076
+ timestamp: finality.timestamp,
10039
10077
  calldata
10040
10078
  }
10041
10079
  };
@@ -10534,6 +10572,40 @@ var PostRequestClient = class {
10534
10572
  async buildFinalized(request, hyperbridgeDelivered) {
10535
10573
  const destChain = this.ctx.config.dest;
10536
10574
  const hyperbridge = this.ctx.config.hyperbridge;
10575
+ const { config } = hyperbridge;
10576
+ const finality = await this.queries.queryStateMachineUpdateByHeight({
10577
+ statemachineId: config.stateMachineId,
10578
+ height: hyperbridgeDelivered.metadata.blockNumber,
10579
+ chain: config.stateMachineId
10580
+ });
10581
+ if (finality) {
10582
+ const proof = await hyperbridge.queryProof(
10583
+ { Requests: [postRequestCommitment(request).commitment] },
10584
+ request.dest,
10585
+ BigInt(finality.height)
10586
+ );
10587
+ const calldata = destChain.encode({
10588
+ kind: "PostRequest",
10589
+ proof: {
10590
+ stateMachine: config.stateMachineId,
10591
+ consensusStateId: config.consensusStateId,
10592
+ proof,
10593
+ height: BigInt(finality.height)
10594
+ },
10595
+ requests: [request],
10596
+ signer: pad("0x")
10597
+ });
10598
+ return {
10599
+ status: RequestStatus.HYPERBRIDGE_FINALIZED,
10600
+ metadata: {
10601
+ blockHash: finality.blockHash,
10602
+ blockNumber: finality.height,
10603
+ transactionHash: finality.transactionHash,
10604
+ timestamp: finality.timestamp,
10605
+ calldata
10606
+ }
10607
+ };
10608
+ }
10537
10609
  if (destChain instanceof EvmChain) {
10538
10610
  const hyperbridgeSubstrate = hyperbridge;
10539
10611
  const currentEpoch = await destChain.currentEpoch();
@@ -10542,18 +10614,18 @@ var PostRequestClient = class {
10542
10614
  currentEpoch
10543
10615
  );
10544
10616
  if (!consensusResult) return void 0;
10545
- const proof2 = await hyperbridge.queryProof(
10617
+ const proof = await hyperbridge.queryProof(
10546
10618
  { Requests: [postRequestCommitment(request).commitment] },
10547
10619
  request.dest,
10548
10620
  consensusResult.provenHeight
10549
10621
  );
10550
- const calldata2 = destChain.encode({
10622
+ const calldata = destChain.encode({
10551
10623
  kind: "BatchConsensusAndPostRequest",
10552
10624
  consensusProofs: consensusResult.proofs,
10553
10625
  proof: {
10554
- stateMachine: this.ctx.config.hyperbridge.config.stateMachineId,
10555
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10556
- proof: proof2,
10626
+ stateMachine: config.stateMachineId,
10627
+ consensusStateId: config.consensusStateId,
10628
+ proof,
10557
10629
  height: consensusResult.provenHeight
10558
10630
  },
10559
10631
  requests: [request],
@@ -10567,42 +10639,11 @@ var PostRequestClient = class {
10567
10639
  transactionHash: hyperbridgeDelivered.metadata.transactionHash,
10568
10640
  // @ts-ignore
10569
10641
  timestamp: hyperbridgeDelivered.metadata.timestamp,
10570
- calldata: calldata2
10642
+ calldata
10571
10643
  }
10572
10644
  };
10573
10645
  }
10574
- const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
10575
- statemachineId: this.ctx.config.hyperbridge.config.stateMachineId,
10576
- height: hyperbridgeDelivered.metadata.blockNumber,
10577
- chain: request.dest
10578
- });
10579
- if (!hyperbridgeFinality) return void 0;
10580
- const proof = await hyperbridge.queryProof(
10581
- { Requests: [postRequestCommitment(request).commitment] },
10582
- request.dest,
10583
- BigInt(hyperbridgeFinality.height)
10584
- );
10585
- const calldata = destChain.encode({
10586
- kind: "PostRequest",
10587
- proof: {
10588
- stateMachine: this.ctx.config.hyperbridge.config.stateMachineId,
10589
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10590
- proof,
10591
- height: BigInt(hyperbridgeFinality.height)
10592
- },
10593
- requests: [request],
10594
- signer: pad("0x")
10595
- });
10596
- return {
10597
- status: RequestStatus.HYPERBRIDGE_FINALIZED,
10598
- metadata: {
10599
- blockHash: hyperbridgeFinality.blockHash,
10600
- blockNumber: hyperbridgeFinality.height,
10601
- transactionHash: hyperbridgeFinality.transactionHash,
10602
- timestamp: hyperbridgeFinality.timestamp,
10603
- calldata
10604
- }
10605
- };
10646
+ return void 0;
10606
10647
  }
10607
10648
  /**
10608
10649
  * Streaming helper: waits for the consensus proof, fetches the messaging
@@ -10616,14 +10657,19 @@ var PostRequestClient = class {
10616
10657
  const stateMachineId = this.ctx.config.hyperbridge.config.stateMachineId;
10617
10658
  const neededHeight = BigInt(request.statuses[hyperbridgeDeliveredIndex].metadata.blockNumber);
10618
10659
  this.logger.trace(`[streamFinalized] neededHeight=${neededHeight}`);
10619
- if (destChain instanceof EvmChain) {
10660
+ const commitment = postRequestCommitment(request).commitment;
10661
+ let finality = await this.queries.queryStateMachineUpdateByHeight({
10662
+ statemachineId: stateMachineId,
10663
+ height: Number(neededHeight),
10664
+ chain: stateMachineId
10665
+ });
10666
+ if (!finality && destChain instanceof EvmChain) {
10620
10667
  const hyperbridgeSubstrate = hyperbridge;
10621
10668
  const currentEpoch = await destChain.currentEpoch();
10622
10669
  const consensusResult = await waitOrAbort(this.ctx, {
10623
10670
  signal,
10624
10671
  promise: () => hyperbridgeSubstrate.queryConsensusProofs(neededHeight, currentEpoch)
10625
10672
  });
10626
- const commitment = postRequestCommitment(request).commitment;
10627
10673
  this.logger.trace(
10628
10674
  `[streamFinalized] consensusProofs found (${consensusResult.proofs.length} proofs), provenHeight=${consensusResult.provenHeight}, commitment=${commitment}, dest=${request.dest}`
10629
10675
  );
@@ -10655,45 +10701,45 @@ var PostRequestClient = class {
10655
10701
  }
10656
10702
  };
10657
10703
  }
10658
- const hyperbridgeFinalized = await waitOrAbort(this.ctx, {
10659
- signal,
10660
- promise: () => this.queries.queryStateMachineUpdateByHeight({
10661
- statemachineId: stateMachineId,
10662
- height: Number(neededHeight),
10663
- chain: request.dest
10664
- })
10665
- });
10704
+ if (!finality) {
10705
+ finality = await waitOrAbort(this.ctx, {
10706
+ signal,
10707
+ promise: () => this.queries.queryStateMachineUpdateByHeight({
10708
+ statemachineId: stateMachineId,
10709
+ height: Number(neededHeight),
10710
+ chain: stateMachineId
10711
+ })
10712
+ });
10713
+ }
10666
10714
  const proof = await this.fetchProofWithRetry(
10667
10715
  signal,
10668
- () => hyperbridge.queryProof(
10669
- { Requests: [postRequestCommitment(request).commitment] },
10670
- request.dest,
10671
- BigInt(hyperbridgeFinalized.height)
10672
- )
10716
+ () => hyperbridge.queryProof({ Requests: [commitment] }, request.dest, BigInt(finality.height))
10673
10717
  );
10718
+ if (!(destChain instanceof EvmChain)) {
10719
+ const { stateId } = parseStateMachineId(stateMachineId);
10720
+ await waitForChallengePeriod(destChain, {
10721
+ height: BigInt(finality.height),
10722
+ id: { stateId, consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId }
10723
+ });
10724
+ }
10674
10725
  const calldata = destChain.encode({
10675
10726
  kind: "PostRequest",
10676
10727
  proof: {
10677
10728
  stateMachine: stateMachineId,
10678
10729
  consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10679
10730
  proof,
10680
- height: BigInt(hyperbridgeFinalized.height)
10731
+ height: BigInt(finality.height)
10681
10732
  },
10682
10733
  requests: [request],
10683
10734
  signer: pad("0x")
10684
10735
  });
10685
- const { stateId } = parseStateMachineId(stateMachineId);
10686
- await waitForChallengePeriod(destChain, {
10687
- height: BigInt(hyperbridgeFinalized.height),
10688
- id: { stateId, consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId }
10689
- });
10690
10736
  return {
10691
10737
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10692
10738
  metadata: {
10693
- blockHash: hyperbridgeFinalized.blockHash,
10694
- blockNumber: hyperbridgeFinalized.height,
10695
- transactionHash: hyperbridgeFinalized.transactionHash,
10696
- timestamp: hyperbridgeFinalized.timestamp,
10739
+ blockHash: finality.blockHash,
10740
+ blockNumber: finality.height,
10741
+ transactionHash: finality.transactionHash,
10742
+ timestamp: finality.timestamp,
10697
10743
  calldata
10698
10744
  }
10699
10745
  };
@@ -14616,6 +14662,7 @@ function orderCommitment(order) {
14616
14662
  return keccak256(encoded);
14617
14663
  }
14618
14664
  async function convertGasToFeeToken(ctx, gasEstimate, gasEstimateIn, evmChainID, gasPriceOverride) {
14665
+ if (TESTNET_CHAINS.has(evmChainID)) return 1n;
14619
14666
  const chain = ctx[gasEstimateIn];
14620
14667
  const client = chain.client;
14621
14668
  const gasPrice = gasPriceOverride ?? await retryPromise(() => client.getGasPrice(), {
@@ -14650,6 +14697,7 @@ async function convertGasToFeeToken(ctx, gasEstimate, gasEstimateIn, evmChainID,
14650
14697
  }
14651
14698
  }
14652
14699
  async function convertFeeTokenToWei(ctx, feeTokenAmount, feeTokenIn, evmChainID) {
14700
+ if (TESTNET_CHAINS.has(evmChainID)) return 1n;
14653
14701
  const chain = ctx[feeTokenIn];
14654
14702
  const client = chain.client;
14655
14703
  const wethAddr = chain.configService.getWrappedNativeAssetWithDecimals(evmChainID).asset;
@@ -14765,16 +14813,16 @@ var OrderPlacer = class {
14765
14813
  return { order, receipt };
14766
14814
  }
14767
14815
  };
14816
+
14817
+ // src/protocols/intents/OrderExecutor.ts
14768
14818
  var USED_USEROPS_STORAGE_KEY = (commitment) => `used-userops:${commitment.toLowerCase()}`;
14769
14819
  var OrderExecutor = class {
14770
- constructor(ctx, bidManager, crypto) {
14820
+ constructor(ctx, bidManager) {
14771
14821
  this.ctx = ctx;
14772
14822
  this.bidManager = bidManager;
14773
- this.crypto = crypto;
14774
14823
  }
14775
14824
  ctx;
14776
14825
  bidManager;
14777
- crypto;
14778
14826
  /**
14779
14827
  * Sleeps until the order's block deadline is reached, then yields EXPIRED.
14780
14828
  * Uses the chain's block time to calculate the sleep duration.
@@ -14845,17 +14893,6 @@ var OrderExecutor = class {
14845
14893
  }
14846
14894
  return fetchedBids;
14847
14895
  }
14848
- /**
14849
- * Selects the best bid from the provided candidates, submits the
14850
- * UserOperation, and persists the dedup entry to prevent resubmission.
14851
- */
14852
- async submitBid(params) {
14853
- const { order, freshBids, sessionPrivateKey, commitment, usedUserOps, userOpHashKey } = params;
14854
- const result = await this.bidManager.selectBid(order, freshBids, sessionPrivateKey);
14855
- usedUserOps.add(userOpHashKey(result.userOp));
14856
- await this.persistUsedUserOps(commitment, usedUserOps);
14857
- return result;
14858
- }
14859
14896
  /**
14860
14897
  * Processes a fill result and returns updated fill accumulators,
14861
14898
  * the status update to yield (if any), and whether the order is
@@ -14923,7 +14960,15 @@ var OrderExecutor = class {
14923
14960
  }
14924
14961
  /**
14925
14962
  * Executes an intent order by racing bid polling against the order's
14926
- * block deadline. Yields status updates at each lifecycle stage.
14963
+ * block deadline. Yields status updates at each lifecycle stage and hands
14964
+ * bid selection to the consumer.
14965
+ *
14966
+ * This is a **bidirectional** generator: when it yields `BIDS_RECEIVED`, the
14967
+ * consumer picks a bid, calls `bid.execute()`, and feeds the resulting
14968
+ * {@link SelectBidResult} back via `gen.next(result)`. The generator then
14969
+ * records the dedup entry, emits `BID_SELECTED`, tracks the fill, and either
14970
+ * terminates or continues polling for the remaining amount. Feeding back
14971
+ * `undefined` (no bid executed this round) causes it to keep polling.
14927
14972
  *
14928
14973
  * **Same-chain:** `AWAITING_BIDS` → `BIDS_RECEIVED` → `BID_SELECTED`
14929
14974
  * → (`FILLED` | `PARTIAL_FILL`)* → (`FILLED` | `EXPIRED`)
@@ -14934,7 +14979,6 @@ var OrderExecutor = class {
14934
14979
  async *executeOrder(options) {
14935
14980
  const { order, sessionPrivateKey, auctionTimeMs, pollIntervalMs = DEFAULT_POLL_INTERVAL, solver } = options;
14936
14981
  const commitment = order.id;
14937
- order.source === order.destination;
14938
14982
  if (!this.ctx.intentsCoprocessor) {
14939
14983
  yield { status: "FAILED", error: "IntentsCoprocessor required for order execution" };
14940
14984
  return;
@@ -14962,11 +15006,24 @@ var OrderExecutor = class {
14962
15006
  remainingAssets
14963
15007
  });
14964
15008
  const deadlineTimeout = this.deadlineStream(order.deadline, commitment);
14965
- const combined = mergeRace(deadlineTimeout, executionStream);
15009
+ const deadlinePromise = deadlineTimeout.next();
14966
15010
  try {
14967
- for await (const update of combined) {
14968
- yield update;
14969
- if (update.status === "EXPIRED" || update.status === "FILLED") return;
15011
+ let input;
15012
+ while (true) {
15013
+ const winner = input !== void 0 ? { from: "exec", r: await executionStream.next(input) } : await Promise.race([
15014
+ executionStream.next(void 0).then((r) => ({ from: "exec", r })),
15015
+ deadlinePromise.then((r) => ({ from: "deadline", r }))
15016
+ ]);
15017
+ input = void 0;
15018
+ if (winner.from === "deadline") {
15019
+ if (!winner.r.done && winner.r.value) yield winner.r.value;
15020
+ return;
15021
+ }
15022
+ const { value, done } = winner.r;
15023
+ if (done) return;
15024
+ const fed = yield value;
15025
+ if (value.status === "BIDS_RECEIVED") input = fed;
15026
+ if (value.status === "EXPIRED" || value.status === "FILLED") return;
14970
15027
  }
14971
15028
  } finally {
14972
15029
  console.log(`[OrderExecutor] Tearing down streams for commitment=${commitment}`);
@@ -14975,9 +15032,16 @@ var OrderExecutor = class {
14975
15032
  }
14976
15033
  }
14977
15034
  /**
14978
- * Core execution loop that polls for bids, submits UserOperations,
14979
- * and tracks fill progress. Yields between each poll iteration so
14980
- * that `mergeRace` can interleave the deadline stream.
15035
+ * Core execution loop that polls for bids and tracks fill progress. Builds
15036
+ * first-class {@link Bid} objects from the raw filler bids and yields them to
15037
+ * the consumer, which picks one, calls `bid.execute()`, and feeds the result
15038
+ * back via `gen.next(result)`. The loop then records the dedup entry, emits
15039
+ * `BID_SELECTED`, processes the fill, and continues polling for the remaining
15040
+ * amount on partial fills.
15041
+ *
15042
+ * Bidirectional: the value passed to `.next()` after a `BIDS_RECEIVED` yield is
15043
+ * the {@link SelectBidResult} from the executed bid (or `undefined` to skip the
15044
+ * round and keep polling).
14981
15045
  */
14982
15046
  async *executionStream(params) {
14983
15047
  const {
@@ -14992,12 +15056,7 @@ var OrderExecutor = class {
14992
15056
  targetAssets
14993
15057
  } = params;
14994
15058
  let { totalFilledAssets, remainingAssets } = params;
14995
- const MAX_BID_ATTEMPTS = 2;
14996
- const bidFailCounts = /* @__PURE__ */ new Map();
14997
- const isFreshBid = (bid) => {
14998
- const key = userOpHashKey(bid.userOp);
14999
- return !usedUserOps.has(key) && (bidFailCounts.get(key) ?? 0) < MAX_BID_ATTEMPTS;
15000
- };
15059
+ const isFreshBid = (bid) => !usedUserOps.has(userOpHashKey(bid.userOp));
15001
15060
  const solverLockStartTime = Date.now();
15002
15061
  yield { status: "AWAITING_BIDS", commitment, totalFilledAssets, remainingAssets };
15003
15062
  try {
@@ -15006,13 +15065,13 @@ var OrderExecutor = class {
15006
15065
  while (Date.now() < auctionEnd) {
15007
15066
  try {
15008
15067
  const bids = await this.fetchBids({ commitment, solver, solverLockStartTime });
15009
- const freshBids = bids.filter((bid) => !usedUserOps.has(userOpHashKey(bid.userOp)));
15010
- const newBids = freshBids.filter((bid) => !auctionSeenBids.has(userOpHashKey(bid.userOp)));
15011
- if (newBids.length > 0) {
15012
- for (const bid of newBids) {
15013
- auctionSeenBids.add(userOpHashKey(bid.userOp));
15014
- }
15015
- yield { status: "NEW_BID", commitment, bidCount: freshBids.length, bids: freshBids };
15068
+ const newBids = bids.filter(
15069
+ (bid) => isFreshBid(bid) && !auctionSeenBids.has(userOpHashKey(bid.userOp))
15070
+ );
15071
+ for (const fillerBid of newBids) {
15072
+ auctionSeenBids.add(userOpHashKey(fillerBid.userOp));
15073
+ const [bid] = this.bidManager.buildBids(order, [fillerBid], sessionPrivateKey);
15074
+ if (bid) yield { status: "NEW_BID", commitment, bid };
15016
15075
  }
15017
15076
  } catch {
15018
15077
  }
@@ -15024,8 +15083,8 @@ var OrderExecutor = class {
15024
15083
  while (true) {
15025
15084
  let freshBids;
15026
15085
  try {
15027
- const bids = await this.fetchBids({ commitment, solver, solverLockStartTime });
15028
- freshBids = bids.filter(isFreshBid);
15086
+ const bids2 = await this.fetchBids({ commitment, solver, solverLockStartTime });
15087
+ freshBids = bids2.filter(isFreshBid);
15029
15088
  } catch {
15030
15089
  await sleep(pollIntervalMs);
15031
15090
  continue;
@@ -15034,56 +15093,33 @@ var OrderExecutor = class {
15034
15093
  await sleep(pollIntervalMs);
15035
15094
  continue;
15036
15095
  }
15037
- yield { status: "BIDS_RECEIVED", commitment, bidCount: freshBids.length, bids: freshBids };
15038
- let submitResult;
15039
- try {
15040
- submitResult = await this.submitBid({
15041
- order,
15042
- freshBids,
15043
- sessionPrivateKey,
15044
- commitment,
15045
- usedUserOps,
15046
- userOpHashKey
15047
- });
15048
- } catch (err) {
15049
- yield {
15050
- status: "FAILED",
15051
- commitment,
15052
- totalFilledAssets,
15053
- remainingAssets,
15054
- error: `Failed to select bid and submit: ${err instanceof Error ? err.message : String(err)}`
15055
- };
15056
- try {
15057
- const sorted = await this.bidManager.validateAndSortBids(freshBids, order);
15058
- if (sorted.length > 0) {
15059
- const key = userOpHashKey(sorted[0].bid.userOp);
15060
- bidFailCounts.set(key, (bidFailCounts.get(key) ?? 0) + 1);
15061
- }
15062
- } catch {
15063
- }
15096
+ const bids = this.bidManager.buildBids(order, freshBids, sessionPrivateKey);
15097
+ if (bids.length === 0) {
15098
+ await sleep(pollIntervalMs);
15099
+ continue;
15100
+ }
15101
+ const result = yield { status: "BIDS_RECEIVED", commitment, bidCount: bids.length, bids };
15102
+ if (!result) {
15064
15103
  await sleep(pollIntervalMs);
15065
15104
  continue;
15066
15105
  }
15106
+ usedUserOps.add(userOpHashKey(result.userOp));
15107
+ await this.persistUsedUserOps(commitment, usedUserOps);
15067
15108
  yield {
15068
15109
  status: "BID_SELECTED",
15069
15110
  commitment,
15070
- selectedSolver: submitResult.solverAddress,
15071
- userOpHash: submitResult.userOpHash,
15072
- userOp: submitResult.userOp,
15073
- transactionHash: submitResult.txnHash
15111
+ selectedSolver: result.solverAddress,
15112
+ userOpHash: result.userOpHash,
15113
+ userOp: result.userOp,
15114
+ transactionHash: result.txnHash
15074
15115
  };
15075
- const fill = this.processFillResult(
15076
- submitResult,
15077
- commitment,
15078
- targetAssets,
15079
- totalFilledAssets,
15080
- remainingAssets
15081
- );
15116
+ const fill = this.processFillResult(result, commitment, targetAssets, totalFilledAssets, remainingAssets);
15082
15117
  totalFilledAssets = fill.totalFilledAssets;
15083
15118
  remainingAssets = fill.remainingAssets;
15084
15119
  if (fill.update) {
15085
15120
  yield fill.update;
15086
15121
  }
15122
+ if (fill.done) return;
15087
15123
  }
15088
15124
  } catch (err) {
15089
15125
  yield {
@@ -15558,183 +15594,148 @@ var OrderCanceller = class {
15558
15594
  return feeInDestFeeToken * 1005n / 1000n;
15559
15595
  }
15560
15596
  };
15561
- var BidManager = class {
15562
- /**
15563
- * @param ctx - Shared IntentsV2 context providing the destination chain
15564
- * client, coprocessor, bundler URL, and session-key storage.
15565
- * @param crypto - Crypto utilities used for gas packing, UserOp hashing,
15566
- * EIP-712 signing, and bundler calls.
15567
- */
15568
- constructor(ctx, crypto) {
15569
- this.ctx = ctx;
15570
- this.crypto = crypto;
15571
- }
15597
+ var BidImpl = class {
15598
+ solverAddress;
15599
+ outputs;
15600
+ relayerFee;
15601
+ nativeDispatchFee;
15602
+ userOp;
15572
15603
  ctx;
15573
15604
  crypto;
15574
- /**
15575
- * Constructs a signed `PackedUserOperation` that a solver can submit to the
15576
- * Hyperbridge coprocessor as a bid to fill an order.
15577
- *
15578
- * The solver's signature covers a hash that binds the UserOperation to the
15579
- * order commitment and the session key address, so the IntentGatewayV2
15580
- * contract can verify the solver's intent on-chain.
15581
- *
15582
- * @param options - Parameters describing the solver account, gas limits, fee
15583
- * market values, and pre-built `callData` for the fill operation.
15584
- * @returns A `PackedUserOperation` with the solver's signature prepended
15585
- * with the order commitment.
15586
- */
15587
- async prepareSubmitBid(options) {
15588
- const {
15589
- order,
15590
- solverAccount,
15591
- solverSigner,
15592
- nonce,
15593
- entryPointAddress,
15594
- callGasLimit,
15595
- verificationGasLimit,
15596
- preVerificationGas,
15597
- maxFeePerGas,
15598
- maxPriorityFeePerGas,
15599
- callData,
15600
- paymasterAndData = "0x"
15601
- } = options;
15602
- const chainId = BigInt(
15605
+ order;
15606
+ fillOptions;
15607
+ priceOutputs;
15608
+ sessionPrivateKey;
15609
+ intentGatewayV2Address;
15610
+ domainSeparator;
15611
+ /** Cached session-key signature over the `SelectSolver` message. */
15612
+ cachedSignature;
15613
+ constructor(params) {
15614
+ this.ctx = params.ctx;
15615
+ this.crypto = params.crypto;
15616
+ this.order = params.order;
15617
+ this.fillOptions = params.fillOptions;
15618
+ this.priceOutputs = params.priceOutputs;
15619
+ this.sessionPrivateKey = params.sessionPrivateKey;
15620
+ this.solverAddress = params.fillerBid.userOp.sender;
15621
+ this.outputs = params.fillOptions.outputs;
15622
+ this.relayerFee = params.fillOptions.relayerFee;
15623
+ this.nativeDispatchFee = params.fillOptions.nativeDispatchFee;
15624
+ this.userOp = params.fillerBid.userOp;
15625
+ this.intentGatewayV2Address = this.ctx.dest.configService.getIntentGatewayAddress(
15626
+ normalizeStateMachineId(this.order.destination)
15627
+ );
15628
+ this.domainSeparator = CryptoUtils.getDomainSeparator(
15629
+ "IntentGateway",
15630
+ "2",
15631
+ this.chainId(),
15632
+ this.intentGatewayV2Address
15633
+ );
15634
+ }
15635
+ /** Resolves the destination chain id from the client or the state-machine id. */
15636
+ chainId() {
15637
+ return BigInt(
15603
15638
  this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15604
15639
  );
15605
- const accountGasLimits = CryptoUtils.packGasLimits(verificationGasLimit, callGasLimit);
15606
- const gasFees = CryptoUtils.packGasFees(maxPriorityFeePerGas, maxFeePerGas);
15607
- const userOp = {
15608
- sender: solverAccount,
15609
- nonce,
15610
- initCode: "0x",
15611
- callData,
15612
- accountGasLimits,
15613
- preVerificationGas,
15614
- gasFees,
15615
- paymasterAndData,
15616
- signature: "0x"
15617
- };
15618
- const userOpHash = CryptoUtils.computeUserOpHash(userOp, entryPointAddress, chainId);
15619
- const sessionKey = order.session;
15620
- const messageHash = keccak256(concat([userOpHash, order.id, sessionKey]));
15621
- const solverSignature = await solverSigner.signMessage(messageHash, Number(chainId));
15622
- const signature = concat([order.id, solverSignature]);
15623
- return { ...userOp, signature };
15624
15640
  }
15625
15641
  /**
15626
- * Selects the best available bid, simulates it on-chain, signs the
15627
- * solver-selection EIP-712 message with the session key, and submits the
15628
- * UserOperation to the bundler.
15642
+ * Resolves the session key, signs the `SelectSolver` message for this bid's
15643
+ * solver, and caches the signature. Signs at most once per bid.
15629
15644
  *
15630
- * **Selection algorithm:**
15631
- * 1. Decodes `fillOrder` calldata from each bid's `callData`.
15632
- * 2. Sorts bids by output value (single-output: amount; all-stables: normalised
15633
- * USD; mixed: DEX-quoted USD; fallback: raw amount).
15634
- * 3. Iterates sorted bids, simulating each with `eth_call` until one passes.
15635
- * 4. Appends the session-key's `SelectSolver` signature to the solver's
15636
- * existing signature and submits via `eth_sendUserOperation`.
15637
- * 5. For same-chain orders, waits for the transaction receipt and reads
15638
- * `OrderFilled` / `PartialFill` events to determine fill status.
15639
- *
15640
- * @param order - The placed order for which to select a bid.
15641
- * @param bids - Raw bids fetched from the Hyperbridge coprocessor.
15642
- * @param sessionPrivateKey - Optional override; if omitted, the key is
15643
- * looked up from `sessionKeyStorage` using `order.session`.
15644
- * @returns A {@link SelectBidResult} containing the submitted UserOperation,
15645
- * its hash, the winning solver address, transaction hash, and fill status.
15646
- * @throws If the session key is not found, no valid bids exist, all
15647
- * simulations fail, or the bundler rejects the UserOperation.
15645
+ * @throws If the session key is missing or signing fails.
15648
15646
  */
15649
- async selectBid(order, bids, sessionPrivateKey) {
15650
- const commitment = order.id;
15651
- const sessionKeyAddress = order.session;
15652
- console.log(`[BidManager] selectBid called for commitment=${commitment}, received ${bids.length} bid(s)`);
15653
- const sessionKeyData = sessionPrivateKey ? { privateKey: sessionPrivateKey } : await this.ctx.sessionKeyStorage.getSessionKeyByAddress(sessionKeyAddress);
15647
+ async signSelection() {
15648
+ if (this.cachedSignature) return this.cachedSignature;
15649
+ const commitment = this.order.id;
15650
+ const sessionKeyAddress = this.order.session;
15651
+ const sessionKeyData = this.sessionPrivateKey ? { privateKey: this.sessionPrivateKey } : await this.ctx.sessionKeyStorage.getSessionKeyByAddress(sessionKeyAddress);
15654
15652
  if (!sessionKeyData) {
15655
15653
  throw new Error("SessionKey not found for commitment: " + commitment);
15656
15654
  }
15657
- if (!this.ctx.bundlerUrl) {
15658
- throw new Error("Bundler URL not configured");
15659
- }
15660
- if (!this.ctx.intentsCoprocessor) {
15661
- throw new Error("IntentsCoprocessor required");
15662
- }
15663
- const sortedBids = await this.validateAndSortBids(bids, order);
15664
- console.log(`[BidManager] ${sortedBids.length}/${bids.length} bid(s) passed validation and sorting`);
15665
- if (sortedBids.length === 0) {
15666
- throw new Error("No valid bids found");
15667
- }
15668
- const intentGatewayV2Address = this.ctx.dest.configService.getIntentGatewayAddress(
15669
- normalizeStateMachineId(order.destination)
15670
- );
15671
- const domainSeparator = CryptoUtils.getDomainSeparator(
15672
- "IntentGateway",
15673
- "2",
15674
- BigInt(
15675
- this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15676
- ),
15677
- intentGatewayV2Address
15655
+ const signature = await CryptoUtils.signSolverSelection(
15656
+ commitment,
15657
+ this.solverAddress,
15658
+ this.domainSeparator,
15659
+ sessionKeyData.privateKey
15678
15660
  );
15679
- let selectedBid = null;
15680
- let sessionSignature = null;
15681
- console.log(`[BidManager] Simulating ${sortedBids.length} sorted bid(s) to find a valid one`);
15682
- for (let idx = 0; idx < sortedBids.length; idx++) {
15683
- const bidWithOptions = sortedBids[idx];
15684
- const solverAddress2 = bidWithOptions.bid.userOp.sender;
15685
- console.log(`[BidManager] Simulating bid ${idx + 1}/${sortedBids.length} from solver=${solverAddress2}`);
15686
- const signature = await CryptoUtils.signSolverSelection(
15687
- commitment,
15688
- solverAddress2,
15689
- domainSeparator,
15690
- sessionKeyData.privateKey
15691
- );
15692
- if (!signature) {
15693
- console.warn(`[BidManager] Bid ${idx + 1}: failed to sign solver selection, skipping`);
15694
- continue;
15695
- }
15696
- const selectOptions = {
15697
- commitment,
15698
- solver: solverAddress2,
15699
- signature
15700
- };
15701
- try {
15702
- await this.simulate(bidWithOptions.bid, bidWithOptions.options, selectOptions, intentGatewayV2Address);
15703
- console.log(`[BidManager] Bid ${idx + 1} from solver=${solverAddress2}: simulation PASSED`);
15704
- selectedBid = bidWithOptions;
15705
- sessionSignature = signature;
15706
- break;
15707
- } catch (err) {
15708
- console.warn(
15709
- `[BidManager] Bid ${idx + 1} from solver=${solverAddress2}: simulation FAILED: ${err instanceof Error ? err.message : String(err)}`
15710
- );
15711
- continue;
15712
- }
15661
+ if (!signature) {
15662
+ throw new Error("Failed to sign solver selection");
15713
15663
  }
15714
- if (!selectedBid || !sessionSignature) {
15715
- console.error(`[BidManager] All ${sortedBids.length} bid(s) failed simulation for commitment=${commitment}`);
15716
- throw new Error("No bids passed simulation");
15664
+ this.cachedSignature = signature;
15665
+ return signature;
15666
+ }
15667
+ /**
15668
+ * Simulates this bid on-chain by batching the `select` and `fillOrder` calls
15669
+ * via `eth_call` from the solver's account, using the IntentGatewayV2 ERC-7821
15670
+ * batch-execute pattern.
15671
+ *
15672
+ * The native value forwarded to the simulation is the sum of any native-token
15673
+ * (`address(0)`) output amounts plus the Hyperbridge dispatch fee.
15674
+ *
15675
+ * @throws If the `eth_call` simulation reverts or errors.
15676
+ */
15677
+ async simulate() {
15678
+ const signature = await this.signSelection();
15679
+ const selectOptions = {
15680
+ commitment: this.order.id,
15681
+ solver: this.solverAddress,
15682
+ signature
15683
+ };
15684
+ const nativeOutputs = this.fillOptions.outputs.reduce(
15685
+ (acc, o) => bytes32ToBytes20(o.token) === ADDRESS_ZERO2 ? acc + o.amount : acc,
15686
+ 0n
15687
+ );
15688
+ const simulationValue = nativeOutputs + this.fillOptions.nativeDispatchFee;
15689
+ const selectCalldata = encodeFunctionData({
15690
+ abi: ABI3,
15691
+ functionName: "select",
15692
+ args: [selectOptions]
15693
+ });
15694
+ const calls = [
15695
+ { target: this.intentGatewayV2Address, value: 0n, data: selectCalldata },
15696
+ { target: this.solverAddress, value: simulationValue, data: this.userOp.callData }
15697
+ ];
15698
+ const batchedCalldata = this.crypto.encodeERC7821Execute(calls);
15699
+ try {
15700
+ await this.ctx.dest.client.call({
15701
+ account: this.solverAddress,
15702
+ to: this.solverAddress,
15703
+ data: batchedCalldata,
15704
+ value: simulationValue
15705
+ });
15706
+ } catch (e) {
15707
+ throw new Error(`Simulation failed: ${e instanceof Error ? e.message : String(e)}`);
15717
15708
  }
15718
- const solverAddress = selectedBid.bid.userOp.sender;
15719
- const finalSignature = concat([
15720
- selectedBid.bid.userOp.signature,
15721
- sessionSignature
15722
- ]);
15709
+ }
15710
+ /**
15711
+ * Signs the `SelectSolver` message with the session key, appends it to the
15712
+ * solver's existing UserOp signature, and submits the UserOperation to the
15713
+ * bundler. For same-chain orders, waits for the receipt and reads
15714
+ * `OrderFilled` / `PartialFill` logs to determine fill status.
15715
+ *
15716
+ * @returns A {@link SelectBidResult} with the submitted UserOperation, its hash,
15717
+ * the solver address, transaction hash, and fill status.
15718
+ * @throws If the bundler is not configured, the session key is missing, or the
15719
+ * bundler rejects the UserOperation.
15720
+ */
15721
+ async execute() {
15722
+ const commitment = this.order.id;
15723
+ if (!this.ctx.bundlerUrl) {
15724
+ throw new Error("Bundler URL not configured");
15725
+ }
15726
+ const sessionSignature = await this.signSelection();
15727
+ const finalSignature = concat([this.userOp.signature, sessionSignature]);
15723
15728
  const signedUserOp = {
15724
- ...selectedBid.bid.userOp,
15729
+ ...this.userOp,
15725
15730
  signature: finalSignature
15726
15731
  };
15727
15732
  const entryPointAddress = this.ctx.dest.configService.getEntryPointV08Address(
15728
- normalizeStateMachineId(order.destination)
15733
+ normalizeStateMachineId(this.order.destination)
15729
15734
  );
15730
- BigInt(
15731
- this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15732
- );
15733
- const bundlerResult = await this.crypto.sendBundler(BundlerMethod.ETH_SEND_USER_OPERATION, [
15735
+ const userOpHash = await this.crypto.sendBundler(BundlerMethod.ETH_SEND_USER_OPERATION, [
15734
15736
  CryptoUtils.prepareBundlerCall(signedUserOp),
15735
15737
  entryPointAddress
15736
15738
  ]);
15737
- const userOpHash = bundlerResult;
15738
15739
  let txnHash;
15739
15740
  let fillStatus;
15740
15741
  let filledAssets;
@@ -15750,7 +15751,7 @@ var BidManager = class {
15750
15751
  { maxRetries: 5, backoffMs: 2e3, logMessage: "Fetching user operation receipt" }
15751
15752
  );
15752
15753
  txnHash = receipt.receipt.transactionHash;
15753
- if (order.source === order.destination) {
15754
+ if (this.order.source === this.order.destination) {
15754
15755
  try {
15755
15756
  const chainReceipt = await this.ctx.dest.client.waitForTransactionReceipt({
15756
15757
  hash: txnHash,
@@ -15779,12 +15780,12 @@ var BidManager = class {
15779
15780
  }
15780
15781
  }
15781
15782
  } catch (err) {
15782
- throw new Error(`Failed to select bid: ${err instanceof Error ? err.message : String(err)}`);
15783
+ throw new Error(`Failed to execute bid: ${err instanceof Error ? err.message : String(err)}`);
15783
15784
  }
15784
15785
  return {
15785
15786
  userOp: signedUserOp,
15786
15787
  userOpHash,
15787
- solverAddress,
15788
+ solverAddress: this.solverAddress,
15788
15789
  commitment,
15789
15790
  txnHash,
15790
15791
  fillStatus,
@@ -15792,7 +15793,177 @@ var BidManager = class {
15792
15793
  };
15793
15794
  }
15794
15795
  /**
15795
- * Validates and sorts a list of raw bids for the given order.
15796
+ * Prices this bid's outputs in USD using the destination chain's DEX-quote
15797
+ * helpers. Returns `null` when any output token cannot be priced.
15798
+ */
15799
+ async outputUsdValue() {
15800
+ return this.priceOutputs(this.outputs);
15801
+ }
15802
+ };
15803
+ var BidManager = class {
15804
+ /**
15805
+ * @param ctx - Shared IntentsV2 context providing the destination chain
15806
+ * client, coprocessor, bundler URL, and session-key storage.
15807
+ * @param crypto - Crypto utilities used for gas packing, UserOp hashing,
15808
+ * EIP-712 signing, and bundler calls.
15809
+ */
15810
+ constructor(ctx, crypto) {
15811
+ this.ctx = ctx;
15812
+ this.crypto = crypto;
15813
+ }
15814
+ ctx;
15815
+ crypto;
15816
+ /**
15817
+ * Constructs a signed `PackedUserOperation` that a solver can submit to the
15818
+ * Hyperbridge coprocessor as a bid to fill an order.
15819
+ *
15820
+ * The solver's signature covers a hash that binds the UserOperation to the
15821
+ * order commitment and the session key address, so the IntentGatewayV2
15822
+ * contract can verify the solver's intent on-chain.
15823
+ *
15824
+ * @param options - Parameters describing the solver account, gas limits, fee
15825
+ * market values, and pre-built `callData` for the fill operation.
15826
+ * @returns A `PackedUserOperation` with the solver's signature prepended
15827
+ * with the order commitment.
15828
+ */
15829
+ async prepareSubmitBid(options) {
15830
+ const {
15831
+ order,
15832
+ solverAccount,
15833
+ solverSigner,
15834
+ nonce,
15835
+ entryPointAddress,
15836
+ callGasLimit,
15837
+ verificationGasLimit,
15838
+ preVerificationGas,
15839
+ maxFeePerGas,
15840
+ maxPriorityFeePerGas,
15841
+ callData,
15842
+ paymasterAndData = "0x"
15843
+ } = options;
15844
+ const chainId = BigInt(
15845
+ this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15846
+ );
15847
+ const accountGasLimits = CryptoUtils.packGasLimits(verificationGasLimit, callGasLimit);
15848
+ const gasFees = CryptoUtils.packGasFees(maxPriorityFeePerGas, maxFeePerGas);
15849
+ const userOp = {
15850
+ sender: solverAccount,
15851
+ nonce,
15852
+ initCode: "0x",
15853
+ callData,
15854
+ accountGasLimits,
15855
+ preVerificationGas,
15856
+ gasFees,
15857
+ paymasterAndData,
15858
+ signature: "0x"
15859
+ };
15860
+ const userOpHash = CryptoUtils.computeUserOpHash(userOp, entryPointAddress, chainId);
15861
+ const sessionKey = order.session;
15862
+ const messageHash = keccak256(concat([userOpHash, order.id, sessionKey]));
15863
+ const solverSignature = await solverSigner.signMessage(messageHash, Number(chainId));
15864
+ const signature = concat([order.id, solverSignature]);
15865
+ return { ...userOp, signature };
15866
+ }
15867
+ /**
15868
+ * Decodes raw filler bids into first-class {@link Bid} objects.
15869
+ *
15870
+ * Each bid's `fillOrder` fill-options are decoded from its ERC-7821 calldata;
15871
+ * bids whose calldata cannot be decoded into a valid `fillOrder` call are
15872
+ * silently dropped with a warning. The returned `Bid` instances are ready to
15873
+ * be ranked, simulated, and executed by the consumer.
15874
+ *
15875
+ * @param order - The placed order the bids are competing to fill.
15876
+ * @param bids - Raw filler bids fetched from the coprocessor.
15877
+ * @param sessionPrivateKey - Optional session-key override; looked up from
15878
+ * storage by `order.session` if omitted.
15879
+ * @returns Array of executable `Bid` objects (one per successfully decoded bid).
15880
+ */
15881
+ buildBids(order, bids, sessionPrivateKey) {
15882
+ const chainId = this.ctx.dest.config.stateMachineId;
15883
+ const priceOutputs = (outputs) => this.computeOutputsUsdValue(outputs, chainId);
15884
+ const result = [];
15885
+ for (const fillerBid of bids) {
15886
+ const fillOptions = this.decodeBidFillOptions(fillerBid);
15887
+ if (!fillOptions) {
15888
+ console.warn(`[BidManager] Failed to decode fillOptions from bid by solver=${fillerBid.userOp.sender}`);
15889
+ continue;
15890
+ }
15891
+ result.push(
15892
+ new BidImpl({
15893
+ ctx: this.ctx,
15894
+ crypto: this.crypto,
15895
+ order,
15896
+ fillerBid,
15897
+ fillOptions,
15898
+ priceOutputs,
15899
+ sessionPrivateKey
15900
+ })
15901
+ );
15902
+ }
15903
+ console.log(`[BidManager] Built ${result.length}/${bids.length} bid(s) successfully`);
15904
+ return result;
15905
+ }
15906
+ /**
15907
+ * Decodes raw filler bids, sorts them, simulates each until one passes, signs
15908
+ * the `SelectSolver` message, and submits — all with no per-bid input from the
15909
+ * caller.
15910
+ *
15911
+ * Equivalent to `selectAndExecuteBest(order, buildBids(order, bids, key))`.
15912
+ *
15913
+ * @param order - The placed order to fill.
15914
+ * @param bids - Raw filler bids fetched from the coprocessor.
15915
+ * @param sessionPrivateKey - Optional session-key override; looked up from
15916
+ * storage by `order.session` if omitted.
15917
+ * @returns A {@link SelectBidResult} for the executed bid.
15918
+ */
15919
+ async selectBid(order, bids, sessionPrivateKey) {
15920
+ return this.selectAndExecuteBest(order, this.buildBids(order, bids, sessionPrivateKey));
15921
+ }
15922
+ /**
15923
+ * Autopilot bid selection: sorts the given bids by output value, simulates
15924
+ * each in order until one passes, then executes that bid. For consumers that
15925
+ * do not need custom selection logic.
15926
+ *
15927
+ * @param order - The placed order to fill.
15928
+ * @param bids - Candidate bids (from {@link buildBids}).
15929
+ * @returns A {@link SelectBidResult} for the executed bid.
15930
+ * @throws If no valid bids exist, all simulations fail, or the bundler rejects
15931
+ * the UserOperation.
15932
+ */
15933
+ async selectAndExecuteBest(order, bids) {
15934
+ const commitment = order.id;
15935
+ console.log(`[BidManager] selectAndExecuteBest called for commitment=${commitment}, ${bids.length} bid(s)`);
15936
+ if (!this.ctx.bundlerUrl) {
15937
+ throw new Error("Bundler URL not configured");
15938
+ }
15939
+ if (!this.ctx.intentsCoprocessor) {
15940
+ throw new Error("IntentsCoprocessor required");
15941
+ }
15942
+ const sortedBids = await this.sortBids(order, bids);
15943
+ console.log(`[BidManager] ${sortedBids.length}/${bids.length} bid(s) passed validation and sorting`);
15944
+ if (sortedBids.length === 0) {
15945
+ throw new Error("No valid bids found");
15946
+ }
15947
+ console.log(`[BidManager] Simulating ${sortedBids.length} sorted bid(s) to find a valid one`);
15948
+ for (let idx = 0; idx < sortedBids.length; idx++) {
15949
+ const bid = sortedBids[idx];
15950
+ console.log(`[BidManager] Simulating bid ${idx + 1}/${sortedBids.length} from solver=${bid.solverAddress}`);
15951
+ try {
15952
+ await bid.simulate();
15953
+ } catch (err) {
15954
+ console.warn(
15955
+ `[BidManager] Bid ${idx + 1} from solver=${bid.solverAddress}: simulation FAILED: ${err instanceof Error ? err.message : String(err)}`
15956
+ );
15957
+ continue;
15958
+ }
15959
+ console.log(`[BidManager] Bid ${idx + 1} from solver=${bid.solverAddress}: simulation PASSED`);
15960
+ return bid.execute();
15961
+ }
15962
+ console.error(`[BidManager] All ${sortedBids.length} bid(s) failed simulation for commitment=${commitment}`);
15963
+ throw new Error("No bids passed simulation");
15964
+ }
15965
+ /**
15966
+ * Sorts a list of bids for the given order by output value.
15796
15967
  *
15797
15968
  * Delegates to one of three strategies based on the order's output token
15798
15969
  * composition:
@@ -15801,47 +15972,26 @@ var BidManager = class {
15801
15972
  * - Mixed outputs: sort by DEX-quoted USD value descending, with a raw-amount
15802
15973
  * fallback if pricing fails.
15803
15974
  *
15804
- * @param bids - Raw filler bids from the coprocessor.
15975
+ * Bids that cannot satisfy the order's token set are dropped.
15976
+ *
15805
15977
  * @param order - The placed order whose output spec drives sorting logic.
15806
- * @returns Sorted array of `{ bid, options }` pairs ready for simulation.
15978
+ * @param bids - Executable bids to sort (from {@link buildBids}).
15979
+ * @returns Sorted array of `Bid` objects ready for simulation.
15807
15980
  */
15808
- async validateAndSortBids(bids, order) {
15981
+ async sortBids(order, bids) {
15809
15982
  const outputs = order.output.assets;
15810
- const decodedBids = this.decodeBids(bids);
15811
15983
  if (outputs.length <= 1) {
15812
15984
  console.log(`[BidManager] Using single-output sorting (1 output asset)`);
15813
- return this.sortSingleOutput(decodedBids, outputs[0]);
15985
+ return this.sortSingleOutput(bids, outputs[0]);
15814
15986
  }
15815
15987
  const chainId = this.ctx.dest.config.stateMachineId;
15816
15988
  const allStables = outputs.every((o) => this.isStableToken(bytes32ToBytes20(o.token), chainId));
15817
15989
  if (allStables) {
15818
15990
  console.log(`[BidManager] Using all-stables sorting (${outputs.length} stable output assets)`);
15819
- return this.sortAllStables(decodedBids, outputs, chainId);
15991
+ return this.sortAllStables(bids, outputs, chainId);
15820
15992
  }
15821
15993
  console.log(`[BidManager] Using mixed-output sorting (${outputs.length} output assets, some non-stable)`);
15822
- return this.sortMixedOutputs(decodedBids, outputs, chainId);
15823
- }
15824
- /**
15825
- * Decodes the `fillOrder` fill-options from each bid's ERC-7821 calldata.
15826
- *
15827
- * Bids whose calldata cannot be decoded or do not contain a valid
15828
- * `fillOrder` call are silently dropped with a warning.
15829
- *
15830
- * @param bids - Raw bids to decode.
15831
- * @returns Array of successfully decoded `{ bid, options }` pairs.
15832
- */
15833
- decodeBids(bids) {
15834
- const result = [];
15835
- for (const bid of bids) {
15836
- const fillOptions = this.decodeBidFillOptions(bid);
15837
- if (fillOptions) {
15838
- result.push({ bid, options: fillOptions });
15839
- } else {
15840
- console.warn(`[BidManager] Failed to decode fillOptions from bid by solver=${bid.userOp.sender}`);
15841
- }
15842
- }
15843
- console.log(`[BidManager] Decoded ${result.length}/${bids.length} bid(s) successfully`);
15844
- return result;
15994
+ return this.sortMixedOutputs(bids, outputs, chainId);
15845
15995
  }
15846
15996
  /**
15847
15997
  * Extracts the `FillOptions` struct from a single bid's ERC-7821
@@ -15874,149 +16024,103 @@ var BidManager = class {
15874
16024
  }
15875
16025
  return null;
15876
16026
  }
15877
- /**
15878
- * Simulates a bid on-chain by batching the `select` and `fillOrder` calls
15879
- * via `eth_call` from the solver's account, using the IntentGatewayV2
15880
- * ERC-7821 batch-execute pattern.
15881
- *
15882
- * The native value forwarded to the simulation is computed from the fill options:
15883
- * sum of any native-token (address(0)) output amounts plus the dispatch fee.
15884
- *
15885
- * @param bid - The filler bid to simulate.
15886
- * @param fillOptions - Decoded fill options from the bid's calldata.
15887
- * @param selectOptions - The signed solver-selection parameters.
15888
- * @param intentGatewayV2Address - Address of the IntentGatewayV2 contract on the destination chain.
15889
- * @throws If the `eth_call` simulation reverts or errors.
15890
- */
15891
- async simulate(bid, fillOptions, selectOptions, intentGatewayV2Address) {
15892
- const solverAddress = bid.userOp.sender;
15893
- const nativeOutputs = fillOptions.outputs.reduce(
15894
- (acc, o) => bytes32ToBytes20(o.token) === ADDRESS_ZERO2 ? acc + o.amount : acc,
15895
- 0n
15896
- );
15897
- const simulationValue = nativeOutputs + fillOptions.nativeDispatchFee;
15898
- const selectCalldata = encodeFunctionData({
15899
- abi: ABI3,
15900
- functionName: "select",
15901
- args: [selectOptions]
15902
- });
15903
- const calls = [
15904
- { target: intentGatewayV2Address, value: 0n, data: selectCalldata },
15905
- { target: solverAddress, value: simulationValue, data: bid.userOp.callData }
15906
- ];
15907
- const batchedCalldata = this.crypto.encodeERC7821Execute(calls);
15908
- try {
15909
- await this.ctx.dest.client.call({
15910
- account: solverAddress,
15911
- to: solverAddress,
15912
- data: batchedCalldata,
15913
- value: simulationValue
15914
- });
15915
- } catch (e) {
15916
- throw new Error(`Simulation failed: ${e instanceof Error ? e.message : String(e)}`);
15917
- }
15918
- }
15919
16027
  /**
15920
16028
  * Case A: single output token.
15921
16029
  * Filter bids by token match only, sort descending by amount.
15922
16030
  * Partial fill bids are allowed — the contract determines fill status.
15923
16031
  */
15924
- sortSingleOutput(decodedBids, requiredAsset) {
16032
+ sortSingleOutput(bids, requiredAsset) {
15925
16033
  const requiredAmount = new Decimal2(requiredAsset.amount.toString());
15926
16034
  console.log(
15927
16035
  `[BidManager] sortSingleOutput: required token=${requiredAsset.token}, amount=${requiredAmount.toString()}`
15928
16036
  );
15929
16037
  const validBids = [];
15930
- for (const { bid, options } of decodedBids) {
15931
- const bidOutput = options.outputs[0];
16038
+ for (const bid of bids) {
16039
+ const bidOutput = bid.outputs[0];
15932
16040
  const bidAmount = new Decimal2(bidOutput.amount.toString());
15933
16041
  if (bidOutput.token.toLowerCase() !== requiredAsset.token.toLowerCase()) {
15934
16042
  console.warn(
15935
- `[BidManager] Bid from solver=${bid.userOp.sender} REJECTED: token mismatch (bid=${bidOutput.token}, required=${requiredAsset.token})`
16043
+ `[BidManager] Bid from solver=${bid.solverAddress} REJECTED: token mismatch (bid=${bidOutput.token}, required=${requiredAsset.token})`
15936
16044
  );
15937
16045
  continue;
15938
16046
  }
15939
16047
  if (bidAmount.lt(requiredAmount)) {
15940
16048
  console.log(
15941
- `[BidManager] Bid from solver=${bid.userOp.sender}: partial fill candidate (bid=${bidAmount.toString()}, required=${requiredAmount.toString()}, covers=${bidAmount.div(requiredAmount).mul(100).toFixed(2)}%)`
16049
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (bid=${bidAmount.toString()}, required=${requiredAmount.toString()}, covers=${bidAmount.div(requiredAmount).mul(100).toFixed(2)}%)`
15942
16050
  );
15943
16051
  } else {
15944
16052
  console.log(
15945
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED: amount=${bidAmount.toString()} (surplus=${bidAmount.minus(requiredAmount).toString()})`
16053
+ `[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED: amount=${bidAmount.toString()} (surplus=${bidAmount.minus(requiredAmount).toString()})`
15946
16054
  );
15947
16055
  }
15948
- validBids.push({ bid, options, amount: bidOutput.amount });
16056
+ validBids.push({ bid, amount: bidOutput.amount });
15949
16057
  }
15950
16058
  validBids.sort((a, b) => {
15951
16059
  const aAmt = new Decimal2(a.amount.toString());
15952
16060
  const bAmt = new Decimal2(b.amount.toString());
15953
16061
  return bAmt.comparedTo(aAmt);
15954
16062
  });
15955
- return validBids.map(({ amount: _, ...rest }) => rest);
16063
+ return validBids.map(({ bid }) => bid);
15956
16064
  }
15957
16065
  /**
15958
16066
  * Case B: all outputs are USDC/USDT.
15959
16067
  * Sum normalised USD values (treating each stable as $1) and sort descending.
15960
16068
  * Partial fill bids are allowed.
15961
16069
  */
15962
- sortAllStables(decodedBids, orderOutputs, chainId) {
16070
+ sortAllStables(bids, orderOutputs, chainId) {
15963
16071
  const requiredUsd = this.computeStablesUsdValue(orderOutputs, chainId);
15964
16072
  console.log(`[BidManager] sortAllStables: required USD value=${requiredUsd.toString()}`);
15965
16073
  const validBids = [];
15966
- for (const { bid, options } of decodedBids) {
15967
- const bidUsd = this.computeStablesUsdValue(options.outputs, chainId);
16074
+ for (const bid of bids) {
16075
+ const bidUsd = this.computeStablesUsdValue(bid.outputs, chainId);
15968
16076
  if (bidUsd === null) {
15969
- console.warn(`[BidManager] Bid from solver=${bid.userOp.sender} REJECTED: unable to compute USD value`);
16077
+ console.warn(`[BidManager] Bid from solver=${bid.solverAddress} REJECTED: unable to compute USD value`);
15970
16078
  continue;
15971
16079
  }
15972
16080
  if (bidUsd.lt(requiredUsd)) {
15973
16081
  console.log(
15974
- `[BidManager] Bid from solver=${bid.userOp.sender}: partial fill candidate (bid=${bidUsd.toString()}, required=${requiredUsd.toString()}, covers=${bidUsd.div(requiredUsd).mul(100).toFixed(2)}%)`
16082
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (bid=${bidUsd.toString()}, required=${requiredUsd.toString()}, covers=${bidUsd.div(requiredUsd).mul(100).toFixed(2)}%)`
15975
16083
  );
15976
16084
  } else {
15977
- console.log(
15978
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED: USD value=${bidUsd.toString()}`
15979
- );
16085
+ console.log(`[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED: USD value=${bidUsd.toString()}`);
15980
16086
  }
15981
- validBids.push({ bid, options, usdValue: bidUsd });
16087
+ validBids.push({ bid, usdValue: bidUsd });
15982
16088
  }
15983
16089
  validBids.sort((a, b) => b.usdValue.comparedTo(a.usdValue));
15984
- return validBids.map(({ usdValue: _, ...rest }) => rest);
16090
+ return validBids.map(({ bid }) => bid);
15985
16091
  }
15986
16092
  /**
15987
16093
  * Case C: mixed output tokens (at least one non-stable).
15988
16094
  * Price every token via on-chain DEX quotes, fall back to raw amounts
15989
16095
  * if pricing is unavailable. Partial fill bids are allowed.
15990
16096
  */
15991
- async sortMixedOutputs(decodedBids, orderOutputs, chainId) {
16097
+ async sortMixedOutputs(bids, orderOutputs, chainId) {
15992
16098
  const requiredUsd = await this.computeOutputsUsdValue(orderOutputs, chainId);
15993
16099
  if (requiredUsd === null) {
15994
16100
  console.warn("[BidManager] sortMixedOutputs: output tokens unpriceable, falling back to raw-amount sort");
15995
- return this.sortByRawAmountFallback(decodedBids, orderOutputs);
16101
+ return this.sortByRawAmountFallback(bids, orderOutputs);
15996
16102
  }
15997
16103
  console.log(`[BidManager] sortMixedOutputs: required USD value=${requiredUsd.toString()}`);
15998
16104
  const validBids = [];
15999
- for (const { bid, options } of decodedBids) {
16000
- const bidUsd = await this.computeOutputsUsdValue(options.outputs, chainId);
16105
+ for (const bid of bids) {
16106
+ const bidUsd = await this.computeOutputsUsdValue(bid.outputs, chainId);
16001
16107
  if (bidUsd === null) {
16002
- console.warn(
16003
- `[BidManager] Bid from solver=${bid.userOp.sender} REJECTED: unable to price mixed outputs`
16004
- );
16108
+ console.warn(`[BidManager] Bid from solver=${bid.solverAddress} REJECTED: unable to price mixed outputs`);
16005
16109
  continue;
16006
16110
  }
16007
16111
  if (bidUsd.lt(requiredUsd)) {
16008
16112
  console.log(
16009
- `[BidManager] Bid from solver=${bid.userOp.sender}: partial fill candidate (bid=${bidUsd.toString()}, required=${requiredUsd.toString()}, covers=${bidUsd.div(requiredUsd).mul(100).toFixed(2)}%)`
16113
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (bid=${bidUsd.toString()}, required=${requiredUsd.toString()}, covers=${bidUsd.div(requiredUsd).mul(100).toFixed(2)}%)`
16010
16114
  );
16011
16115
  } else {
16012
16116
  console.log(
16013
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED: mixed USD value=${bidUsd.toString()}`
16117
+ `[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED: mixed USD value=${bidUsd.toString()}`
16014
16118
  );
16015
16119
  }
16016
- validBids.push({ bid, options, usdValue: bidUsd });
16120
+ validBids.push({ bid, usdValue: bidUsd });
16017
16121
  }
16018
16122
  validBids.sort((a, b) => b.usdValue.comparedTo(a.usdValue));
16019
- return validBids.map(({ usdValue: _, ...rest }) => rest);
16123
+ return validBids.map(({ bid }) => bid);
16020
16124
  }
16021
16125
  /**
16022
16126
  * Fallback when DEX pricing is unavailable.
@@ -16024,17 +16128,17 @@ var BidManager = class {
16024
16128
  * Bids offering less than required for a token are allowed (partial fill).
16025
16129
  * Sorted by total offered amount descending.
16026
16130
  */
16027
- sortByRawAmountFallback(decodedBids, orderOutputs) {
16131
+ sortByRawAmountFallback(bids, orderOutputs) {
16028
16132
  console.log(
16029
- `[BidManager] sortByRawAmountFallback: checking ${decodedBids.length} bid(s) against ${orderOutputs.length} required output(s)`
16133
+ `[BidManager] sortByRawAmountFallback: checking ${bids.length} bid(s) against ${orderOutputs.length} required output(s)`
16030
16134
  );
16031
16135
  const validBids = [];
16032
- for (const { bid, options } of decodedBids) {
16136
+ for (const bid of bids) {
16033
16137
  let valid = true;
16034
16138
  let totalOffered = new Decimal2(0);
16035
16139
  let rejectReason = "";
16036
16140
  for (const required of orderOutputs) {
16037
- const matching = options.outputs.find((o) => o.token.toLowerCase() === required.token.toLowerCase());
16141
+ const matching = bid.outputs.find((o) => o.token.toLowerCase() === required.token.toLowerCase());
16038
16142
  if (!matching) {
16039
16143
  valid = false;
16040
16144
  rejectReason = `missing output token=${required.token}`;
@@ -16043,7 +16147,7 @@ var BidManager = class {
16043
16147
  totalOffered = totalOffered.plus(new Decimal2(matching.amount.toString()));
16044
16148
  }
16045
16149
  if (!valid) {
16046
- console.warn(`[BidManager] Bid from solver=${bid.userOp.sender} REJECTED (fallback): ${rejectReason}`);
16150
+ console.warn(`[BidManager] Bid from solver=${bid.solverAddress} REJECTED (fallback): ${rejectReason}`);
16047
16151
  continue;
16048
16152
  }
16049
16153
  const totalRequired = orderOutputs.reduce(
@@ -16052,17 +16156,17 @@ var BidManager = class {
16052
16156
  );
16053
16157
  if (totalOffered.lt(totalRequired)) {
16054
16158
  console.log(
16055
- `[BidManager] Bid from solver=${bid.userOp.sender}: partial fill candidate (fallback) (offered=${totalOffered.toString()}, required=${totalRequired.toString()}, covers=${totalOffered.div(totalRequired).mul(100).toFixed(2)}%)`
16159
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (fallback) (offered=${totalOffered.toString()}, required=${totalRequired.toString()}, covers=${totalOffered.div(totalRequired).mul(100).toFixed(2)}%)`
16056
16160
  );
16057
16161
  } else {
16058
16162
  console.log(
16059
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED (fallback): totalOffered=${totalOffered.toString()}`
16163
+ `[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED (fallback): totalOffered=${totalOffered.toString()}`
16060
16164
  );
16061
16165
  }
16062
- validBids.push({ bid, options, totalOffered });
16166
+ validBids.push({ bid, totalOffered });
16063
16167
  }
16064
16168
  validBids.sort((a, b) => b.totalOffered.comparedTo(a.totalOffered));
16065
- return validBids.map(({ totalOffered: _, ...rest }) => rest);
16169
+ return validBids.map(({ bid }) => bid);
16066
16170
  }
16067
16171
  // ── Token classification helpers ──────────────────────────────────
16068
16172
  /**
@@ -16671,6 +16775,262 @@ var OrderStatusChecker = class {
16671
16775
  }
16672
16776
  };
16673
16777
 
16778
+ // src/protocols/intents/quote/types.ts
16779
+ var UnsupportedIntentQuoteStrategyError = class extends Error {
16780
+ constructor(strategy) {
16781
+ super(`Unsupported intent quote strategy: ${strategy}`);
16782
+ this.name = "UnsupportedIntentQuoteStrategyError";
16783
+ }
16784
+ };
16785
+ var UnsupportedIntentQuotePairError = class extends Error {
16786
+ constructor(params) {
16787
+ super(
16788
+ `No Uniswap v4 pool config found for ${params.tokenIn.symbol ?? params.tokenIn.address} -> ${params.tokenOut.symbol ?? params.tokenOut.address} on ${params.source} -> ${params.destination}`
16789
+ );
16790
+ this.name = "UnsupportedIntentQuotePairError";
16791
+ }
16792
+ };
16793
+
16794
+ // src/protocols/intents/quote/uniswapV4.ts
16795
+ var UNISWAP_INTENT_QUOTE_CHAIN = "EVM-8453" /* BASE_MAINNET */;
16796
+ var BPS_DENOMINATOR = 10000n;
16797
+ var UniswapV4IntentQuoteStrategy = class {
16798
+ constructor(chainConfigService) {
16799
+ this.chainConfigService = chainConfigService;
16800
+ }
16801
+ chainConfigService;
16802
+ baseQuoteClient;
16803
+ async quote(params, source, destination) {
16804
+ this.validateQuoteParams(params);
16805
+ const protocolFeeBps = await this.readProtocolFeeBps(source.client, source.stateMachineId);
16806
+ const quoteClient = this.resolveQuoteClient(source, destination);
16807
+ const poolConfig = this.resolvePoolConfig(params, source.stateMachineId, UNISWAP_INTENT_QUOTE_CHAIN);
16808
+ return params.amountIn !== void 0 ? this.quoteExactInput({ params, client: quoteClient, protocolFeeBps, poolConfig }) : this.quoteExactOutput({ params, client: quoteClient, protocolFeeBps, poolConfig });
16809
+ }
16810
+ resolveQuoteClient(source, destination) {
16811
+ if (source.stateMachineId === UNISWAP_INTENT_QUOTE_CHAIN) return source.client;
16812
+ if (destination.stateMachineId === UNISWAP_INTENT_QUOTE_CHAIN) return destination.client;
16813
+ if (this.baseQuoteClient) return this.baseQuoteClient;
16814
+ const rpcUrl = this.chainConfigService.getRpcUrl(UNISWAP_INTENT_QUOTE_CHAIN);
16815
+ if (!rpcUrl) throw new Error(`RPC URL is not configured for ${UNISWAP_INTENT_QUOTE_CHAIN}`);
16816
+ const baseQuoteClient = createPublicClient({
16817
+ chain: base,
16818
+ transport: http(rpcUrl)
16819
+ });
16820
+ this.baseQuoteClient = baseQuoteClient;
16821
+ return baseQuoteClient;
16822
+ }
16823
+ validateQuoteParams(params) {
16824
+ const hasAmountIn = params.amountIn !== void 0;
16825
+ const hasAmountOut = params.amountOut !== void 0;
16826
+ if (hasAmountIn === hasAmountOut) throw new Error("Provide exactly one of amountIn or amountOut");
16827
+ if (hasAmountIn && params.amountIn <= 0n) throw new Error("amountIn must be greater than zero");
16828
+ if (hasAmountOut && params.amountOut <= 0n) throw new Error("amountOut must be greater than zero");
16829
+ if (params.tokenIn.address.toLowerCase() === params.tokenOut.address.toLowerCase()) {
16830
+ throw new Error("tokenIn and tokenOut cannot be the same");
16831
+ }
16832
+ }
16833
+ async readProtocolFeeBps(client, chain) {
16834
+ const gatewayAddress = this.chainConfigService.getIntentGatewayAddress(chain);
16835
+ if (!gatewayAddress || gatewayAddress === "0x" || gatewayAddress === zeroAddress) {
16836
+ throw new Error(`IntentGatewayV2 is not configured for chain ${chain}`);
16837
+ }
16838
+ const gatewayParams = await client.readContract({
16839
+ address: gatewayAddress,
16840
+ abi: IntentGatewayV2_default.ABI,
16841
+ functionName: "params"
16842
+ });
16843
+ if (isGatewayParamsTuple(gatewayParams)) return BigInt(gatewayParams[4]);
16844
+ return BigInt(gatewayParams.protocolFeeBps ?? 0);
16845
+ }
16846
+ resolvePoolConfig(params, source, destination) {
16847
+ const override = params.uniswapV4?.poolKey;
16848
+ if (override) {
16849
+ const poolKey = normalizePoolKey(override);
16850
+ const tokenInForQuote = getAddress(override.currencyIn ?? params.tokenIn.address);
16851
+ if (tokenInForQuote !== poolKey.currency0 && tokenInForQuote !== poolKey.currency1) {
16852
+ throw new Error(
16853
+ `Input currency ${tokenInForQuote} is not part of the override pool (${poolKey.currency0}, ${poolKey.currency1}). For cross-chain quotes pass uniswapV4.poolKey.currencyIn with the Base-side input currency address.`
16854
+ );
16855
+ }
16856
+ return {
16857
+ poolKey,
16858
+ quoterAddress: this.resolveQuoterAddress(destination, override.quoterAddress),
16859
+ tokenInForQuote
16860
+ };
16861
+ }
16862
+ const poolConfig = this.resolveConfiguredPool(params, destination);
16863
+ if (poolConfig) return poolConfig;
16864
+ throw new UnsupportedIntentQuotePairError({
16865
+ source,
16866
+ destination,
16867
+ tokenIn: params.tokenIn,
16868
+ tokenOut: params.tokenOut
16869
+ });
16870
+ }
16871
+ resolveConfiguredPool(params, chain) {
16872
+ for (const pool of this.chainConfigService.getUniswapV4PoolConfigs(chain)) {
16873
+ const resolvedPool = this.resolveConfiguredPoolTokens(chain, pool);
16874
+ if (!resolvedPool) continue;
16875
+ const tokenInForQuote = matchPoolToken(params.tokenIn, resolvedPool);
16876
+ const tokenOutForQuote = matchPoolToken(params.tokenOut, resolvedPool);
16877
+ if (!tokenInForQuote || !tokenOutForQuote || tokenInForQuote.symbol === tokenOutForQuote.symbol) continue;
16878
+ const { currency0, currency1 } = sortCurrencies(resolvedPool[0].address, resolvedPool[1].address);
16879
+ return {
16880
+ poolKey: {
16881
+ currency0,
16882
+ currency1,
16883
+ fee: pool.fee,
16884
+ tickSpacing: pool.tickSpacing,
16885
+ hooks: getAddress(pool.hooks ?? zeroAddress)
16886
+ },
16887
+ quoterAddress: this.resolveQuoterAddress(chain),
16888
+ tokenInForQuote: tokenInForQuote.address
16889
+ };
16890
+ }
16891
+ return null;
16892
+ }
16893
+ resolveQuoterAddress(chain, override) {
16894
+ const address = override ?? this.chainConfigService.getUniswapV4QuoterAddress(chain);
16895
+ if (!address || address === "0x" || address === zeroAddress) {
16896
+ throw new Error(`Uniswap V4 quoter is not configured for chain ${chain}`);
16897
+ }
16898
+ return getAddress(address);
16899
+ }
16900
+ resolveConfiguredPoolTokens(chain, pool) {
16901
+ const first = this.resolveConfiguredPoolToken(chain, pool.tokens[0]);
16902
+ const second = this.resolveConfiguredPoolToken(chain, pool.tokens[1]);
16903
+ return first && second ? [first, second] : null;
16904
+ }
16905
+ resolveConfiguredPoolToken(chain, symbol) {
16906
+ const address = this.chainConfigService.getAssetAddress(chain, symbol);
16907
+ if (!address || address === "0x") return null;
16908
+ return { symbol, address: getAddress(address) };
16909
+ }
16910
+ async quoteExactInput(args) {
16911
+ const amountIn = args.params.amountIn;
16912
+ const swapAmountIn = deductProtocolFee(amountIn, args.protocolFeeBps);
16913
+ const amountOut = await this.readV4QuoteExactInput(args.client, args.poolConfig, swapAmountIn);
16914
+ return {
16915
+ strategy: "uniswap_v4",
16916
+ tradeType: "EXACT_INPUT",
16917
+ amountIn,
16918
+ amountOut,
16919
+ quoteMetadata: {
16920
+ quoteChain: UNISWAP_INTENT_QUOTE_CHAIN,
16921
+ poolKey: args.poolConfig.poolKey,
16922
+ quoterAddress: args.poolConfig.quoterAddress,
16923
+ protocolFeeBps: args.protocolFeeBps
16924
+ }
16925
+ };
16926
+ }
16927
+ async quoteExactOutput(args) {
16928
+ const amountOut = args.params.amountOut;
16929
+ const swapAmountIn = await this.readV4QuoteExactOutput(args.client, args.poolConfig, amountOut);
16930
+ const amountIn = grossUpForProtocolFee(swapAmountIn, args.protocolFeeBps);
16931
+ return {
16932
+ strategy: "uniswap_v4",
16933
+ tradeType: "EXACT_OUTPUT",
16934
+ amountIn,
16935
+ amountOut,
16936
+ quoteMetadata: {
16937
+ quoteChain: UNISWAP_INTENT_QUOTE_CHAIN,
16938
+ poolKey: args.poolConfig.poolKey,
16939
+ quoterAddress: args.poolConfig.quoterAddress,
16940
+ protocolFeeBps: args.protocolFeeBps
16941
+ }
16942
+ };
16943
+ }
16944
+ async readV4QuoteExactInput(client, poolConfig, amountIn) {
16945
+ const data = encodeFunctionData({
16946
+ abi: UNISWAP_V4_QUOTER_ABI,
16947
+ functionName: "quoteExactInputSingle",
16948
+ args: [
16949
+ {
16950
+ poolKey: poolConfig.poolKey,
16951
+ zeroForOne: getZeroForOne(poolConfig.tokenInForQuote, poolConfig.poolKey),
16952
+ exactAmount: amountIn,
16953
+ hookData: "0x"
16954
+ }
16955
+ ]
16956
+ });
16957
+ const response = await client.call({ to: poolConfig.quoterAddress, data });
16958
+ if (!response.data || response.data === "0x") {
16959
+ throw new Error(`Uniswap V4 quoter at ${poolConfig.quoterAddress} returned no data`);
16960
+ }
16961
+ const [amountOut] = decodeFunctionResult({
16962
+ abi: UNISWAP_V4_QUOTER_ABI,
16963
+ functionName: "quoteExactInputSingle",
16964
+ data: response.data
16965
+ });
16966
+ return amountOut;
16967
+ }
16968
+ async readV4QuoteExactOutput(client, poolConfig, amountOut) {
16969
+ const data = encodeFunctionData({
16970
+ abi: UNISWAP_V4_QUOTER_ABI,
16971
+ functionName: "quoteExactOutputSingle",
16972
+ args: [
16973
+ {
16974
+ poolKey: poolConfig.poolKey,
16975
+ zeroForOne: getZeroForOne(poolConfig.tokenInForQuote, poolConfig.poolKey),
16976
+ exactAmount: amountOut,
16977
+ hookData: "0x"
16978
+ }
16979
+ ]
16980
+ });
16981
+ const response = await client.call({ to: poolConfig.quoterAddress, data });
16982
+ if (!response.data || response.data === "0x") {
16983
+ throw new Error(`Uniswap V4 quoter at ${poolConfig.quoterAddress} returned no data`);
16984
+ }
16985
+ const [amountIn] = decodeFunctionResult({
16986
+ abi: UNISWAP_V4_QUOTER_ABI,
16987
+ functionName: "quoteExactOutputSingle",
16988
+ data: response.data
16989
+ });
16990
+ return amountIn;
16991
+ }
16992
+ };
16993
+ function normalizePoolKey(poolKey) {
16994
+ return {
16995
+ currency0: getAddress(poolKey.currency0),
16996
+ currency1: getAddress(poolKey.currency1),
16997
+ fee: poolKey.fee,
16998
+ tickSpacing: poolKey.tickSpacing,
16999
+ hooks: getAddress(poolKey.hooks)
17000
+ };
17001
+ }
17002
+ function sortCurrencies(tokenIn, tokenOut) {
17003
+ const input = getAddress(tokenIn);
17004
+ const output = getAddress(tokenOut);
17005
+ return BigInt(input) < BigInt(output) ? { currency0: input, currency1: output } : { currency0: output, currency1: input };
17006
+ }
17007
+ function matchPoolToken(token, poolTokens) {
17008
+ const tokenAddress = token.address.toLowerCase();
17009
+ const addressMatch = poolTokens.find((poolToken) => poolToken.address.toLowerCase() === tokenAddress);
17010
+ if (addressMatch) return addressMatch;
17011
+ const tokenSymbol = token.symbol?.toUpperCase();
17012
+ if (!tokenSymbol) return null;
17013
+ return poolTokens.find((poolToken) => poolToken.symbol.toUpperCase() === tokenSymbol) ?? null;
17014
+ }
17015
+ function getZeroForOne(tokenIn, poolKey) {
17016
+ return getAddress(tokenIn).toLowerCase() === getAddress(poolKey.currency0).toLowerCase();
17017
+ }
17018
+ function isGatewayParamsTuple(value) {
17019
+ return Array.isArray(value);
17020
+ }
17021
+ function deductProtocolFee(amount, protocolFeeBps) {
17022
+ if (protocolFeeBps <= 0n) return amount;
17023
+ const fee = amount * protocolFeeBps / BPS_DENOMINATOR;
17024
+ return amount - fee;
17025
+ }
17026
+ function grossUpForProtocolFee(netAmount, protocolFeeBps) {
17027
+ if (protocolFeeBps <= 0n) return netAmount;
17028
+ return divCeil(netAmount * BPS_DENOMINATOR, BPS_DENOMINATOR - protocolFeeBps);
17029
+ }
17030
+ function divCeil(numerator, denominator) {
17031
+ return (numerator + denominator - 1n) / denominator;
17032
+ }
17033
+
16674
17034
  // src/protocols/intents/IntentGateway.ts
16675
17035
  var IntentGateway = class _IntentGateway {
16676
17036
  /** EVM chain on which orders are placed and escrowed. */
@@ -16697,6 +17057,8 @@ var IntentGateway = class _IntentGateway {
16697
17057
  bidManager;
16698
17058
  /** Estimates gas costs for filling an order and converts them to fee-token amounts. */
16699
17059
  gasEstimator;
17060
+ /** Quote strategies for pricing orders before placement, keyed by strategy name. */
17061
+ quoteStrategies;
16700
17062
  /**
16701
17063
  * Private constructor — use {@link IntentGateway.create} instead.
16702
17064
  *
@@ -16734,12 +17096,15 @@ var IntentGateway = class _IntentGateway {
16734
17096
  const bidManager = new BidManager(this.ctx, crypto);
16735
17097
  const gasEstimator = new GasEstimator(this.ctx, crypto);
16736
17098
  this.orderPlacer = new OrderPlacer(this.ctx);
16737
- this.orderExecutor = new OrderExecutor(this.ctx, bidManager, crypto);
17099
+ this.orderExecutor = new OrderExecutor(this.ctx, bidManager);
16738
17100
  this.orderCanceller = new OrderCanceller(this.ctx);
16739
17101
  this.orderStatusChecker = new OrderStatusChecker(this.ctx);
16740
17102
  this.bidManager = bidManager;
16741
17103
  this.gasEstimator = gasEstimator;
16742
17104
  this._crypto = crypto;
17105
+ this.quoteStrategies = {
17106
+ uniswap_v4: new UniswapV4IntentQuoteStrategy(dest.configService)
17107
+ };
16743
17108
  }
16744
17109
  /**
16745
17110
  * Creates an initialized IntentGateway instance.
@@ -16784,6 +17149,33 @@ var IntentGateway = class _IntentGateway {
16784
17149
  }
16785
17150
  }
16786
17151
  }
17152
+ /**
17153
+ * Quotes an intent between this gateway's source and destination chains.
17154
+ *
17155
+ * `strategy` defaults to `uniswap_v4`, currently the only supported
17156
+ * strategy. Provide exactly one of `amountIn` or `amountOut`.
17157
+ *
17158
+ * The Uniswap quote strategy always prices against the configured Base
17159
+ * pool, regardless of this gateway's destination chain. Returned
17160
+ * `amountIn`/`amountOut` already account for the gateway's protocol fee
17161
+ * (`quoteMetadata.protocolFeeBps`), which the gateway deducts from order
17162
+ * inputs; apply only your own slippage tolerance before placing the order.
17163
+ *
17164
+ * @param params - Token pair, amount, and optional strategy/pool overrides.
17165
+ * @returns The quoted amounts plus strategy-specific metadata.
17166
+ * @throws {UnsupportedIntentQuoteStrategyError} For unknown strategies.
17167
+ * @throws {UnsupportedIntentQuotePairError} When no pool is configured for the pair.
17168
+ */
17169
+ async quoteIntent(params) {
17170
+ const strategy = params.strategy ?? "uniswap_v4";
17171
+ const handler = this.quoteStrategies[strategy];
17172
+ if (!handler) throw new UnsupportedIntentQuoteStrategyError(strategy);
17173
+ return handler.quote(
17174
+ { ...params, strategy },
17175
+ { stateMachineId: this.source.config.stateMachineId, client: this.source.client },
17176
+ { stateMachineId: this.dest.config.stateMachineId, client: this.dest.client }
17177
+ );
17178
+ }
16787
17179
  /**
16788
17180
  * Bidirectional async generator that orchestrates the full order lifecycle:
16789
17181
  * placement, fee estimation, bid collection, and execution.
@@ -16838,17 +17230,38 @@ var IntentGateway = class _IntentGateway {
16838
17230
  }
16839
17231
  const { order: finalizedOrder, receipt: placementReceipt } = placeOrderSecond.value;
16840
17232
  yield { status: "ORDER_PLACED", order: finalizedOrder, receipt: placementReceipt };
16841
- for await (const status of this.orderExecutor.executeOrder({
16842
- order: finalizedOrder,
16843
- sessionPrivateKey,
16844
- auctionTimeMs: options.auctionTimeMs,
16845
- pollIntervalMs: options.pollIntervalMs,
16846
- solver: options.solver
16847
- })) {
16848
- yield status;
16849
- }
17233
+ yield* this.driveExecution(
17234
+ this.orderExecutor.executeOrder({
17235
+ order: finalizedOrder,
17236
+ sessionPrivateKey,
17237
+ auctionTimeMs: options.auctionTimeMs,
17238
+ pollIntervalMs: options.pollIntervalMs,
17239
+ solver: options.solver
17240
+ })
17241
+ );
16850
17242
  return;
16851
17243
  }
17244
+ /**
17245
+ * Forwards updates from the executor's bidirectional generator to the caller,
17246
+ * threading the {@link SelectBidResult} the caller feeds back after a
17247
+ * `BIDS_RECEIVED` yield into the executor's `.next()`. Other yields expect no
17248
+ * feedback. This is what lets the consumer own `bid.execute()` while the
17249
+ * executor keeps tracking fills and continuing the auction.
17250
+ */
17251
+ async *driveExecution(execGen) {
17252
+ try {
17253
+ let input;
17254
+ while (true) {
17255
+ const { value, done } = await execGen.next(input);
17256
+ input = void 0;
17257
+ if (done) break;
17258
+ const fed = yield value;
17259
+ if (value.status === "BIDS_RECEIVED") input = fed;
17260
+ }
17261
+ } finally {
17262
+ await execGen.return();
17263
+ }
17264
+ }
16852
17265
  /**
16853
17266
  * Validates that an order has the minimum fields required for post-placement
16854
17267
  * resume (i.e. it was previously placed and has an on-chain identity).
@@ -16885,14 +17298,99 @@ var IntentGateway = class _IntentGateway {
16885
17298
  */
16886
17299
  async *resume(order, options) {
16887
17300
  this.assertOrderCanResume(order);
16888
- for await (const status of this.orderExecutor.executeOrder({
16889
- order,
16890
- sessionPrivateKey: options.sessionPrivateKey,
16891
- auctionTimeMs: options.auctionTimeMs,
16892
- pollIntervalMs: options.pollIntervalMs,
16893
- solver: options.solver
16894
- })) {
16895
- yield status;
17301
+ yield* this.driveExecution(
17302
+ this.orderExecutor.executeOrder({
17303
+ order,
17304
+ sessionPrivateKey: options.sessionPrivateKey,
17305
+ auctionTimeMs: options.auctionTimeMs,
17306
+ pollIntervalMs: options.pollIntervalMs,
17307
+ solver: options.solver
17308
+ })
17309
+ );
17310
+ }
17311
+ /**
17312
+ * Batteries-included variant of {@link execute}: places the order and then
17313
+ * auto-selects the best bid each round via {@link selectAndExecuteBest}, with
17314
+ * no bid-selection input from the caller.
17315
+ *
17316
+ * The caller still signs the placement transaction: this generator yields
17317
+ * `AWAITING_PLACE_ORDER` and the caller must hand the signed tx back via
17318
+ * `gen.next(signedTx)` exactly as with {@link execute}. Every other stage
17319
+ * (`BIDS_RECEIVED`, `BID_SELECTED`, `FILLED`, …) is handled automatically and
17320
+ * surfaced for observation, so the rest of the loop needs no feedback.
17321
+ *
17322
+ * @param order - The order to place and execute.
17323
+ * @param graffiti - Optional orderflow-attribution tag.
17324
+ * @param options - Same tuning parameters as {@link execute}.
17325
+ * @yields {@link IntentOrderStatusUpdate} at each lifecycle stage.
17326
+ */
17327
+ async *executeBest(order, graffiti = DEFAULT_GRAFFITI, options) {
17328
+ const gen = this.execute(order, graffiti, options);
17329
+ try {
17330
+ let input;
17331
+ while (true) {
17332
+ const { value, done } = await gen.next(input);
17333
+ input = void 0;
17334
+ if (done) break;
17335
+ if (value.status === "BIDS_RECEIVED") {
17336
+ yield value;
17337
+ input = await this.autoSelect(order, value.bids);
17338
+ } else if (value.status === "AWAITING_PLACE_ORDER") {
17339
+ input = yield value;
17340
+ } else {
17341
+ yield value;
17342
+ }
17343
+ }
17344
+ } finally {
17345
+ await gen.return();
17346
+ }
17347
+ }
17348
+ /**
17349
+ * Batteries-included variant of {@link resume}: auto-selects the best bid each
17350
+ * round via {@link selectAndExecuteBest}, with no bid-selection input from the
17351
+ * caller. A plain `for await` loop is sufficient — there is no placement step.
17352
+ *
17353
+ * @param order - A previously placed order with a valid `id` and `session`.
17354
+ * @param options - Optional tuning parameters for bid collection and execution.
17355
+ * @yields {@link IntentOrderStatusUpdate} at each execution stage.
17356
+ */
17357
+ async *resumeBest(order, options) {
17358
+ const gen = this.resume(order, options);
17359
+ try {
17360
+ let input;
17361
+ while (true) {
17362
+ const { value, done } = await gen.next(input);
17363
+ input = void 0;
17364
+ if (done) break;
17365
+ yield value;
17366
+ if (value.status === "BIDS_RECEIVED") {
17367
+ input = await this.autoSelect(order, value.bids);
17368
+ }
17369
+ }
17370
+ } finally {
17371
+ await gen.return();
17372
+ }
17373
+ }
17374
+ /**
17375
+ * Auto-select wrapper used by {@link executeBest} / {@link resumeBest}.
17376
+ *
17377
+ * Runs {@link selectAndExecuteBest} and returns the {@link SelectBidResult} to
17378
+ * feed back to the executor. If selection fails this round — all bids fail
17379
+ * simulation, no valid bids, or the bundler rejects the UserOp — it swallows
17380
+ * the error and returns `undefined`, which tells the executor to keep polling
17381
+ * for fresh bids until the deadline rather than aborting the order. Swallowing
17382
+ * the error here (rather than letting it propagate) also keeps the executor's
17383
+ * `finally` teardown intact, since nothing throws across the suspended
17384
+ * generators.
17385
+ */
17386
+ async autoSelect(order, bids) {
17387
+ try {
17388
+ return await this.selectAndExecuteBest(order, bids);
17389
+ } catch (err) {
17390
+ console.warn(
17391
+ `[IntentGateway] autoSelect: bid selection failed this round, continuing to poll: ${err instanceof Error ? err.message : String(err)}`
17392
+ );
17393
+ return void 0;
16896
17394
  }
16897
17395
  }
16898
17396
  /**
@@ -16948,10 +17446,52 @@ var IntentGateway = class _IntentGateway {
16948
17446
  return this.bidManager.prepareSubmitBid(options);
16949
17447
  }
16950
17448
  /**
16951
- * Selects the best available bid, simulates it, and submits the UserOperation
16952
- * to the bundler.
17449
+ * Decodes raw filler bids into first-class {@link Bid} objects that can be
17450
+ * ranked, simulated, and executed by the consumer.
17451
+ *
17452
+ * Delegates to {@link BidManager.buildBids}.
17453
+ *
17454
+ * @param order - The placed order the bids are competing to fill.
17455
+ * @param bids - Raw filler bids fetched from the coprocessor.
17456
+ * @param sessionPrivateKey - Optional session key override; looked up from
17457
+ * storage by `order.session` if omitted.
17458
+ * @returns Array of executable {@link Bid} objects.
17459
+ */
17460
+ buildBids(order, bids, sessionPrivateKey) {
17461
+ return this.bidManager.buildBids(order, bids, sessionPrivateKey);
17462
+ }
17463
+ /**
17464
+ * Sorts bids by output value using the same strategy the autopilot uses.
17465
+ *
17466
+ * Delegates to {@link BidManager.sortBids}.
17467
+ *
17468
+ * @param order - The placed order whose output spec drives sorting.
17469
+ * @param bids - Bids to sort (from {@link buildBids}).
17470
+ * @returns Sorted array of {@link Bid} objects.
17471
+ */
17472
+ async sortBids(order, bids) {
17473
+ return this.bidManager.sortBids(order, bids);
17474
+ }
17475
+ /**
17476
+ * Autopilot bid selection: sorts the given bids, simulates each until one
17477
+ * passes, then executes it.
17478
+ *
17479
+ * Delegates to {@link BidManager.selectAndExecuteBest}.
17480
+ *
17481
+ * @param order - The placed order to fill.
17482
+ * @param bids - Candidate bids (from {@link buildBids}).
17483
+ * @returns A {@link SelectBidResult} with the submitted UserOperation, hashes,
17484
+ * and fill status.
17485
+ */
17486
+ async selectAndExecuteBest(order, bids) {
17487
+ return this.bidManager.selectAndExecuteBest(order, bids);
17488
+ }
17489
+ /**
17490
+ * Decodes, sorts, simulates, signs, and submits the best of the given raw
17491
+ * filler bids with no per-bid input from the caller.
16953
17492
  *
16954
- * Delegates to {@link BidManager.selectBid}.
17493
+ * Delegates to {@link BidManager.selectBid}. Prefer {@link buildBids} +
17494
+ * {@link selectAndExecuteBest} (or {@link executeBest}) for new code.
16955
17495
  *
16956
17496
  * @param order - The placed order to fill.
16957
17497
  * @param bids - Raw filler bids fetched from the coprocessor.
@@ -17871,7 +18411,7 @@ var HyperFungibleTokenABI = [
17871
18411
  internalType: "uint256"
17872
18412
  }
17873
18413
  ],
17874
- stateMutability: "view"
18414
+ stateMutability: "nonpayable"
17875
18415
  },
17876
18416
  {
17877
18417
  type: "function",
@@ -17922,7 +18462,7 @@ var HyperFungibleTokenABI = [
17922
18462
  internalType: "uint256"
17923
18463
  }
17924
18464
  ],
17925
- stateMutability: "view"
18465
+ stateMutability: "nonpayable"
17926
18466
  },
17927
18467
  {
17928
18468
  type: "function",
@@ -17973,7 +18513,7 @@ var HyperFungibleTokenABI = [
17973
18513
  internalType: "uint256"
17974
18514
  }
17975
18515
  ],
17976
- stateMutability: "view"
18516
+ stateMutability: "nonpayable"
17977
18517
  },
17978
18518
  {
17979
18519
  type: "function",
@@ -18992,7 +19532,7 @@ var WrappedHyperFungibleTokenABI = [
18992
19532
  internalType: "uint256"
18993
19533
  }
18994
19534
  ],
18995
- stateMutability: "view"
19535
+ stateMutability: "nonpayable"
18996
19536
  },
18997
19537
  {
18998
19538
  type: "function",
@@ -19043,7 +19583,7 @@ var WrappedHyperFungibleTokenABI = [
19043
19583
  internalType: "uint256"
19044
19584
  }
19045
19585
  ],
19046
- stateMutability: "view"
19586
+ stateMutability: "nonpayable"
19047
19587
  },
19048
19588
  {
19049
19589
  type: "function",
@@ -19094,7 +19634,7 @@ var WrappedHyperFungibleTokenABI = [
19094
19634
  internalType: "uint256"
19095
19635
  }
19096
19636
  ],
19097
- stateMutability: "view"
19637
+ stateMutability: "nonpayable"
19098
19638
  },
19099
19639
  {
19100
19640
  type: "function",
@@ -19636,13 +20176,13 @@ var HyperFungibleToken = class {
19636
20176
  };
19637
20177
  let totalNativeCost = 0n;
19638
20178
  try {
19639
- totalNativeCost = await this.source.client.readContract({
20179
+ const { result } = await this.source.client.simulateContract({
19640
20180
  address: params.token,
19641
20181
  abi: HyperFungibleTokenABI,
19642
20182
  functionName: "quote",
19643
20183
  args: [sendParams]
19644
20184
  });
19645
- totalNativeCost = totalNativeCost * 101n / 100n;
20185
+ totalNativeCost = result * 101n / 100n;
19646
20186
  } catch {
19647
20187
  }
19648
20188
  return {
@@ -21550,6 +22090,6 @@ async function teleportDot(param_) {
21550
22090
  return stream;
21551
22091
  }
21552
22092
 
21553
- 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, 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 };
22093
+ 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 };
21554
22094
  //# sourceMappingURL=index.js.map
21555
22095
  //# sourceMappingURL=index.js.map