@hyperbridge/sdk 2.2.0 → 2.2.3

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
  };
@@ -10224,26 +10262,27 @@ var PostRequestClient = class {
10224
10262
  * accompanying timeout-proof calldata.
10225
10263
  */
10226
10264
  async addTimeoutFinalityEvents(request) {
10227
- const destChain = this.ctx.config.dest;
10228
- const hyperbridge = this.ctx.config.hyperbridge;
10229
10265
  const events = [];
10230
- const commitment = postRequestCommitment(request).commitment;
10231
- const receipt = await destChain.queryRequestReceipt(commitment);
10232
- const destTimestamp = await destChain.timestamp();
10233
10266
  const commit = (req) => {
10234
10267
  this.logger.trace(`Added ${events.length} timeout events`, events);
10235
10268
  request.statuses = [...req.statuses, ...events];
10236
10269
  return request;
10237
10270
  };
10238
10271
  if (request.timeoutTimestamp === 0n) return commit(request);
10272
+ if (request.statuses.some(
10273
+ (item) => item.status === RequestStatus.DESTINATION || item.status === TimeoutStatus.TIMED_OUT
10274
+ ))
10275
+ return commit(request);
10276
+ const destChain = this.ctx.config.dest;
10277
+ const hyperbridge = this.ctx.config.hyperbridge;
10278
+ const commitment = postRequestCommitment(request).commitment;
10279
+ const receipt = await destChain.queryRequestReceipt(commitment);
10280
+ const destTimestamp = await destChain.timestamp();
10239
10281
  if (receipt || request.timeoutTimestamp > destTimestamp) return commit(request);
10240
- const is_finished = request.statuses.find((item) => item.status === RequestStatus.DESTINATION);
10241
- if (!is_finished) {
10242
- events.push({
10243
- status: TimeoutStatus.PENDING_TIMEOUT,
10244
- metadata: { blockHash: "0x", blockNumber: 0, transactionHash: "0x" }
10245
- });
10246
- }
10282
+ events.push({
10283
+ status: TimeoutStatus.PENDING_TIMEOUT,
10284
+ metadata: { blockHash: "0x", blockNumber: 0, transactionHash: "0x" }
10285
+ });
10247
10286
  const delivered = request.statuses.find((item) => item.status === RequestStatus.HYPERBRIDGE_DELIVERED);
10248
10287
  let hyperbridgeFinalized;
10249
10288
  if (!delivered) {
@@ -10534,6 +10573,40 @@ var PostRequestClient = class {
10534
10573
  async buildFinalized(request, hyperbridgeDelivered) {
10535
10574
  const destChain = this.ctx.config.dest;
10536
10575
  const hyperbridge = this.ctx.config.hyperbridge;
10576
+ const { config } = hyperbridge;
10577
+ const finality = await this.queries.queryStateMachineUpdateByHeight({
10578
+ statemachineId: config.stateMachineId,
10579
+ height: hyperbridgeDelivered.metadata.blockNumber,
10580
+ chain: config.stateMachineId
10581
+ });
10582
+ if (finality) {
10583
+ const proof = await hyperbridge.queryProof(
10584
+ { Requests: [postRequestCommitment(request).commitment] },
10585
+ request.dest,
10586
+ BigInt(finality.height)
10587
+ );
10588
+ const calldata = destChain.encode({
10589
+ kind: "PostRequest",
10590
+ proof: {
10591
+ stateMachine: config.stateMachineId,
10592
+ consensusStateId: config.consensusStateId,
10593
+ proof,
10594
+ height: BigInt(finality.height)
10595
+ },
10596
+ requests: [request],
10597
+ signer: pad("0x")
10598
+ });
10599
+ return {
10600
+ status: RequestStatus.HYPERBRIDGE_FINALIZED,
10601
+ metadata: {
10602
+ blockHash: finality.blockHash,
10603
+ blockNumber: finality.height,
10604
+ transactionHash: finality.transactionHash,
10605
+ timestamp: finality.timestamp,
10606
+ calldata
10607
+ }
10608
+ };
10609
+ }
10537
10610
  if (destChain instanceof EvmChain) {
10538
10611
  const hyperbridgeSubstrate = hyperbridge;
10539
10612
  const currentEpoch = await destChain.currentEpoch();
@@ -10542,18 +10615,18 @@ var PostRequestClient = class {
10542
10615
  currentEpoch
10543
10616
  );
10544
10617
  if (!consensusResult) return void 0;
10545
- const proof2 = await hyperbridge.queryProof(
10618
+ const proof = await hyperbridge.queryProof(
10546
10619
  { Requests: [postRequestCommitment(request).commitment] },
10547
10620
  request.dest,
10548
10621
  consensusResult.provenHeight
10549
10622
  );
10550
- const calldata2 = destChain.encode({
10623
+ const calldata = destChain.encode({
10551
10624
  kind: "BatchConsensusAndPostRequest",
10552
10625
  consensusProofs: consensusResult.proofs,
10553
10626
  proof: {
10554
- stateMachine: this.ctx.config.hyperbridge.config.stateMachineId,
10555
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10556
- proof: proof2,
10627
+ stateMachine: config.stateMachineId,
10628
+ consensusStateId: config.consensusStateId,
10629
+ proof,
10557
10630
  height: consensusResult.provenHeight
10558
10631
  },
10559
10632
  requests: [request],
@@ -10567,42 +10640,11 @@ var PostRequestClient = class {
10567
10640
  transactionHash: hyperbridgeDelivered.metadata.transactionHash,
10568
10641
  // @ts-ignore
10569
10642
  timestamp: hyperbridgeDelivered.metadata.timestamp,
10570
- calldata: calldata2
10643
+ calldata
10571
10644
  }
10572
10645
  };
10573
10646
  }
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
- };
10647
+ return void 0;
10606
10648
  }
10607
10649
  /**
10608
10650
  * Streaming helper: waits for the consensus proof, fetches the messaging
@@ -10616,14 +10658,19 @@ var PostRequestClient = class {
10616
10658
  const stateMachineId = this.ctx.config.hyperbridge.config.stateMachineId;
10617
10659
  const neededHeight = BigInt(request.statuses[hyperbridgeDeliveredIndex].metadata.blockNumber);
10618
10660
  this.logger.trace(`[streamFinalized] neededHeight=${neededHeight}`);
10619
- if (destChain instanceof EvmChain) {
10661
+ const commitment = postRequestCommitment(request).commitment;
10662
+ let finality = await this.queries.queryStateMachineUpdateByHeight({
10663
+ statemachineId: stateMachineId,
10664
+ height: Number(neededHeight),
10665
+ chain: stateMachineId
10666
+ });
10667
+ if (!finality && destChain instanceof EvmChain) {
10620
10668
  const hyperbridgeSubstrate = hyperbridge;
10621
10669
  const currentEpoch = await destChain.currentEpoch();
10622
10670
  const consensusResult = await waitOrAbort(this.ctx, {
10623
10671
  signal,
10624
10672
  promise: () => hyperbridgeSubstrate.queryConsensusProofs(neededHeight, currentEpoch)
10625
10673
  });
10626
- const commitment = postRequestCommitment(request).commitment;
10627
10674
  this.logger.trace(
10628
10675
  `[streamFinalized] consensusProofs found (${consensusResult.proofs.length} proofs), provenHeight=${consensusResult.provenHeight}, commitment=${commitment}, dest=${request.dest}`
10629
10676
  );
@@ -10655,45 +10702,45 @@ var PostRequestClient = class {
10655
10702
  }
10656
10703
  };
10657
10704
  }
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
- });
10705
+ if (!finality) {
10706
+ finality = await waitOrAbort(this.ctx, {
10707
+ signal,
10708
+ promise: () => this.queries.queryStateMachineUpdateByHeight({
10709
+ statemachineId: stateMachineId,
10710
+ height: Number(neededHeight),
10711
+ chain: stateMachineId
10712
+ })
10713
+ });
10714
+ }
10666
10715
  const proof = await this.fetchProofWithRetry(
10667
10716
  signal,
10668
- () => hyperbridge.queryProof(
10669
- { Requests: [postRequestCommitment(request).commitment] },
10670
- request.dest,
10671
- BigInt(hyperbridgeFinalized.height)
10672
- )
10717
+ () => hyperbridge.queryProof({ Requests: [commitment] }, request.dest, BigInt(finality.height))
10673
10718
  );
10719
+ if (!(destChain instanceof EvmChain)) {
10720
+ const { stateId } = parseStateMachineId(stateMachineId);
10721
+ await waitForChallengePeriod(destChain, {
10722
+ height: BigInt(finality.height),
10723
+ id: { stateId, consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId }
10724
+ });
10725
+ }
10674
10726
  const calldata = destChain.encode({
10675
10727
  kind: "PostRequest",
10676
10728
  proof: {
10677
10729
  stateMachine: stateMachineId,
10678
10730
  consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10679
10731
  proof,
10680
- height: BigInt(hyperbridgeFinalized.height)
10732
+ height: BigInt(finality.height)
10681
10733
  },
10682
10734
  requests: [request],
10683
10735
  signer: pad("0x")
10684
10736
  });
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
10737
  return {
10691
10738
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10692
10739
  metadata: {
10693
- blockHash: hyperbridgeFinalized.blockHash,
10694
- blockNumber: hyperbridgeFinalized.height,
10695
- transactionHash: hyperbridgeFinalized.transactionHash,
10696
- timestamp: hyperbridgeFinalized.timestamp,
10740
+ blockHash: finality.blockHash,
10741
+ blockNumber: finality.height,
10742
+ transactionHash: finality.transactionHash,
10743
+ timestamp: finality.timestamp,
10697
10744
  calldata
10698
10745
  }
10699
10746
  };
@@ -14616,6 +14663,7 @@ function orderCommitment(order) {
14616
14663
  return keccak256(encoded);
14617
14664
  }
14618
14665
  async function convertGasToFeeToken(ctx, gasEstimate, gasEstimateIn, evmChainID, gasPriceOverride) {
14666
+ if (TESTNET_CHAINS.has(evmChainID)) return 1n;
14619
14667
  const chain = ctx[gasEstimateIn];
14620
14668
  const client = chain.client;
14621
14669
  const gasPrice = gasPriceOverride ?? await retryPromise(() => client.getGasPrice(), {
@@ -14650,6 +14698,7 @@ async function convertGasToFeeToken(ctx, gasEstimate, gasEstimateIn, evmChainID,
14650
14698
  }
14651
14699
  }
14652
14700
  async function convertFeeTokenToWei(ctx, feeTokenAmount, feeTokenIn, evmChainID) {
14701
+ if (TESTNET_CHAINS.has(evmChainID)) return 1n;
14653
14702
  const chain = ctx[feeTokenIn];
14654
14703
  const client = chain.client;
14655
14704
  const wethAddr = chain.configService.getWrappedNativeAssetWithDecimals(evmChainID).asset;
@@ -14765,16 +14814,16 @@ var OrderPlacer = class {
14765
14814
  return { order, receipt };
14766
14815
  }
14767
14816
  };
14817
+
14818
+ // src/protocols/intents/OrderExecutor.ts
14768
14819
  var USED_USEROPS_STORAGE_KEY = (commitment) => `used-userops:${commitment.toLowerCase()}`;
14769
14820
  var OrderExecutor = class {
14770
- constructor(ctx, bidManager, crypto) {
14821
+ constructor(ctx, bidManager) {
14771
14822
  this.ctx = ctx;
14772
14823
  this.bidManager = bidManager;
14773
- this.crypto = crypto;
14774
14824
  }
14775
14825
  ctx;
14776
14826
  bidManager;
14777
- crypto;
14778
14827
  /**
14779
14828
  * Sleeps until the order's block deadline is reached, then yields EXPIRED.
14780
14829
  * Uses the chain's block time to calculate the sleep duration.
@@ -14845,17 +14894,6 @@ var OrderExecutor = class {
14845
14894
  }
14846
14895
  return fetchedBids;
14847
14896
  }
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
14897
  /**
14860
14898
  * Processes a fill result and returns updated fill accumulators,
14861
14899
  * the status update to yield (if any), and whether the order is
@@ -14923,7 +14961,15 @@ var OrderExecutor = class {
14923
14961
  }
14924
14962
  /**
14925
14963
  * Executes an intent order by racing bid polling against the order's
14926
- * block deadline. Yields status updates at each lifecycle stage.
14964
+ * block deadline. Yields status updates at each lifecycle stage and hands
14965
+ * bid selection to the consumer.
14966
+ *
14967
+ * This is a **bidirectional** generator: when it yields `BIDS_RECEIVED`, the
14968
+ * consumer picks a bid, calls `bid.execute()`, and feeds the resulting
14969
+ * {@link SelectBidResult} back via `gen.next(result)`. The generator then
14970
+ * records the dedup entry, emits `BID_SELECTED`, tracks the fill, and either
14971
+ * terminates or continues polling for the remaining amount. Feeding back
14972
+ * `undefined` (no bid executed this round) causes it to keep polling.
14927
14973
  *
14928
14974
  * **Same-chain:** `AWAITING_BIDS` → `BIDS_RECEIVED` → `BID_SELECTED`
14929
14975
  * → (`FILLED` | `PARTIAL_FILL`)* → (`FILLED` | `EXPIRED`)
@@ -14934,7 +14980,6 @@ var OrderExecutor = class {
14934
14980
  async *executeOrder(options) {
14935
14981
  const { order, sessionPrivateKey, auctionTimeMs, pollIntervalMs = DEFAULT_POLL_INTERVAL, solver } = options;
14936
14982
  const commitment = order.id;
14937
- order.source === order.destination;
14938
14983
  if (!this.ctx.intentsCoprocessor) {
14939
14984
  yield { status: "FAILED", error: "IntentsCoprocessor required for order execution" };
14940
14985
  return;
@@ -14962,11 +15007,24 @@ var OrderExecutor = class {
14962
15007
  remainingAssets
14963
15008
  });
14964
15009
  const deadlineTimeout = this.deadlineStream(order.deadline, commitment);
14965
- const combined = mergeRace(deadlineTimeout, executionStream);
15010
+ const deadlinePromise = deadlineTimeout.next();
14966
15011
  try {
14967
- for await (const update of combined) {
14968
- yield update;
14969
- if (update.status === "EXPIRED" || update.status === "FILLED") return;
15012
+ let input;
15013
+ while (true) {
15014
+ const winner = input !== void 0 ? { from: "exec", r: await executionStream.next(input) } : await Promise.race([
15015
+ executionStream.next(void 0).then((r) => ({ from: "exec", r })),
15016
+ deadlinePromise.then((r) => ({ from: "deadline", r }))
15017
+ ]);
15018
+ input = void 0;
15019
+ if (winner.from === "deadline") {
15020
+ if (!winner.r.done && winner.r.value) yield winner.r.value;
15021
+ return;
15022
+ }
15023
+ const { value, done } = winner.r;
15024
+ if (done) return;
15025
+ const fed = yield value;
15026
+ if (value.status === "BIDS_RECEIVED") input = fed;
15027
+ if (value.status === "EXPIRED" || value.status === "FILLED") return;
14970
15028
  }
14971
15029
  } finally {
14972
15030
  console.log(`[OrderExecutor] Tearing down streams for commitment=${commitment}`);
@@ -14975,9 +15033,16 @@ var OrderExecutor = class {
14975
15033
  }
14976
15034
  }
14977
15035
  /**
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.
15036
+ * Core execution loop that polls for bids and tracks fill progress. Builds
15037
+ * first-class {@link Bid} objects from the raw filler bids and yields them to
15038
+ * the consumer, which picks one, calls `bid.execute()`, and feeds the result
15039
+ * back via `gen.next(result)`. The loop then records the dedup entry, emits
15040
+ * `BID_SELECTED`, processes the fill, and continues polling for the remaining
15041
+ * amount on partial fills.
15042
+ *
15043
+ * Bidirectional: the value passed to `.next()` after a `BIDS_RECEIVED` yield is
15044
+ * the {@link SelectBidResult} from the executed bid (or `undefined` to skip the
15045
+ * round and keep polling).
14981
15046
  */
14982
15047
  async *executionStream(params) {
14983
15048
  const {
@@ -14992,12 +15057,7 @@ var OrderExecutor = class {
14992
15057
  targetAssets
14993
15058
  } = params;
14994
15059
  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
- };
15060
+ const isFreshBid = (bid) => !usedUserOps.has(userOpHashKey(bid.userOp));
15001
15061
  const solverLockStartTime = Date.now();
15002
15062
  yield { status: "AWAITING_BIDS", commitment, totalFilledAssets, remainingAssets };
15003
15063
  try {
@@ -15006,13 +15066,13 @@ var OrderExecutor = class {
15006
15066
  while (Date.now() < auctionEnd) {
15007
15067
  try {
15008
15068
  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 };
15069
+ const newBids = bids.filter(
15070
+ (bid) => isFreshBid(bid) && !auctionSeenBids.has(userOpHashKey(bid.userOp))
15071
+ );
15072
+ for (const fillerBid of newBids) {
15073
+ auctionSeenBids.add(userOpHashKey(fillerBid.userOp));
15074
+ const [bid] = this.bidManager.buildBids(order, [fillerBid], sessionPrivateKey);
15075
+ if (bid) yield { status: "NEW_BID", commitment, bid };
15016
15076
  }
15017
15077
  } catch {
15018
15078
  }
@@ -15024,8 +15084,8 @@ var OrderExecutor = class {
15024
15084
  while (true) {
15025
15085
  let freshBids;
15026
15086
  try {
15027
- const bids = await this.fetchBids({ commitment, solver, solverLockStartTime });
15028
- freshBids = bids.filter(isFreshBid);
15087
+ const bids2 = await this.fetchBids({ commitment, solver, solverLockStartTime });
15088
+ freshBids = bids2.filter(isFreshBid);
15029
15089
  } catch {
15030
15090
  await sleep(pollIntervalMs);
15031
15091
  continue;
@@ -15034,56 +15094,33 @@ var OrderExecutor = class {
15034
15094
  await sleep(pollIntervalMs);
15035
15095
  continue;
15036
15096
  }
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
- }
15097
+ const bids = this.bidManager.buildBids(order, freshBids, sessionPrivateKey);
15098
+ if (bids.length === 0) {
15099
+ await sleep(pollIntervalMs);
15100
+ continue;
15101
+ }
15102
+ const result = yield { status: "BIDS_RECEIVED", commitment, bidCount: bids.length, bids };
15103
+ if (!result) {
15064
15104
  await sleep(pollIntervalMs);
15065
15105
  continue;
15066
15106
  }
15107
+ usedUserOps.add(userOpHashKey(result.userOp));
15108
+ await this.persistUsedUserOps(commitment, usedUserOps);
15067
15109
  yield {
15068
15110
  status: "BID_SELECTED",
15069
15111
  commitment,
15070
- selectedSolver: submitResult.solverAddress,
15071
- userOpHash: submitResult.userOpHash,
15072
- userOp: submitResult.userOp,
15073
- transactionHash: submitResult.txnHash
15112
+ selectedSolver: result.solverAddress,
15113
+ userOpHash: result.userOpHash,
15114
+ userOp: result.userOp,
15115
+ transactionHash: result.txnHash
15074
15116
  };
15075
- const fill = this.processFillResult(
15076
- submitResult,
15077
- commitment,
15078
- targetAssets,
15079
- totalFilledAssets,
15080
- remainingAssets
15081
- );
15117
+ const fill = this.processFillResult(result, commitment, targetAssets, totalFilledAssets, remainingAssets);
15082
15118
  totalFilledAssets = fill.totalFilledAssets;
15083
15119
  remainingAssets = fill.remainingAssets;
15084
15120
  if (fill.update) {
15085
15121
  yield fill.update;
15086
15122
  }
15123
+ if (fill.done) return;
15087
15124
  }
15088
15125
  } catch (err) {
15089
15126
  yield {
@@ -15558,183 +15595,148 @@ var OrderCanceller = class {
15558
15595
  return feeInDestFeeToken * 1005n / 1000n;
15559
15596
  }
15560
15597
  };
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
- }
15598
+ var BidImpl = class {
15599
+ solverAddress;
15600
+ outputs;
15601
+ relayerFee;
15602
+ nativeDispatchFee;
15603
+ userOp;
15572
15604
  ctx;
15573
15605
  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(
15606
+ order;
15607
+ fillOptions;
15608
+ priceOutputs;
15609
+ sessionPrivateKey;
15610
+ intentGatewayV2Address;
15611
+ domainSeparator;
15612
+ /** Cached session-key signature over the `SelectSolver` message. */
15613
+ cachedSignature;
15614
+ constructor(params) {
15615
+ this.ctx = params.ctx;
15616
+ this.crypto = params.crypto;
15617
+ this.order = params.order;
15618
+ this.fillOptions = params.fillOptions;
15619
+ this.priceOutputs = params.priceOutputs;
15620
+ this.sessionPrivateKey = params.sessionPrivateKey;
15621
+ this.solverAddress = params.fillerBid.userOp.sender;
15622
+ this.outputs = params.fillOptions.outputs;
15623
+ this.relayerFee = params.fillOptions.relayerFee;
15624
+ this.nativeDispatchFee = params.fillOptions.nativeDispatchFee;
15625
+ this.userOp = params.fillerBid.userOp;
15626
+ this.intentGatewayV2Address = this.ctx.dest.configService.getIntentGatewayAddress(
15627
+ normalizeStateMachineId(this.order.destination)
15628
+ );
15629
+ this.domainSeparator = CryptoUtils.getDomainSeparator(
15630
+ "IntentGateway",
15631
+ "2",
15632
+ this.chainId(),
15633
+ this.intentGatewayV2Address
15634
+ );
15635
+ }
15636
+ /** Resolves the destination chain id from the client or the state-machine id. */
15637
+ chainId() {
15638
+ return BigInt(
15603
15639
  this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15604
15640
  );
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
15641
  }
15625
15642
  /**
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.
15629
- *
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.
15643
+ * Resolves the session key, signs the `SelectSolver` message for this bid's
15644
+ * solver, and caches the signature. Signs at most once per bid.
15639
15645
  *
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.
15646
+ * @throws If the session key is missing or signing fails.
15648
15647
  */
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);
15648
+ async signSelection() {
15649
+ if (this.cachedSignature) return this.cachedSignature;
15650
+ const commitment = this.order.id;
15651
+ const sessionKeyAddress = this.order.session;
15652
+ const sessionKeyData = this.sessionPrivateKey ? { privateKey: this.sessionPrivateKey } : await this.ctx.sessionKeyStorage.getSessionKeyByAddress(sessionKeyAddress);
15654
15653
  if (!sessionKeyData) {
15655
15654
  throw new Error("SessionKey not found for commitment: " + commitment);
15656
15655
  }
15657
- if (!this.ctx.bundlerUrl) {
15658
- throw new Error("Bundler URL not configured");
15656
+ const signature = await CryptoUtils.signSolverSelection(
15657
+ commitment,
15658
+ this.solverAddress,
15659
+ this.domainSeparator,
15660
+ sessionKeyData.privateKey
15661
+ );
15662
+ if (!signature) {
15663
+ throw new Error("Failed to sign solver selection");
15659
15664
  }
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
15665
+ this.cachedSignature = signature;
15666
+ return signature;
15667
+ }
15668
+ /**
15669
+ * Simulates this bid on-chain by batching the `select` and `fillOrder` calls
15670
+ * via `eth_call` from the solver's account, using the IntentGatewayV2 ERC-7821
15671
+ * batch-execute pattern.
15672
+ *
15673
+ * The native value forwarded to the simulation is the sum of any native-token
15674
+ * (`address(0)`) output amounts plus the Hyperbridge dispatch fee.
15675
+ *
15676
+ * @throws If the `eth_call` simulation reverts or errors.
15677
+ */
15678
+ async simulate() {
15679
+ const signature = await this.signSelection();
15680
+ const selectOptions = {
15681
+ commitment: this.order.id,
15682
+ solver: this.solverAddress,
15683
+ signature
15684
+ };
15685
+ const nativeOutputs = this.fillOptions.outputs.reduce(
15686
+ (acc, o) => bytes32ToBytes20(o.token) === ADDRESS_ZERO2 ? acc + o.amount : acc,
15687
+ 0n
15678
15688
  );
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
- }
15689
+ const simulationValue = nativeOutputs + this.fillOptions.nativeDispatchFee;
15690
+ const selectCalldata = encodeFunctionData({
15691
+ abi: ABI3,
15692
+ functionName: "select",
15693
+ args: [selectOptions]
15694
+ });
15695
+ const calls = [
15696
+ { target: this.intentGatewayV2Address, value: 0n, data: selectCalldata },
15697
+ { target: this.solverAddress, value: simulationValue, data: this.userOp.callData }
15698
+ ];
15699
+ const batchedCalldata = this.crypto.encodeERC7821Execute(calls);
15700
+ try {
15701
+ await this.ctx.dest.client.call({
15702
+ account: this.solverAddress,
15703
+ to: this.solverAddress,
15704
+ data: batchedCalldata,
15705
+ value: simulationValue
15706
+ });
15707
+ } catch (e) {
15708
+ throw new Error(`Simulation failed: ${e instanceof Error ? e.message : String(e)}`);
15713
15709
  }
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");
15710
+ }
15711
+ /**
15712
+ * Signs the `SelectSolver` message with the session key, appends it to the
15713
+ * solver's existing UserOp signature, and submits the UserOperation to the
15714
+ * bundler. For same-chain orders, waits for the receipt and reads
15715
+ * `OrderFilled` / `PartialFill` logs to determine fill status.
15716
+ *
15717
+ * @returns A {@link SelectBidResult} with the submitted UserOperation, its hash,
15718
+ * the solver address, transaction hash, and fill status.
15719
+ * @throws If the bundler is not configured, the session key is missing, or the
15720
+ * bundler rejects the UserOperation.
15721
+ */
15722
+ async execute() {
15723
+ const commitment = this.order.id;
15724
+ if (!this.ctx.bundlerUrl) {
15725
+ throw new Error("Bundler URL not configured");
15717
15726
  }
15718
- const solverAddress = selectedBid.bid.userOp.sender;
15719
- const finalSignature = concat([
15720
- selectedBid.bid.userOp.signature,
15721
- sessionSignature
15722
- ]);
15727
+ const sessionSignature = await this.signSelection();
15728
+ const finalSignature = concat([this.userOp.signature, sessionSignature]);
15723
15729
  const signedUserOp = {
15724
- ...selectedBid.bid.userOp,
15730
+ ...this.userOp,
15725
15731
  signature: finalSignature
15726
15732
  };
15727
15733
  const entryPointAddress = this.ctx.dest.configService.getEntryPointV08Address(
15728
- normalizeStateMachineId(order.destination)
15734
+ normalizeStateMachineId(this.order.destination)
15729
15735
  );
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, [
15736
+ const userOpHash = await this.crypto.sendBundler(BundlerMethod.ETH_SEND_USER_OPERATION, [
15734
15737
  CryptoUtils.prepareBundlerCall(signedUserOp),
15735
15738
  entryPointAddress
15736
15739
  ]);
15737
- const userOpHash = bundlerResult;
15738
15740
  let txnHash;
15739
15741
  let fillStatus;
15740
15742
  let filledAssets;
@@ -15750,7 +15752,7 @@ var BidManager = class {
15750
15752
  { maxRetries: 5, backoffMs: 2e3, logMessage: "Fetching user operation receipt" }
15751
15753
  );
15752
15754
  txnHash = receipt.receipt.transactionHash;
15753
- if (order.source === order.destination) {
15755
+ if (this.order.source === this.order.destination) {
15754
15756
  try {
15755
15757
  const chainReceipt = await this.ctx.dest.client.waitForTransactionReceipt({
15756
15758
  hash: txnHash,
@@ -15779,12 +15781,12 @@ var BidManager = class {
15779
15781
  }
15780
15782
  }
15781
15783
  } catch (err) {
15782
- throw new Error(`Failed to select bid: ${err instanceof Error ? err.message : String(err)}`);
15784
+ throw new Error(`Failed to execute bid: ${err instanceof Error ? err.message : String(err)}`);
15783
15785
  }
15784
15786
  return {
15785
15787
  userOp: signedUserOp,
15786
15788
  userOpHash,
15787
- solverAddress,
15789
+ solverAddress: this.solverAddress,
15788
15790
  commitment,
15789
15791
  txnHash,
15790
15792
  fillStatus,
@@ -15792,7 +15794,177 @@ var BidManager = class {
15792
15794
  };
15793
15795
  }
15794
15796
  /**
15795
- * Validates and sorts a list of raw bids for the given order.
15797
+ * Prices this bid's outputs in USD using the destination chain's DEX-quote
15798
+ * helpers. Returns `null` when any output token cannot be priced.
15799
+ */
15800
+ async outputUsdValue() {
15801
+ return this.priceOutputs(this.outputs);
15802
+ }
15803
+ };
15804
+ var BidManager = class {
15805
+ /**
15806
+ * @param ctx - Shared IntentsV2 context providing the destination chain
15807
+ * client, coprocessor, bundler URL, and session-key storage.
15808
+ * @param crypto - Crypto utilities used for gas packing, UserOp hashing,
15809
+ * EIP-712 signing, and bundler calls.
15810
+ */
15811
+ constructor(ctx, crypto) {
15812
+ this.ctx = ctx;
15813
+ this.crypto = crypto;
15814
+ }
15815
+ ctx;
15816
+ crypto;
15817
+ /**
15818
+ * Constructs a signed `PackedUserOperation` that a solver can submit to the
15819
+ * Hyperbridge coprocessor as a bid to fill an order.
15820
+ *
15821
+ * The solver's signature covers a hash that binds the UserOperation to the
15822
+ * order commitment and the session key address, so the IntentGatewayV2
15823
+ * contract can verify the solver's intent on-chain.
15824
+ *
15825
+ * @param options - Parameters describing the solver account, gas limits, fee
15826
+ * market values, and pre-built `callData` for the fill operation.
15827
+ * @returns A `PackedUserOperation` with the solver's signature prepended
15828
+ * with the order commitment.
15829
+ */
15830
+ async prepareSubmitBid(options) {
15831
+ const {
15832
+ order,
15833
+ solverAccount,
15834
+ solverSigner,
15835
+ nonce,
15836
+ entryPointAddress,
15837
+ callGasLimit,
15838
+ verificationGasLimit,
15839
+ preVerificationGas,
15840
+ maxFeePerGas,
15841
+ maxPriorityFeePerGas,
15842
+ callData,
15843
+ paymasterAndData = "0x"
15844
+ } = options;
15845
+ const chainId = BigInt(
15846
+ this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15847
+ );
15848
+ const accountGasLimits = CryptoUtils.packGasLimits(verificationGasLimit, callGasLimit);
15849
+ const gasFees = CryptoUtils.packGasFees(maxPriorityFeePerGas, maxFeePerGas);
15850
+ const userOp = {
15851
+ sender: solverAccount,
15852
+ nonce,
15853
+ initCode: "0x",
15854
+ callData,
15855
+ accountGasLimits,
15856
+ preVerificationGas,
15857
+ gasFees,
15858
+ paymasterAndData,
15859
+ signature: "0x"
15860
+ };
15861
+ const userOpHash = CryptoUtils.computeUserOpHash(userOp, entryPointAddress, chainId);
15862
+ const sessionKey = order.session;
15863
+ const messageHash = keccak256(concat([userOpHash, order.id, sessionKey]));
15864
+ const solverSignature = await solverSigner.signMessage(messageHash, Number(chainId));
15865
+ const signature = concat([order.id, solverSignature]);
15866
+ return { ...userOp, signature };
15867
+ }
15868
+ /**
15869
+ * Decodes raw filler bids into first-class {@link Bid} objects.
15870
+ *
15871
+ * Each bid's `fillOrder` fill-options are decoded from its ERC-7821 calldata;
15872
+ * bids whose calldata cannot be decoded into a valid `fillOrder` call are
15873
+ * silently dropped with a warning. The returned `Bid` instances are ready to
15874
+ * be ranked, simulated, and executed by the consumer.
15875
+ *
15876
+ * @param order - The placed order the bids are competing to fill.
15877
+ * @param bids - Raw filler bids fetched from the coprocessor.
15878
+ * @param sessionPrivateKey - Optional session-key override; looked up from
15879
+ * storage by `order.session` if omitted.
15880
+ * @returns Array of executable `Bid` objects (one per successfully decoded bid).
15881
+ */
15882
+ buildBids(order, bids, sessionPrivateKey) {
15883
+ const chainId = this.ctx.dest.config.stateMachineId;
15884
+ const priceOutputs = (outputs) => this.computeOutputsUsdValue(outputs, chainId);
15885
+ const result = [];
15886
+ for (const fillerBid of bids) {
15887
+ const fillOptions = this.decodeBidFillOptions(fillerBid);
15888
+ if (!fillOptions) {
15889
+ console.warn(`[BidManager] Failed to decode fillOptions from bid by solver=${fillerBid.userOp.sender}`);
15890
+ continue;
15891
+ }
15892
+ result.push(
15893
+ new BidImpl({
15894
+ ctx: this.ctx,
15895
+ crypto: this.crypto,
15896
+ order,
15897
+ fillerBid,
15898
+ fillOptions,
15899
+ priceOutputs,
15900
+ sessionPrivateKey
15901
+ })
15902
+ );
15903
+ }
15904
+ console.log(`[BidManager] Built ${result.length}/${bids.length} bid(s) successfully`);
15905
+ return result;
15906
+ }
15907
+ /**
15908
+ * Decodes raw filler bids, sorts them, simulates each until one passes, signs
15909
+ * the `SelectSolver` message, and submits — all with no per-bid input from the
15910
+ * caller.
15911
+ *
15912
+ * Equivalent to `selectAndExecuteBest(order, buildBids(order, bids, key))`.
15913
+ *
15914
+ * @param order - The placed order to fill.
15915
+ * @param bids - Raw filler bids fetched from the coprocessor.
15916
+ * @param sessionPrivateKey - Optional session-key override; looked up from
15917
+ * storage by `order.session` if omitted.
15918
+ * @returns A {@link SelectBidResult} for the executed bid.
15919
+ */
15920
+ async selectBid(order, bids, sessionPrivateKey) {
15921
+ return this.selectAndExecuteBest(order, this.buildBids(order, bids, sessionPrivateKey));
15922
+ }
15923
+ /**
15924
+ * Autopilot bid selection: sorts the given bids by output value, simulates
15925
+ * each in order until one passes, then executes that bid. For consumers that
15926
+ * do not need custom selection logic.
15927
+ *
15928
+ * @param order - The placed order to fill.
15929
+ * @param bids - Candidate bids (from {@link buildBids}).
15930
+ * @returns A {@link SelectBidResult} for the executed bid.
15931
+ * @throws If no valid bids exist, all simulations fail, or the bundler rejects
15932
+ * the UserOperation.
15933
+ */
15934
+ async selectAndExecuteBest(order, bids) {
15935
+ const commitment = order.id;
15936
+ console.log(`[BidManager] selectAndExecuteBest called for commitment=${commitment}, ${bids.length} bid(s)`);
15937
+ if (!this.ctx.bundlerUrl) {
15938
+ throw new Error("Bundler URL not configured");
15939
+ }
15940
+ if (!this.ctx.intentsCoprocessor) {
15941
+ throw new Error("IntentsCoprocessor required");
15942
+ }
15943
+ const sortedBids = await this.sortBids(order, bids);
15944
+ console.log(`[BidManager] ${sortedBids.length}/${bids.length} bid(s) passed validation and sorting`);
15945
+ if (sortedBids.length === 0) {
15946
+ throw new Error("No valid bids found");
15947
+ }
15948
+ console.log(`[BidManager] Simulating ${sortedBids.length} sorted bid(s) to find a valid one`);
15949
+ for (let idx = 0; idx < sortedBids.length; idx++) {
15950
+ const bid = sortedBids[idx];
15951
+ console.log(`[BidManager] Simulating bid ${idx + 1}/${sortedBids.length} from solver=${bid.solverAddress}`);
15952
+ try {
15953
+ await bid.simulate();
15954
+ } catch (err) {
15955
+ console.warn(
15956
+ `[BidManager] Bid ${idx + 1} from solver=${bid.solverAddress}: simulation FAILED: ${err instanceof Error ? err.message : String(err)}`
15957
+ );
15958
+ continue;
15959
+ }
15960
+ console.log(`[BidManager] Bid ${idx + 1} from solver=${bid.solverAddress}: simulation PASSED`);
15961
+ return bid.execute();
15962
+ }
15963
+ console.error(`[BidManager] All ${sortedBids.length} bid(s) failed simulation for commitment=${commitment}`);
15964
+ throw new Error("No bids passed simulation");
15965
+ }
15966
+ /**
15967
+ * Sorts a list of bids for the given order by output value.
15796
15968
  *
15797
15969
  * Delegates to one of three strategies based on the order's output token
15798
15970
  * composition:
@@ -15801,47 +15973,26 @@ var BidManager = class {
15801
15973
  * - Mixed outputs: sort by DEX-quoted USD value descending, with a raw-amount
15802
15974
  * fallback if pricing fails.
15803
15975
  *
15804
- * @param bids - Raw filler bids from the coprocessor.
15976
+ * Bids that cannot satisfy the order's token set are dropped.
15977
+ *
15805
15978
  * @param order - The placed order whose output spec drives sorting logic.
15806
- * @returns Sorted array of `{ bid, options }` pairs ready for simulation.
15979
+ * @param bids - Executable bids to sort (from {@link buildBids}).
15980
+ * @returns Sorted array of `Bid` objects ready for simulation.
15807
15981
  */
15808
- async validateAndSortBids(bids, order) {
15982
+ async sortBids(order, bids) {
15809
15983
  const outputs = order.output.assets;
15810
- const decodedBids = this.decodeBids(bids);
15811
15984
  if (outputs.length <= 1) {
15812
15985
  console.log(`[BidManager] Using single-output sorting (1 output asset)`);
15813
- return this.sortSingleOutput(decodedBids, outputs[0]);
15986
+ return this.sortSingleOutput(bids, outputs[0]);
15814
15987
  }
15815
15988
  const chainId = this.ctx.dest.config.stateMachineId;
15816
15989
  const allStables = outputs.every((o) => this.isStableToken(bytes32ToBytes20(o.token), chainId));
15817
15990
  if (allStables) {
15818
15991
  console.log(`[BidManager] Using all-stables sorting (${outputs.length} stable output assets)`);
15819
- return this.sortAllStables(decodedBids, outputs, chainId);
15992
+ return this.sortAllStables(bids, outputs, chainId);
15820
15993
  }
15821
15994
  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;
15995
+ return this.sortMixedOutputs(bids, outputs, chainId);
15845
15996
  }
15846
15997
  /**
15847
15998
  * Extracts the `FillOptions` struct from a single bid's ERC-7821
@@ -15874,149 +16025,103 @@ var BidManager = class {
15874
16025
  }
15875
16026
  return null;
15876
16027
  }
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
16028
  /**
15920
16029
  * Case A: single output token.
15921
16030
  * Filter bids by token match only, sort descending by amount.
15922
16031
  * Partial fill bids are allowed — the contract determines fill status.
15923
16032
  */
15924
- sortSingleOutput(decodedBids, requiredAsset) {
16033
+ sortSingleOutput(bids, requiredAsset) {
15925
16034
  const requiredAmount = new Decimal2(requiredAsset.amount.toString());
15926
16035
  console.log(
15927
16036
  `[BidManager] sortSingleOutput: required token=${requiredAsset.token}, amount=${requiredAmount.toString()}`
15928
16037
  );
15929
16038
  const validBids = [];
15930
- for (const { bid, options } of decodedBids) {
15931
- const bidOutput = options.outputs[0];
16039
+ for (const bid of bids) {
16040
+ const bidOutput = bid.outputs[0];
15932
16041
  const bidAmount = new Decimal2(bidOutput.amount.toString());
15933
16042
  if (bidOutput.token.toLowerCase() !== requiredAsset.token.toLowerCase()) {
15934
16043
  console.warn(
15935
- `[BidManager] Bid from solver=${bid.userOp.sender} REJECTED: token mismatch (bid=${bidOutput.token}, required=${requiredAsset.token})`
16044
+ `[BidManager] Bid from solver=${bid.solverAddress} REJECTED: token mismatch (bid=${bidOutput.token}, required=${requiredAsset.token})`
15936
16045
  );
15937
16046
  continue;
15938
16047
  }
15939
16048
  if (bidAmount.lt(requiredAmount)) {
15940
16049
  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)}%)`
16050
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (bid=${bidAmount.toString()}, required=${requiredAmount.toString()}, covers=${bidAmount.div(requiredAmount).mul(100).toFixed(2)}%)`
15942
16051
  );
15943
16052
  } else {
15944
16053
  console.log(
15945
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED: amount=${bidAmount.toString()} (surplus=${bidAmount.minus(requiredAmount).toString()})`
16054
+ `[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED: amount=${bidAmount.toString()} (surplus=${bidAmount.minus(requiredAmount).toString()})`
15946
16055
  );
15947
16056
  }
15948
- validBids.push({ bid, options, amount: bidOutput.amount });
16057
+ validBids.push({ bid, amount: bidOutput.amount });
15949
16058
  }
15950
16059
  validBids.sort((a, b) => {
15951
16060
  const aAmt = new Decimal2(a.amount.toString());
15952
16061
  const bAmt = new Decimal2(b.amount.toString());
15953
16062
  return bAmt.comparedTo(aAmt);
15954
16063
  });
15955
- return validBids.map(({ amount: _, ...rest }) => rest);
16064
+ return validBids.map(({ bid }) => bid);
15956
16065
  }
15957
16066
  /**
15958
16067
  * Case B: all outputs are USDC/USDT.
15959
16068
  * Sum normalised USD values (treating each stable as $1) and sort descending.
15960
16069
  * Partial fill bids are allowed.
15961
16070
  */
15962
- sortAllStables(decodedBids, orderOutputs, chainId) {
16071
+ sortAllStables(bids, orderOutputs, chainId) {
15963
16072
  const requiredUsd = this.computeStablesUsdValue(orderOutputs, chainId);
15964
16073
  console.log(`[BidManager] sortAllStables: required USD value=${requiredUsd.toString()}`);
15965
16074
  const validBids = [];
15966
- for (const { bid, options } of decodedBids) {
15967
- const bidUsd = this.computeStablesUsdValue(options.outputs, chainId);
16075
+ for (const bid of bids) {
16076
+ const bidUsd = this.computeStablesUsdValue(bid.outputs, chainId);
15968
16077
  if (bidUsd === null) {
15969
- console.warn(`[BidManager] Bid from solver=${bid.userOp.sender} REJECTED: unable to compute USD value`);
16078
+ console.warn(`[BidManager] Bid from solver=${bid.solverAddress} REJECTED: unable to compute USD value`);
15970
16079
  continue;
15971
16080
  }
15972
16081
  if (bidUsd.lt(requiredUsd)) {
15973
16082
  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)}%)`
16083
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (bid=${bidUsd.toString()}, required=${requiredUsd.toString()}, covers=${bidUsd.div(requiredUsd).mul(100).toFixed(2)}%)`
15975
16084
  );
15976
16085
  } else {
15977
- console.log(
15978
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED: USD value=${bidUsd.toString()}`
15979
- );
16086
+ console.log(`[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED: USD value=${bidUsd.toString()}`);
15980
16087
  }
15981
- validBids.push({ bid, options, usdValue: bidUsd });
16088
+ validBids.push({ bid, usdValue: bidUsd });
15982
16089
  }
15983
16090
  validBids.sort((a, b) => b.usdValue.comparedTo(a.usdValue));
15984
- return validBids.map(({ usdValue: _, ...rest }) => rest);
16091
+ return validBids.map(({ bid }) => bid);
15985
16092
  }
15986
16093
  /**
15987
16094
  * Case C: mixed output tokens (at least one non-stable).
15988
16095
  * Price every token via on-chain DEX quotes, fall back to raw amounts
15989
16096
  * if pricing is unavailable. Partial fill bids are allowed.
15990
16097
  */
15991
- async sortMixedOutputs(decodedBids, orderOutputs, chainId) {
16098
+ async sortMixedOutputs(bids, orderOutputs, chainId) {
15992
16099
  const requiredUsd = await this.computeOutputsUsdValue(orderOutputs, chainId);
15993
16100
  if (requiredUsd === null) {
15994
16101
  console.warn("[BidManager] sortMixedOutputs: output tokens unpriceable, falling back to raw-amount sort");
15995
- return this.sortByRawAmountFallback(decodedBids, orderOutputs);
16102
+ return this.sortByRawAmountFallback(bids, orderOutputs);
15996
16103
  }
15997
16104
  console.log(`[BidManager] sortMixedOutputs: required USD value=${requiredUsd.toString()}`);
15998
16105
  const validBids = [];
15999
- for (const { bid, options } of decodedBids) {
16000
- const bidUsd = await this.computeOutputsUsdValue(options.outputs, chainId);
16106
+ for (const bid of bids) {
16107
+ const bidUsd = await this.computeOutputsUsdValue(bid.outputs, chainId);
16001
16108
  if (bidUsd === null) {
16002
- console.warn(
16003
- `[BidManager] Bid from solver=${bid.userOp.sender} REJECTED: unable to price mixed outputs`
16004
- );
16109
+ console.warn(`[BidManager] Bid from solver=${bid.solverAddress} REJECTED: unable to price mixed outputs`);
16005
16110
  continue;
16006
16111
  }
16007
16112
  if (bidUsd.lt(requiredUsd)) {
16008
16113
  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)}%)`
16114
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (bid=${bidUsd.toString()}, required=${requiredUsd.toString()}, covers=${bidUsd.div(requiredUsd).mul(100).toFixed(2)}%)`
16010
16115
  );
16011
16116
  } else {
16012
16117
  console.log(
16013
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED: mixed USD value=${bidUsd.toString()}`
16118
+ `[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED: mixed USD value=${bidUsd.toString()}`
16014
16119
  );
16015
16120
  }
16016
- validBids.push({ bid, options, usdValue: bidUsd });
16121
+ validBids.push({ bid, usdValue: bidUsd });
16017
16122
  }
16018
16123
  validBids.sort((a, b) => b.usdValue.comparedTo(a.usdValue));
16019
- return validBids.map(({ usdValue: _, ...rest }) => rest);
16124
+ return validBids.map(({ bid }) => bid);
16020
16125
  }
16021
16126
  /**
16022
16127
  * Fallback when DEX pricing is unavailable.
@@ -16024,17 +16129,17 @@ var BidManager = class {
16024
16129
  * Bids offering less than required for a token are allowed (partial fill).
16025
16130
  * Sorted by total offered amount descending.
16026
16131
  */
16027
- sortByRawAmountFallback(decodedBids, orderOutputs) {
16132
+ sortByRawAmountFallback(bids, orderOutputs) {
16028
16133
  console.log(
16029
- `[BidManager] sortByRawAmountFallback: checking ${decodedBids.length} bid(s) against ${orderOutputs.length} required output(s)`
16134
+ `[BidManager] sortByRawAmountFallback: checking ${bids.length} bid(s) against ${orderOutputs.length} required output(s)`
16030
16135
  );
16031
16136
  const validBids = [];
16032
- for (const { bid, options } of decodedBids) {
16137
+ for (const bid of bids) {
16033
16138
  let valid = true;
16034
16139
  let totalOffered = new Decimal2(0);
16035
16140
  let rejectReason = "";
16036
16141
  for (const required of orderOutputs) {
16037
- const matching = options.outputs.find((o) => o.token.toLowerCase() === required.token.toLowerCase());
16142
+ const matching = bid.outputs.find((o) => o.token.toLowerCase() === required.token.toLowerCase());
16038
16143
  if (!matching) {
16039
16144
  valid = false;
16040
16145
  rejectReason = `missing output token=${required.token}`;
@@ -16043,7 +16148,7 @@ var BidManager = class {
16043
16148
  totalOffered = totalOffered.plus(new Decimal2(matching.amount.toString()));
16044
16149
  }
16045
16150
  if (!valid) {
16046
- console.warn(`[BidManager] Bid from solver=${bid.userOp.sender} REJECTED (fallback): ${rejectReason}`);
16151
+ console.warn(`[BidManager] Bid from solver=${bid.solverAddress} REJECTED (fallback): ${rejectReason}`);
16047
16152
  continue;
16048
16153
  }
16049
16154
  const totalRequired = orderOutputs.reduce(
@@ -16052,17 +16157,17 @@ var BidManager = class {
16052
16157
  );
16053
16158
  if (totalOffered.lt(totalRequired)) {
16054
16159
  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)}%)`
16160
+ `[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
16161
  );
16057
16162
  } else {
16058
16163
  console.log(
16059
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED (fallback): totalOffered=${totalOffered.toString()}`
16164
+ `[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED (fallback): totalOffered=${totalOffered.toString()}`
16060
16165
  );
16061
16166
  }
16062
- validBids.push({ bid, options, totalOffered });
16167
+ validBids.push({ bid, totalOffered });
16063
16168
  }
16064
16169
  validBids.sort((a, b) => b.totalOffered.comparedTo(a.totalOffered));
16065
- return validBids.map(({ totalOffered: _, ...rest }) => rest);
16170
+ return validBids.map(({ bid }) => bid);
16066
16171
  }
16067
16172
  // ── Token classification helpers ──────────────────────────────────
16068
16173
  /**
@@ -16671,6 +16776,262 @@ var OrderStatusChecker = class {
16671
16776
  }
16672
16777
  };
16673
16778
 
16779
+ // src/protocols/intents/quote/types.ts
16780
+ var UnsupportedIntentQuoteStrategyError = class extends Error {
16781
+ constructor(strategy) {
16782
+ super(`Unsupported intent quote strategy: ${strategy}`);
16783
+ this.name = "UnsupportedIntentQuoteStrategyError";
16784
+ }
16785
+ };
16786
+ var UnsupportedIntentQuotePairError = class extends Error {
16787
+ constructor(params) {
16788
+ super(
16789
+ `No Uniswap v4 pool config found for ${params.tokenIn.symbol ?? params.tokenIn.address} -> ${params.tokenOut.symbol ?? params.tokenOut.address} on ${params.source} -> ${params.destination}`
16790
+ );
16791
+ this.name = "UnsupportedIntentQuotePairError";
16792
+ }
16793
+ };
16794
+
16795
+ // src/protocols/intents/quote/uniswapV4.ts
16796
+ var UNISWAP_INTENT_QUOTE_CHAIN = "EVM-8453" /* BASE_MAINNET */;
16797
+ var BPS_DENOMINATOR = 10000n;
16798
+ var UniswapV4IntentQuoteStrategy = class {
16799
+ constructor(chainConfigService) {
16800
+ this.chainConfigService = chainConfigService;
16801
+ }
16802
+ chainConfigService;
16803
+ baseQuoteClient;
16804
+ async quote(params, source, destination) {
16805
+ this.validateQuoteParams(params);
16806
+ const protocolFeeBps = await this.readProtocolFeeBps(source.client, source.stateMachineId);
16807
+ const quoteClient = this.resolveQuoteClient(source, destination);
16808
+ const poolConfig = this.resolvePoolConfig(params, source.stateMachineId, UNISWAP_INTENT_QUOTE_CHAIN);
16809
+ return params.amountIn !== void 0 ? this.quoteExactInput({ params, client: quoteClient, protocolFeeBps, poolConfig }) : this.quoteExactOutput({ params, client: quoteClient, protocolFeeBps, poolConfig });
16810
+ }
16811
+ resolveQuoteClient(source, destination) {
16812
+ if (source.stateMachineId === UNISWAP_INTENT_QUOTE_CHAIN) return source.client;
16813
+ if (destination.stateMachineId === UNISWAP_INTENT_QUOTE_CHAIN) return destination.client;
16814
+ if (this.baseQuoteClient) return this.baseQuoteClient;
16815
+ const rpcUrl = this.chainConfigService.getRpcUrl(UNISWAP_INTENT_QUOTE_CHAIN);
16816
+ if (!rpcUrl) throw new Error(`RPC URL is not configured for ${UNISWAP_INTENT_QUOTE_CHAIN}`);
16817
+ const baseQuoteClient = createPublicClient({
16818
+ chain: base,
16819
+ transport: http(rpcUrl)
16820
+ });
16821
+ this.baseQuoteClient = baseQuoteClient;
16822
+ return baseQuoteClient;
16823
+ }
16824
+ validateQuoteParams(params) {
16825
+ const hasAmountIn = params.amountIn !== void 0;
16826
+ const hasAmountOut = params.amountOut !== void 0;
16827
+ if (hasAmountIn === hasAmountOut) throw new Error("Provide exactly one of amountIn or amountOut");
16828
+ if (hasAmountIn && params.amountIn <= 0n) throw new Error("amountIn must be greater than zero");
16829
+ if (hasAmountOut && params.amountOut <= 0n) throw new Error("amountOut must be greater than zero");
16830
+ if (params.tokenIn.address.toLowerCase() === params.tokenOut.address.toLowerCase()) {
16831
+ throw new Error("tokenIn and tokenOut cannot be the same");
16832
+ }
16833
+ }
16834
+ async readProtocolFeeBps(client, chain) {
16835
+ const gatewayAddress = this.chainConfigService.getIntentGatewayAddress(chain);
16836
+ if (!gatewayAddress || gatewayAddress === "0x" || gatewayAddress === zeroAddress) {
16837
+ throw new Error(`IntentGatewayV2 is not configured for chain ${chain}`);
16838
+ }
16839
+ const gatewayParams = await client.readContract({
16840
+ address: gatewayAddress,
16841
+ abi: IntentGatewayV2_default.ABI,
16842
+ functionName: "params"
16843
+ });
16844
+ if (isGatewayParamsTuple(gatewayParams)) return BigInt(gatewayParams[4]);
16845
+ return BigInt(gatewayParams.protocolFeeBps ?? 0);
16846
+ }
16847
+ resolvePoolConfig(params, source, destination) {
16848
+ const override = params.uniswapV4?.poolKey;
16849
+ if (override) {
16850
+ const poolKey = normalizePoolKey(override);
16851
+ const tokenInForQuote = getAddress(override.currencyIn ?? params.tokenIn.address);
16852
+ if (tokenInForQuote !== poolKey.currency0 && tokenInForQuote !== poolKey.currency1) {
16853
+ throw new Error(
16854
+ `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.`
16855
+ );
16856
+ }
16857
+ return {
16858
+ poolKey,
16859
+ quoterAddress: this.resolveQuoterAddress(destination, override.quoterAddress),
16860
+ tokenInForQuote
16861
+ };
16862
+ }
16863
+ const poolConfig = this.resolveConfiguredPool(params, destination);
16864
+ if (poolConfig) return poolConfig;
16865
+ throw new UnsupportedIntentQuotePairError({
16866
+ source,
16867
+ destination,
16868
+ tokenIn: params.tokenIn,
16869
+ tokenOut: params.tokenOut
16870
+ });
16871
+ }
16872
+ resolveConfiguredPool(params, chain) {
16873
+ for (const pool of this.chainConfigService.getUniswapV4PoolConfigs(chain)) {
16874
+ const resolvedPool = this.resolveConfiguredPoolTokens(chain, pool);
16875
+ if (!resolvedPool) continue;
16876
+ const tokenInForQuote = matchPoolToken(params.tokenIn, resolvedPool);
16877
+ const tokenOutForQuote = matchPoolToken(params.tokenOut, resolvedPool);
16878
+ if (!tokenInForQuote || !tokenOutForQuote || tokenInForQuote.symbol === tokenOutForQuote.symbol) continue;
16879
+ const { currency0, currency1 } = sortCurrencies(resolvedPool[0].address, resolvedPool[1].address);
16880
+ return {
16881
+ poolKey: {
16882
+ currency0,
16883
+ currency1,
16884
+ fee: pool.fee,
16885
+ tickSpacing: pool.tickSpacing,
16886
+ hooks: getAddress(pool.hooks ?? zeroAddress)
16887
+ },
16888
+ quoterAddress: this.resolveQuoterAddress(chain),
16889
+ tokenInForQuote: tokenInForQuote.address
16890
+ };
16891
+ }
16892
+ return null;
16893
+ }
16894
+ resolveQuoterAddress(chain, override) {
16895
+ const address = override ?? this.chainConfigService.getUniswapV4QuoterAddress(chain);
16896
+ if (!address || address === "0x" || address === zeroAddress) {
16897
+ throw new Error(`Uniswap V4 quoter is not configured for chain ${chain}`);
16898
+ }
16899
+ return getAddress(address);
16900
+ }
16901
+ resolveConfiguredPoolTokens(chain, pool) {
16902
+ const first = this.resolveConfiguredPoolToken(chain, pool.tokens[0]);
16903
+ const second = this.resolveConfiguredPoolToken(chain, pool.tokens[1]);
16904
+ return first && second ? [first, second] : null;
16905
+ }
16906
+ resolveConfiguredPoolToken(chain, symbol) {
16907
+ const address = this.chainConfigService.getAssetAddress(chain, symbol);
16908
+ if (!address || address === "0x") return null;
16909
+ return { symbol, address: getAddress(address) };
16910
+ }
16911
+ async quoteExactInput(args) {
16912
+ const amountIn = args.params.amountIn;
16913
+ const swapAmountIn = deductProtocolFee(amountIn, args.protocolFeeBps);
16914
+ const amountOut = await this.readV4QuoteExactInput(args.client, args.poolConfig, swapAmountIn);
16915
+ return {
16916
+ strategy: "uniswap_v4",
16917
+ tradeType: "EXACT_INPUT",
16918
+ amountIn,
16919
+ amountOut,
16920
+ quoteMetadata: {
16921
+ quoteChain: UNISWAP_INTENT_QUOTE_CHAIN,
16922
+ poolKey: args.poolConfig.poolKey,
16923
+ quoterAddress: args.poolConfig.quoterAddress,
16924
+ protocolFeeBps: args.protocolFeeBps
16925
+ }
16926
+ };
16927
+ }
16928
+ async quoteExactOutput(args) {
16929
+ const amountOut = args.params.amountOut;
16930
+ const swapAmountIn = await this.readV4QuoteExactOutput(args.client, args.poolConfig, amountOut);
16931
+ const amountIn = grossUpForProtocolFee(swapAmountIn, args.protocolFeeBps);
16932
+ return {
16933
+ strategy: "uniswap_v4",
16934
+ tradeType: "EXACT_OUTPUT",
16935
+ amountIn,
16936
+ amountOut,
16937
+ quoteMetadata: {
16938
+ quoteChain: UNISWAP_INTENT_QUOTE_CHAIN,
16939
+ poolKey: args.poolConfig.poolKey,
16940
+ quoterAddress: args.poolConfig.quoterAddress,
16941
+ protocolFeeBps: args.protocolFeeBps
16942
+ }
16943
+ };
16944
+ }
16945
+ async readV4QuoteExactInput(client, poolConfig, amountIn) {
16946
+ const data = encodeFunctionData({
16947
+ abi: UNISWAP_V4_QUOTER_ABI,
16948
+ functionName: "quoteExactInputSingle",
16949
+ args: [
16950
+ {
16951
+ poolKey: poolConfig.poolKey,
16952
+ zeroForOne: getZeroForOne(poolConfig.tokenInForQuote, poolConfig.poolKey),
16953
+ exactAmount: amountIn,
16954
+ hookData: "0x"
16955
+ }
16956
+ ]
16957
+ });
16958
+ const response = await client.call({ to: poolConfig.quoterAddress, data });
16959
+ if (!response.data || response.data === "0x") {
16960
+ throw new Error(`Uniswap V4 quoter at ${poolConfig.quoterAddress} returned no data`);
16961
+ }
16962
+ const [amountOut] = decodeFunctionResult({
16963
+ abi: UNISWAP_V4_QUOTER_ABI,
16964
+ functionName: "quoteExactInputSingle",
16965
+ data: response.data
16966
+ });
16967
+ return amountOut;
16968
+ }
16969
+ async readV4QuoteExactOutput(client, poolConfig, amountOut) {
16970
+ const data = encodeFunctionData({
16971
+ abi: UNISWAP_V4_QUOTER_ABI,
16972
+ functionName: "quoteExactOutputSingle",
16973
+ args: [
16974
+ {
16975
+ poolKey: poolConfig.poolKey,
16976
+ zeroForOne: getZeroForOne(poolConfig.tokenInForQuote, poolConfig.poolKey),
16977
+ exactAmount: amountOut,
16978
+ hookData: "0x"
16979
+ }
16980
+ ]
16981
+ });
16982
+ const response = await client.call({ to: poolConfig.quoterAddress, data });
16983
+ if (!response.data || response.data === "0x") {
16984
+ throw new Error(`Uniswap V4 quoter at ${poolConfig.quoterAddress} returned no data`);
16985
+ }
16986
+ const [amountIn] = decodeFunctionResult({
16987
+ abi: UNISWAP_V4_QUOTER_ABI,
16988
+ functionName: "quoteExactOutputSingle",
16989
+ data: response.data
16990
+ });
16991
+ return amountIn;
16992
+ }
16993
+ };
16994
+ function normalizePoolKey(poolKey) {
16995
+ return {
16996
+ currency0: getAddress(poolKey.currency0),
16997
+ currency1: getAddress(poolKey.currency1),
16998
+ fee: poolKey.fee,
16999
+ tickSpacing: poolKey.tickSpacing,
17000
+ hooks: getAddress(poolKey.hooks)
17001
+ };
17002
+ }
17003
+ function sortCurrencies(tokenIn, tokenOut) {
17004
+ const input = getAddress(tokenIn);
17005
+ const output = getAddress(tokenOut);
17006
+ return BigInt(input) < BigInt(output) ? { currency0: input, currency1: output } : { currency0: output, currency1: input };
17007
+ }
17008
+ function matchPoolToken(token, poolTokens) {
17009
+ const tokenAddress = token.address.toLowerCase();
17010
+ const addressMatch = poolTokens.find((poolToken) => poolToken.address.toLowerCase() === tokenAddress);
17011
+ if (addressMatch) return addressMatch;
17012
+ const tokenSymbol = token.symbol?.toUpperCase();
17013
+ if (!tokenSymbol) return null;
17014
+ return poolTokens.find((poolToken) => poolToken.symbol.toUpperCase() === tokenSymbol) ?? null;
17015
+ }
17016
+ function getZeroForOne(tokenIn, poolKey) {
17017
+ return getAddress(tokenIn).toLowerCase() === getAddress(poolKey.currency0).toLowerCase();
17018
+ }
17019
+ function isGatewayParamsTuple(value) {
17020
+ return Array.isArray(value);
17021
+ }
17022
+ function deductProtocolFee(amount, protocolFeeBps) {
17023
+ if (protocolFeeBps <= 0n) return amount;
17024
+ const fee = amount * protocolFeeBps / BPS_DENOMINATOR;
17025
+ return amount - fee;
17026
+ }
17027
+ function grossUpForProtocolFee(netAmount, protocolFeeBps) {
17028
+ if (protocolFeeBps <= 0n) return netAmount;
17029
+ return divCeil(netAmount * BPS_DENOMINATOR, BPS_DENOMINATOR - protocolFeeBps);
17030
+ }
17031
+ function divCeil(numerator, denominator) {
17032
+ return (numerator + denominator - 1n) / denominator;
17033
+ }
17034
+
16674
17035
  // src/protocols/intents/IntentGateway.ts
16675
17036
  var IntentGateway = class _IntentGateway {
16676
17037
  /** EVM chain on which orders are placed and escrowed. */
@@ -16697,6 +17058,8 @@ var IntentGateway = class _IntentGateway {
16697
17058
  bidManager;
16698
17059
  /** Estimates gas costs for filling an order and converts them to fee-token amounts. */
16699
17060
  gasEstimator;
17061
+ /** Quote strategies for pricing orders before placement, keyed by strategy name. */
17062
+ quoteStrategies;
16700
17063
  /**
16701
17064
  * Private constructor — use {@link IntentGateway.create} instead.
16702
17065
  *
@@ -16734,12 +17097,15 @@ var IntentGateway = class _IntentGateway {
16734
17097
  const bidManager = new BidManager(this.ctx, crypto);
16735
17098
  const gasEstimator = new GasEstimator(this.ctx, crypto);
16736
17099
  this.orderPlacer = new OrderPlacer(this.ctx);
16737
- this.orderExecutor = new OrderExecutor(this.ctx, bidManager, crypto);
17100
+ this.orderExecutor = new OrderExecutor(this.ctx, bidManager);
16738
17101
  this.orderCanceller = new OrderCanceller(this.ctx);
16739
17102
  this.orderStatusChecker = new OrderStatusChecker(this.ctx);
16740
17103
  this.bidManager = bidManager;
16741
17104
  this.gasEstimator = gasEstimator;
16742
17105
  this._crypto = crypto;
17106
+ this.quoteStrategies = {
17107
+ uniswap_v4: new UniswapV4IntentQuoteStrategy(dest.configService)
17108
+ };
16743
17109
  }
16744
17110
  /**
16745
17111
  * Creates an initialized IntentGateway instance.
@@ -16784,6 +17150,33 @@ var IntentGateway = class _IntentGateway {
16784
17150
  }
16785
17151
  }
16786
17152
  }
17153
+ /**
17154
+ * Quotes an intent between this gateway's source and destination chains.
17155
+ *
17156
+ * `strategy` defaults to `uniswap_v4`, currently the only supported
17157
+ * strategy. Provide exactly one of `amountIn` or `amountOut`.
17158
+ *
17159
+ * The Uniswap quote strategy always prices against the configured Base
17160
+ * pool, regardless of this gateway's destination chain. Returned
17161
+ * `amountIn`/`amountOut` already account for the gateway's protocol fee
17162
+ * (`quoteMetadata.protocolFeeBps`), which the gateway deducts from order
17163
+ * inputs; apply only your own slippage tolerance before placing the order.
17164
+ *
17165
+ * @param params - Token pair, amount, and optional strategy/pool overrides.
17166
+ * @returns The quoted amounts plus strategy-specific metadata.
17167
+ * @throws {UnsupportedIntentQuoteStrategyError} For unknown strategies.
17168
+ * @throws {UnsupportedIntentQuotePairError} When no pool is configured for the pair.
17169
+ */
17170
+ async quoteIntent(params) {
17171
+ const strategy = params.strategy ?? "uniswap_v4";
17172
+ const handler = this.quoteStrategies[strategy];
17173
+ if (!handler) throw new UnsupportedIntentQuoteStrategyError(strategy);
17174
+ return handler.quote(
17175
+ { ...params, strategy },
17176
+ { stateMachineId: this.source.config.stateMachineId, client: this.source.client },
17177
+ { stateMachineId: this.dest.config.stateMachineId, client: this.dest.client }
17178
+ );
17179
+ }
16787
17180
  /**
16788
17181
  * Bidirectional async generator that orchestrates the full order lifecycle:
16789
17182
  * placement, fee estimation, bid collection, and execution.
@@ -16838,17 +17231,38 @@ var IntentGateway = class _IntentGateway {
16838
17231
  }
16839
17232
  const { order: finalizedOrder, receipt: placementReceipt } = placeOrderSecond.value;
16840
17233
  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
- }
17234
+ yield* this.driveExecution(
17235
+ this.orderExecutor.executeOrder({
17236
+ order: finalizedOrder,
17237
+ sessionPrivateKey,
17238
+ auctionTimeMs: options.auctionTimeMs,
17239
+ pollIntervalMs: options.pollIntervalMs,
17240
+ solver: options.solver
17241
+ })
17242
+ );
16850
17243
  return;
16851
17244
  }
17245
+ /**
17246
+ * Forwards updates from the executor's bidirectional generator to the caller,
17247
+ * threading the {@link SelectBidResult} the caller feeds back after a
17248
+ * `BIDS_RECEIVED` yield into the executor's `.next()`. Other yields expect no
17249
+ * feedback. This is what lets the consumer own `bid.execute()` while the
17250
+ * executor keeps tracking fills and continuing the auction.
17251
+ */
17252
+ async *driveExecution(execGen) {
17253
+ try {
17254
+ let input;
17255
+ while (true) {
17256
+ const { value, done } = await execGen.next(input);
17257
+ input = void 0;
17258
+ if (done) break;
17259
+ const fed = yield value;
17260
+ if (value.status === "BIDS_RECEIVED") input = fed;
17261
+ }
17262
+ } finally {
17263
+ await execGen.return();
17264
+ }
17265
+ }
16852
17266
  /**
16853
17267
  * Validates that an order has the minimum fields required for post-placement
16854
17268
  * resume (i.e. it was previously placed and has an on-chain identity).
@@ -16885,14 +17299,99 @@ var IntentGateway = class _IntentGateway {
16885
17299
  */
16886
17300
  async *resume(order, options) {
16887
17301
  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;
17302
+ yield* this.driveExecution(
17303
+ this.orderExecutor.executeOrder({
17304
+ order,
17305
+ sessionPrivateKey: options.sessionPrivateKey,
17306
+ auctionTimeMs: options.auctionTimeMs,
17307
+ pollIntervalMs: options.pollIntervalMs,
17308
+ solver: options.solver
17309
+ })
17310
+ );
17311
+ }
17312
+ /**
17313
+ * Batteries-included variant of {@link execute}: places the order and then
17314
+ * auto-selects the best bid each round via {@link selectAndExecuteBest}, with
17315
+ * no bid-selection input from the caller.
17316
+ *
17317
+ * The caller still signs the placement transaction: this generator yields
17318
+ * `AWAITING_PLACE_ORDER` and the caller must hand the signed tx back via
17319
+ * `gen.next(signedTx)` exactly as with {@link execute}. Every other stage
17320
+ * (`BIDS_RECEIVED`, `BID_SELECTED`, `FILLED`, …) is handled automatically and
17321
+ * surfaced for observation, so the rest of the loop needs no feedback.
17322
+ *
17323
+ * @param order - The order to place and execute.
17324
+ * @param graffiti - Optional orderflow-attribution tag.
17325
+ * @param options - Same tuning parameters as {@link execute}.
17326
+ * @yields {@link IntentOrderStatusUpdate} at each lifecycle stage.
17327
+ */
17328
+ async *executeBest(order, graffiti = DEFAULT_GRAFFITI, options) {
17329
+ const gen = this.execute(order, graffiti, options);
17330
+ try {
17331
+ let input;
17332
+ while (true) {
17333
+ const { value, done } = await gen.next(input);
17334
+ input = void 0;
17335
+ if (done) break;
17336
+ if (value.status === "BIDS_RECEIVED") {
17337
+ yield value;
17338
+ input = await this.autoSelect(order, value.bids);
17339
+ } else if (value.status === "AWAITING_PLACE_ORDER") {
17340
+ input = yield value;
17341
+ } else {
17342
+ yield value;
17343
+ }
17344
+ }
17345
+ } finally {
17346
+ await gen.return();
17347
+ }
17348
+ }
17349
+ /**
17350
+ * Batteries-included variant of {@link resume}: auto-selects the best bid each
17351
+ * round via {@link selectAndExecuteBest}, with no bid-selection input from the
17352
+ * caller. A plain `for await` loop is sufficient — there is no placement step.
17353
+ *
17354
+ * @param order - A previously placed order with a valid `id` and `session`.
17355
+ * @param options - Optional tuning parameters for bid collection and execution.
17356
+ * @yields {@link IntentOrderStatusUpdate} at each execution stage.
17357
+ */
17358
+ async *resumeBest(order, options) {
17359
+ const gen = this.resume(order, options);
17360
+ try {
17361
+ let input;
17362
+ while (true) {
17363
+ const { value, done } = await gen.next(input);
17364
+ input = void 0;
17365
+ if (done) break;
17366
+ yield value;
17367
+ if (value.status === "BIDS_RECEIVED") {
17368
+ input = await this.autoSelect(order, value.bids);
17369
+ }
17370
+ }
17371
+ } finally {
17372
+ await gen.return();
17373
+ }
17374
+ }
17375
+ /**
17376
+ * Auto-select wrapper used by {@link executeBest} / {@link resumeBest}.
17377
+ *
17378
+ * Runs {@link selectAndExecuteBest} and returns the {@link SelectBidResult} to
17379
+ * feed back to the executor. If selection fails this round — all bids fail
17380
+ * simulation, no valid bids, or the bundler rejects the UserOp — it swallows
17381
+ * the error and returns `undefined`, which tells the executor to keep polling
17382
+ * for fresh bids until the deadline rather than aborting the order. Swallowing
17383
+ * the error here (rather than letting it propagate) also keeps the executor's
17384
+ * `finally` teardown intact, since nothing throws across the suspended
17385
+ * generators.
17386
+ */
17387
+ async autoSelect(order, bids) {
17388
+ try {
17389
+ return await this.selectAndExecuteBest(order, bids);
17390
+ } catch (err) {
17391
+ console.warn(
17392
+ `[IntentGateway] autoSelect: bid selection failed this round, continuing to poll: ${err instanceof Error ? err.message : String(err)}`
17393
+ );
17394
+ return void 0;
16896
17395
  }
16897
17396
  }
16898
17397
  /**
@@ -16948,10 +17447,52 @@ var IntentGateway = class _IntentGateway {
16948
17447
  return this.bidManager.prepareSubmitBid(options);
16949
17448
  }
16950
17449
  /**
16951
- * Selects the best available bid, simulates it, and submits the UserOperation
16952
- * to the bundler.
17450
+ * Decodes raw filler bids into first-class {@link Bid} objects that can be
17451
+ * ranked, simulated, and executed by the consumer.
17452
+ *
17453
+ * Delegates to {@link BidManager.buildBids}.
17454
+ *
17455
+ * @param order - The placed order the bids are competing to fill.
17456
+ * @param bids - Raw filler bids fetched from the coprocessor.
17457
+ * @param sessionPrivateKey - Optional session key override; looked up from
17458
+ * storage by `order.session` if omitted.
17459
+ * @returns Array of executable {@link Bid} objects.
17460
+ */
17461
+ buildBids(order, bids, sessionPrivateKey) {
17462
+ return this.bidManager.buildBids(order, bids, sessionPrivateKey);
17463
+ }
17464
+ /**
17465
+ * Sorts bids by output value using the same strategy the autopilot uses.
17466
+ *
17467
+ * Delegates to {@link BidManager.sortBids}.
17468
+ *
17469
+ * @param order - The placed order whose output spec drives sorting.
17470
+ * @param bids - Bids to sort (from {@link buildBids}).
17471
+ * @returns Sorted array of {@link Bid} objects.
17472
+ */
17473
+ async sortBids(order, bids) {
17474
+ return this.bidManager.sortBids(order, bids);
17475
+ }
17476
+ /**
17477
+ * Autopilot bid selection: sorts the given bids, simulates each until one
17478
+ * passes, then executes it.
17479
+ *
17480
+ * Delegates to {@link BidManager.selectAndExecuteBest}.
17481
+ *
17482
+ * @param order - The placed order to fill.
17483
+ * @param bids - Candidate bids (from {@link buildBids}).
17484
+ * @returns A {@link SelectBidResult} with the submitted UserOperation, hashes,
17485
+ * and fill status.
17486
+ */
17487
+ async selectAndExecuteBest(order, bids) {
17488
+ return this.bidManager.selectAndExecuteBest(order, bids);
17489
+ }
17490
+ /**
17491
+ * Decodes, sorts, simulates, signs, and submits the best of the given raw
17492
+ * filler bids with no per-bid input from the caller.
16953
17493
  *
16954
- * Delegates to {@link BidManager.selectBid}.
17494
+ * Delegates to {@link BidManager.selectBid}. Prefer {@link buildBids} +
17495
+ * {@link selectAndExecuteBest} (or {@link executeBest}) for new code.
16955
17496
  *
16956
17497
  * @param order - The placed order to fill.
16957
17498
  * @param bids - Raw filler bids fetched from the coprocessor.
@@ -17871,7 +18412,7 @@ var HyperFungibleTokenABI = [
17871
18412
  internalType: "uint256"
17872
18413
  }
17873
18414
  ],
17874
- stateMutability: "view"
18415
+ stateMutability: "nonpayable"
17875
18416
  },
17876
18417
  {
17877
18418
  type: "function",
@@ -17922,7 +18463,7 @@ var HyperFungibleTokenABI = [
17922
18463
  internalType: "uint256"
17923
18464
  }
17924
18465
  ],
17925
- stateMutability: "view"
18466
+ stateMutability: "nonpayable"
17926
18467
  },
17927
18468
  {
17928
18469
  type: "function",
@@ -17973,7 +18514,7 @@ var HyperFungibleTokenABI = [
17973
18514
  internalType: "uint256"
17974
18515
  }
17975
18516
  ],
17976
- stateMutability: "view"
18517
+ stateMutability: "nonpayable"
17977
18518
  },
17978
18519
  {
17979
18520
  type: "function",
@@ -18992,7 +19533,7 @@ var WrappedHyperFungibleTokenABI = [
18992
19533
  internalType: "uint256"
18993
19534
  }
18994
19535
  ],
18995
- stateMutability: "view"
19536
+ stateMutability: "nonpayable"
18996
19537
  },
18997
19538
  {
18998
19539
  type: "function",
@@ -19043,7 +19584,7 @@ var WrappedHyperFungibleTokenABI = [
19043
19584
  internalType: "uint256"
19044
19585
  }
19045
19586
  ],
19046
- stateMutability: "view"
19587
+ stateMutability: "nonpayable"
19047
19588
  },
19048
19589
  {
19049
19590
  type: "function",
@@ -19094,7 +19635,7 @@ var WrappedHyperFungibleTokenABI = [
19094
19635
  internalType: "uint256"
19095
19636
  }
19096
19637
  ],
19097
- stateMutability: "view"
19638
+ stateMutability: "nonpayable"
19098
19639
  },
19099
19640
  {
19100
19641
  type: "function",
@@ -19636,13 +20177,13 @@ var HyperFungibleToken = class {
19636
20177
  };
19637
20178
  let totalNativeCost = 0n;
19638
20179
  try {
19639
- totalNativeCost = await this.source.client.readContract({
20180
+ const { result } = await this.source.client.simulateContract({
19640
20181
  address: params.token,
19641
20182
  abi: HyperFungibleTokenABI,
19642
20183
  functionName: "quote",
19643
20184
  args: [sendParams]
19644
20185
  });
19645
- totalNativeCost = totalNativeCost * 101n / 100n;
20186
+ totalNativeCost = result * 101n / 100n;
19646
20187
  } catch {
19647
20188
  }
19648
20189
  return {
@@ -21550,6 +22091,6 @@ async function teleportDot(param_) {
21550
22091
  return stream;
21551
22092
  }
21552
22093
 
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 };
22094
+ export { ADDRESS_ZERO2 as ADDRESS_ZERO, BundlerMethod, ChainConfigService, Chains, CryptoUtils, DEFAULT_ADDRESS, DEFAULT_GRAFFITI, DOMAIN_TYPEHASH, DUMMY_PRIVATE_KEY, ERC20Method, ERC7821_BATCH_MODE, EvmChain, ABI as EvmHostABI, EvmLanguage, HyperClientStatus, HyperFungibleToken, HyperFungibleTokenABI, IntentGateway, ABI3 as IntentGatewayABI, IntentOrderStatus, IntentsCoprocessor, IsmpClient, MOCK_ADDRESS, ORDER_V2_PARAM_TYPE, OrderStatus, OrderStatusChecker, PACKED_USEROP_TYPEHASH, PLACE_ORDER_SELECTOR, PharosChain, PolkadotHubChain, REQUEST_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, RESPONSE_COMMITMENTS_SLOT, RESPONSE_RECEIPTS_SLOT, RequestKind, RequestStatus, SELECT_SOLVER_TYPEHASH, STATE_COMMITMENTS_SLOT, SubstrateChain, Swap, TESTNET_CHAINS, TeleportStatus, TimeoutStatus, TokenGateway, TronChain, USE_ETHERSCAN_CHAINS, UnsupportedIntentQuotePairError, UnsupportedIntentQuoteStrategyError, WrappedHyperFungibleTokenABI, __test, adjustDecimals, bytes20ToBytes32, bytes32ToBytes20, calculateAllowanceMappingLocation, calculateBalanceMappingLocation, chainConfigs, constructRedeemEscrowRequestBody, constructRefundEscrowRequestBody, convertCodecToIGetRequest, convertCodecToIProof, convertIGetRequestToCodec, convertIProofToCodec, convertStateIdToStateMachineId, convertStateMachineEnumToString, convertStateMachineIdToEnum, createEvmChain, createQueryClient, decodeUserOpScale, encodeERC7821ExecuteBatch, encodeISMPMessage, encodeStateMachineId, encodeUserOpScale, encodeWithdrawalRequest, estimateGasForPost, fetchPrice, fetchSourceProof, generateRootWithProof, getChainId, getConfigByStateMachineId, getContractCallInput, getContractCallInputs, getGasPriceFromEtherscan, getOrFetchStorageSlot, getOrderPlacedFromTx, getPostRequestEventFromTx, getPostResponseEventFromTx, getRequestCommitment, getStateCommitmentFieldSlot, getStateCommitmentSlot, getStorageSlot, getViemChain, hexToString, hyperbridgeAddress, maxBigInt, normalizeAddressForEvmBytes32, normalizeAddressForStateMachine, normalizeEvmChainId, normalizeStateMachineId, orderCommitment, parseStateMachineId, pharosAtlantic, pharosMainnet, polkadotAssetHubPaseo, polkadotHubMainnet, postRequestCommitment, queryAssetTeleported, queryGetRequest, queryPostRequest, quoteUniswap, requestCommitmentKey, responseCommitmentKey, retryPromise, teleport, teleportDot, transformOrderForContract, tronChainIds, tronNile };
21554
22095
  //# sourceMappingURL=index.js.map
21555
22096
  //# sourceMappingURL=index.js.map