@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.
@@ -1,5 +1,5 @@
1
1
  import { createConsola, LogLevels } from 'consola';
2
- 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';
2
+ 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';
3
3
  import { baseSepolia, optimismSepolia, arbitrumSepolia, soneium, gnosis, optimism, polygonAmoy, polygon, base, arbitrum, bsc, mainnet, sepolia, gnosisChiado, bscTestnet, tron, unichain } from 'viem/chains';
4
4
  import { TronWeb } from 'tronweb';
5
5
  import { flatten, zip, capitalize, maxBy, isNil } from 'lodash-es';
@@ -2619,7 +2619,7 @@ var chainConfigs = {
2619
2619
  USDT: { balanceSlot: 151, allowanceSlot: 152 }
2620
2620
  },
2621
2621
  addresses: {
2622
- IntentGateway: "0xFbF50B2b32768127603cC9eF4b871574b881b8eD",
2622
+ IntentGateway: "0xE13fB34CAe12505ae51BaC8C405AF8EB27AC8058",
2623
2623
  TokenGateway: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6",
2624
2624
  Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
2625
2625
  UniswapRouter02: "0x9639379819420704457B07A0C33B678D9E0F8Df0",
@@ -2629,7 +2629,7 @@ var chainConfigs = {
2629
2629
  UniswapV3Quoter: "0x0000000000000000000000000000000000000000",
2630
2630
  UniswapV4Quoter: "0x0000000000000000000000000000000000000000",
2631
2631
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
2632
- SolverAccount: "0xCDFcFeD7A14154846808FddC8Ba971A2f8a830a3"
2632
+ SolverAccount: "0x0b5cfBc16ef60AD6930ba5A90Bb09475B7BF3815"
2633
2633
  },
2634
2634
  rpcEnvKey: "BSC_CHAPEL",
2635
2635
  defaultRpcUrl: "https://bnb-testnet.api.onfinality.io/public",
@@ -2736,8 +2736,8 @@ var chainConfigs = {
2736
2736
  DAI: { balanceSlot: 0, allowanceSlot: 0 }
2737
2737
  },
2738
2738
  addresses: {
2739
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
2740
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
2739
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2740
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2741
2741
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2742
2742
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2743
2743
  UniswapRouter02: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
@@ -2791,8 +2791,8 @@ var chainConfigs = {
2791
2791
  DAI: { balanceSlot: 0, allowanceSlot: 0 }
2792
2792
  },
2793
2793
  addresses: {
2794
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
2795
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
2794
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2795
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2796
2796
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2797
2797
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2798
2798
  UniswapRouter02: "0x10ED43C718714eb63d5aA57B78B54704E256024E",
@@ -2847,8 +2847,8 @@ var chainConfigs = {
2847
2847
  DAI: { balanceSlot: 0, allowanceSlot: 0 }
2848
2848
  },
2849
2849
  addresses: {
2850
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
2851
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
2850
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2851
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2852
2852
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2853
2853
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2854
2854
  UniswapRouter02: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
@@ -2904,8 +2904,8 @@ var chainConfigs = {
2904
2904
  DAI: { balanceSlot: 0, allowanceSlot: 0 }
2905
2905
  },
2906
2906
  addresses: {
2907
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
2908
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
2907
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2908
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2909
2909
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2910
2910
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2911
2911
  UniswapRouter02: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
@@ -2929,6 +2929,7 @@ var chainConfigs = {
2929
2929
  consensusStateId: "ETH0",
2930
2930
  coingeckoId: "base",
2931
2931
  layerZeroEid: 30184,
2932
+ uniswapV4Pools: [{ tokens: ["USDC", "cNGN"], fee: 1500, tickSpacing: 30 }],
2932
2933
  popularTokens: [
2933
2934
  "0x4200000000000000000000000000000000000006",
2934
2935
  "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
@@ -2962,8 +2963,8 @@ var chainConfigs = {
2962
2963
  DAI: { balanceSlot: 0, allowanceSlot: 0 }
2963
2964
  },
2964
2965
  addresses: {
2965
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
2966
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
2966
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2967
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2967
2968
  TokenGateway: "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E",
2968
2969
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2969
2970
  UniswapRouter02: "0xd2f9496824951D5237cC71245D659E48d0d5f9E8",
@@ -3033,7 +3034,7 @@ var chainConfigs = {
3033
3034
  //wmatic, change it to wpol
3034
3035
  DAI: "0x0000000000000000000000000000000000000000",
3035
3036
  USDC: "0x693b854d6965ffeaae21c74049dea644b56fcacb",
3036
- USDT: "0x693b854d6965ffeaae21c74049dea644b56fcacb"
3037
+ USDT: "0x0000000000000000000000000000000000000000"
3037
3038
  },
3038
3039
  tokenDecimals: {
3039
3040
  USDC: 18,
@@ -3044,13 +3045,13 @@ var chainConfigs = {
3044
3045
  USDC: { balanceSlot: 1, allowanceSlot: 2 }
3045
3046
  },
3046
3047
  addresses: {
3047
- IntentGateway: "0xFbF50B2b32768127603cC9eF4b871574b881b8eD",
3048
+ IntentGateway: "0xE13fB34CAe12505ae51BaC8C405AF8EB27AC8058",
3048
3049
  TokenGateway: "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E",
3049
3050
  Host: "0xEB944071A9Bf22810757C5BcFf7a2aE9663a311D",
3050
3051
  Calldispatcher: "0x876F1891982E260026630c233A4897160A281Fb8",
3051
3052
  Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
3052
3053
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
3053
- SolverAccount: "0xCDFcFeD7A14154846808FddC8Ba971A2f8a830a3"
3054
+ SolverAccount: "0x0b5cfBc16ef60AD6930ba5A90Bb09475B7BF3815"
3054
3055
  },
3055
3056
  rpcEnvKey: "POLYGON_AMOY",
3056
3057
  defaultRpcUrl: "https://rpc-amoy.polygon.technology",
@@ -3073,8 +3074,8 @@ var chainConfigs = {
3073
3074
  USDT: 6
3074
3075
  },
3075
3076
  addresses: {
3076
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
3077
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
3077
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
3078
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
3078
3079
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
3079
3080
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
3080
3081
  UniswapRouter02: "0x4A7b5Da61326A6379179b40d00F57E5bbDC962c2",
@@ -3108,8 +3109,8 @@ var chainConfigs = {
3108
3109
  USDT: 6
3109
3110
  },
3110
3111
  addresses: {
3111
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
3112
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
3112
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
3113
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
3113
3114
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
3114
3115
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
3115
3116
  UniswapRouter02: "0xB2e26652e4BAd1e56055A051f922E06760cA0BFE",
@@ -3263,8 +3264,8 @@ var chainConfigs = {
3263
3264
  USDT: 6
3264
3265
  },
3265
3266
  addresses: {
3266
- IntentGateway: "0x16F9E57f735bBfF9f6c4E5276330f9c437d0e9E0",
3267
- SolverAccount: "0xB92A51A609e85f8316004a6da9feaB4421c01b43",
3267
+ IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
3268
+ SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
3268
3269
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
3269
3270
  Calldispatcher: "0xE2C7e576E26E0bE7aC97c6fE925bcDAbD87c4bEd"
3270
3271
  },
@@ -5142,6 +5143,9 @@ var ChainConfigService = class {
5142
5143
  getDaiAsset(chain) {
5143
5144
  return this.getConfig(chain)?.assets?.DAI ?? "0x";
5144
5145
  }
5146
+ getAssetAddress(chain, symbol) {
5147
+ return this.getConfig(chain)?.assets?.[symbol];
5148
+ }
5145
5149
  getUsdtAsset(chain) {
5146
5150
  return this.getConfig(chain)?.assets?.USDT ?? "0x";
5147
5151
  }
@@ -5210,6 +5214,9 @@ var ChainConfigService = class {
5210
5214
  getUniswapV4StateViewAddress(chain) {
5211
5215
  return this.getConfig(chain)?.addresses.UniswapV4StateView ?? "0x";
5212
5216
  }
5217
+ getUniswapV4PoolConfigs(chain) {
5218
+ return this.getConfig(chain)?.uniswapV4Pools ?? [];
5219
+ }
5213
5220
  getPermit2Address(chain) {
5214
5221
  return this.getConfig(chain)?.addresses.Permit2 ?? "0x";
5215
5222
  }
@@ -5220,7 +5227,7 @@ var ChainConfigService = class {
5220
5227
  return this.getConfig(chain)?.coingeckoId;
5221
5228
  }
5222
5229
  getEtherscanApiKey() {
5223
- return typeof process !== "undefined" ? process?.env?.ETHERSCAN_API_KEY : void 0;
5230
+ return typeof process !== "undefined" ? process.env?.ETHERSCAN_API_KEY : void 0;
5224
5231
  }
5225
5232
  getCalldispatcherAddress(chain) {
5226
5233
  return this.getConfig(chain)?.addresses.Calldispatcher ?? "0x";
@@ -9589,7 +9596,28 @@ function adjustDecimals(feeInFeeToken, fromDecimals, toDecimals) {
9589
9596
  }
9590
9597
  }
9591
9598
  var USE_ETHERSCAN_CHAINS = /* @__PURE__ */ new Set(["EVM-137", "EVM-56", "EVM-1"]);
9592
- var TESTNET_CHAINS = /* @__PURE__ */ new Set(["EVM-10200", "EVM-97"]);
9599
+ var TESTNET_CHAINS = /* @__PURE__ */ new Set([
9600
+ "EVM-97",
9601
+ // BSC Chapel
9602
+ "EVM-10200",
9603
+ // Gnosis Chiado
9604
+ "EVM-11155111",
9605
+ // Sepolia
9606
+ "EVM-421614",
9607
+ // Arbitrum Sepolia
9608
+ "EVM-84532",
9609
+ // Base Sepolia
9610
+ "EVM-11155420",
9611
+ // Optimism Sepolia
9612
+ "EVM-80002",
9613
+ // Polygon Amoy
9614
+ "EVM-420420417",
9615
+ // Polkadot Asset Hub Paseo
9616
+ "EVM-3448148188",
9617
+ // Tron Nile
9618
+ "EVM-688689"
9619
+ // Pharos Atlantic
9620
+ ]);
9593
9621
  function collectCallInputsByAddress(call, targetContractAddress, acc) {
9594
9622
  const normalizedTarget = targetContractAddress.toLowerCase();
9595
9623
  if (call.calls && Array.isArray(call.calls)) {
@@ -9904,6 +9932,48 @@ var GetRequestClient = class {
9904
9932
  async buildFinalized(request, hyperbridgeDelivered, response) {
9905
9933
  const sourceChain = this.ctx.config.source;
9906
9934
  const hyperbridge = this.ctx.config.hyperbridge;
9935
+ const { config } = hyperbridge;
9936
+ const finality = await this.queries.queryStateMachineUpdateByHeight({
9937
+ statemachineId: config.stateMachineId,
9938
+ height: hyperbridgeDelivered.metadata.blockNumber,
9939
+ chain: config.stateMachineId
9940
+ });
9941
+ if (finality) {
9942
+ const proof = await hyperbridge.queryProof(
9943
+ { Responses: [response.commitment] },
9944
+ request.source,
9945
+ BigInt(finality.height)
9946
+ );
9947
+ const calldata = sourceChain.encode({
9948
+ kind: "GetResponse",
9949
+ proof: {
9950
+ stateMachine: config.stateMachineId,
9951
+ consensusStateId: config.consensusStateId,
9952
+ proof,
9953
+ height: BigInt(finality.height)
9954
+ },
9955
+ responses: [
9956
+ {
9957
+ get: request,
9958
+ values: request.keys.map((key, index) => ({
9959
+ key,
9960
+ value: response.values[index] || "0x"
9961
+ }))
9962
+ }
9963
+ ],
9964
+ signer: pad("0x")
9965
+ });
9966
+ return {
9967
+ status: RequestStatus.HYPERBRIDGE_FINALIZED,
9968
+ metadata: {
9969
+ blockHash: finality.blockHash,
9970
+ blockNumber: finality.height,
9971
+ transactionHash: finality.transactionHash,
9972
+ timestamp: finality.timestamp,
9973
+ calldata
9974
+ }
9975
+ };
9976
+ }
9907
9977
  if (sourceChain instanceof EvmChain) {
9908
9978
  const hyperbridgeSubstrate = hyperbridge;
9909
9979
  const currentEpoch = await sourceChain.currentEpoch();
@@ -9912,18 +9982,18 @@ var GetRequestClient = class {
9912
9982
  currentEpoch
9913
9983
  );
9914
9984
  if (!consensusResult) return void 0;
9915
- const proof2 = await hyperbridge.queryProof(
9985
+ const proof = await hyperbridge.queryProof(
9916
9986
  { Responses: [response.commitment] },
9917
9987
  request.source,
9918
9988
  consensusResult.provenHeight
9919
9989
  );
9920
- const calldata2 = sourceChain.encode({
9990
+ const calldata = sourceChain.encode({
9921
9991
  kind: "BatchConsensusAndGetResponse",
9922
9992
  consensusProofs: consensusResult.proofs,
9923
9993
  proof: {
9924
- stateMachine: this.ctx.config.hyperbridge.config.stateMachineId,
9925
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
9926
- proof: proof2,
9994
+ stateMachine: config.stateMachineId,
9995
+ consensusStateId: config.consensusStateId,
9996
+ proof,
9927
9997
  height: consensusResult.provenHeight
9928
9998
  },
9929
9999
  responses: [
@@ -9945,50 +10015,11 @@ var GetRequestClient = class {
9945
10015
  transactionHash: hyperbridgeDelivered.metadata.transactionHash,
9946
10016
  // @ts-ignore
9947
10017
  timestamp: hyperbridgeDelivered.metadata.timestamp,
9948
- calldata: calldata2
10018
+ calldata
9949
10019
  }
9950
10020
  };
9951
10021
  }
9952
- const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
9953
- statemachineId: this.ctx.config.hyperbridge.config.stateMachineId,
9954
- height: hyperbridgeDelivered.metadata.blockNumber,
9955
- chain: request.source
9956
- });
9957
- if (!hyperbridgeFinality) return void 0;
9958
- const proof = await hyperbridge.queryProof(
9959
- { Responses: [response.commitment] },
9960
- request.source,
9961
- BigInt(hyperbridgeFinality.height)
9962
- );
9963
- const calldata = sourceChain.encode({
9964
- kind: "GetResponse",
9965
- proof: {
9966
- stateMachine: this.ctx.config.hyperbridge.config.stateMachineId,
9967
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
9968
- proof,
9969
- height: BigInt(hyperbridgeFinality.height)
9970
- },
9971
- responses: [
9972
- {
9973
- get: request,
9974
- values: request.keys.map((key, index) => ({
9975
- key,
9976
- value: response.values[index] || "0x"
9977
- }))
9978
- }
9979
- ],
9980
- signer: pad("0x")
9981
- });
9982
- return {
9983
- status: RequestStatus.HYPERBRIDGE_FINALIZED,
9984
- metadata: {
9985
- blockHash: hyperbridgeFinality.blockHash,
9986
- blockNumber: hyperbridgeFinality.height,
9987
- transactionHash: hyperbridgeFinality.transactionHash,
9988
- timestamp: hyperbridgeFinality.timestamp,
9989
- calldata
9990
- }
9991
- };
10022
+ return void 0;
9992
10023
  }
9993
10024
  /**
9994
10025
  * Streaming helper: waits (via `waitOrAbort`) for the consensus proof or
@@ -10003,7 +10034,12 @@ var GetRequestClient = class {
10003
10034
  const hyperbridge = this.ctx.config.hyperbridge;
10004
10035
  const stateMachineId = this.ctx.config.hyperbridge.config.stateMachineId;
10005
10036
  const neededHeight = BigInt(request.statuses[hyperbridgeDeliveredIndex].metadata.blockNumber);
10006
- if (sourceChain instanceof EvmChain) {
10037
+ let finality = await this.queries.queryStateMachineUpdateByHeight({
10038
+ statemachineId: stateMachineId,
10039
+ height: Number(neededHeight),
10040
+ chain: stateMachineId
10041
+ });
10042
+ if (!finality && sourceChain instanceof EvmChain) {
10007
10043
  const hyperbridgeSubstrate = hyperbridge;
10008
10044
  const currentEpoch = await sourceChain.currentEpoch();
10009
10045
  const consensusResult = await waitOrAbort(this.ctx, {
@@ -10047,18 +10083,20 @@ var GetRequestClient = class {
10047
10083
  }
10048
10084
  };
10049
10085
  }
10050
- const hyperbridgeFinalized = await waitOrAbort(this.ctx, {
10051
- signal,
10052
- promise: () => this.queries.queryStateMachineUpdateByHeight({
10053
- statemachineId: stateMachineId,
10054
- height: Number(neededHeight),
10055
- chain: request.source
10056
- })
10057
- });
10086
+ if (!finality) {
10087
+ finality = await waitOrAbort(this.ctx, {
10088
+ signal,
10089
+ promise: () => this.queries.queryStateMachineUpdateByHeight({
10090
+ statemachineId: stateMachineId,
10091
+ height: Number(neededHeight),
10092
+ chain: stateMachineId
10093
+ })
10094
+ });
10095
+ }
10058
10096
  const proof = await hyperbridge.queryProof(
10059
10097
  { Responses: [response?.commitment] },
10060
10098
  request.source,
10061
- BigInt(hyperbridgeFinalized.height)
10099
+ BigInt(finality.height)
10062
10100
  );
10063
10101
  const calldata = sourceChain.encode({
10064
10102
  kind: "GetResponse",
@@ -10066,7 +10104,7 @@ var GetRequestClient = class {
10066
10104
  stateMachine: stateMachineId,
10067
10105
  consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10068
10106
  proof,
10069
- height: BigInt(hyperbridgeFinalized.height)
10107
+ height: BigInt(finality.height)
10070
10108
  },
10071
10109
  responses: [
10072
10110
  {
@@ -10082,10 +10120,10 @@ var GetRequestClient = class {
10082
10120
  return {
10083
10121
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10084
10122
  metadata: {
10085
- blockHash: hyperbridgeFinalized.blockHash,
10086
- blockNumber: hyperbridgeFinalized.height,
10087
- transactionHash: hyperbridgeFinalized.transactionHash,
10088
- timestamp: hyperbridgeFinalized.timestamp,
10123
+ blockHash: finality.blockHash,
10124
+ blockNumber: finality.height,
10125
+ transactionHash: finality.transactionHash,
10126
+ timestamp: finality.timestamp,
10089
10127
  calldata
10090
10128
  }
10091
10129
  };
@@ -10274,26 +10312,27 @@ var PostRequestClient = class {
10274
10312
  * accompanying timeout-proof calldata.
10275
10313
  */
10276
10314
  async addTimeoutFinalityEvents(request) {
10277
- const destChain = this.ctx.config.dest;
10278
- const hyperbridge = this.ctx.config.hyperbridge;
10279
10315
  const events = [];
10280
- const commitment = postRequestCommitment(request).commitment;
10281
- const receipt = await destChain.queryRequestReceipt(commitment);
10282
- const destTimestamp = await destChain.timestamp();
10283
10316
  const commit = (req) => {
10284
10317
  this.logger.trace(`Added ${events.length} timeout events`, events);
10285
10318
  request.statuses = [...req.statuses, ...events];
10286
10319
  return request;
10287
10320
  };
10288
10321
  if (request.timeoutTimestamp === 0n) return commit(request);
10322
+ if (request.statuses.some(
10323
+ (item) => item.status === RequestStatus.DESTINATION || item.status === TimeoutStatus.TIMED_OUT
10324
+ ))
10325
+ return commit(request);
10326
+ const destChain = this.ctx.config.dest;
10327
+ const hyperbridge = this.ctx.config.hyperbridge;
10328
+ const commitment = postRequestCommitment(request).commitment;
10329
+ const receipt = await destChain.queryRequestReceipt(commitment);
10330
+ const destTimestamp = await destChain.timestamp();
10289
10331
  if (receipt || request.timeoutTimestamp > destTimestamp) return commit(request);
10290
- const is_finished = request.statuses.find((item) => item.status === RequestStatus.DESTINATION);
10291
- if (!is_finished) {
10292
- events.push({
10293
- status: TimeoutStatus.PENDING_TIMEOUT,
10294
- metadata: { blockHash: "0x", blockNumber: 0, transactionHash: "0x" }
10295
- });
10296
- }
10332
+ events.push({
10333
+ status: TimeoutStatus.PENDING_TIMEOUT,
10334
+ metadata: { blockHash: "0x", blockNumber: 0, transactionHash: "0x" }
10335
+ });
10297
10336
  const delivered = request.statuses.find((item) => item.status === RequestStatus.HYPERBRIDGE_DELIVERED);
10298
10337
  let hyperbridgeFinalized;
10299
10338
  if (!delivered) {
@@ -10584,6 +10623,40 @@ var PostRequestClient = class {
10584
10623
  async buildFinalized(request, hyperbridgeDelivered) {
10585
10624
  const destChain = this.ctx.config.dest;
10586
10625
  const hyperbridge = this.ctx.config.hyperbridge;
10626
+ const { config } = hyperbridge;
10627
+ const finality = await this.queries.queryStateMachineUpdateByHeight({
10628
+ statemachineId: config.stateMachineId,
10629
+ height: hyperbridgeDelivered.metadata.blockNumber,
10630
+ chain: config.stateMachineId
10631
+ });
10632
+ if (finality) {
10633
+ const proof = await hyperbridge.queryProof(
10634
+ { Requests: [postRequestCommitment(request).commitment] },
10635
+ request.dest,
10636
+ BigInt(finality.height)
10637
+ );
10638
+ const calldata = destChain.encode({
10639
+ kind: "PostRequest",
10640
+ proof: {
10641
+ stateMachine: config.stateMachineId,
10642
+ consensusStateId: config.consensusStateId,
10643
+ proof,
10644
+ height: BigInt(finality.height)
10645
+ },
10646
+ requests: [request],
10647
+ signer: pad("0x")
10648
+ });
10649
+ return {
10650
+ status: RequestStatus.HYPERBRIDGE_FINALIZED,
10651
+ metadata: {
10652
+ blockHash: finality.blockHash,
10653
+ blockNumber: finality.height,
10654
+ transactionHash: finality.transactionHash,
10655
+ timestamp: finality.timestamp,
10656
+ calldata
10657
+ }
10658
+ };
10659
+ }
10587
10660
  if (destChain instanceof EvmChain) {
10588
10661
  const hyperbridgeSubstrate = hyperbridge;
10589
10662
  const currentEpoch = await destChain.currentEpoch();
@@ -10592,18 +10665,18 @@ var PostRequestClient = class {
10592
10665
  currentEpoch
10593
10666
  );
10594
10667
  if (!consensusResult) return void 0;
10595
- const proof2 = await hyperbridge.queryProof(
10668
+ const proof = await hyperbridge.queryProof(
10596
10669
  { Requests: [postRequestCommitment(request).commitment] },
10597
10670
  request.dest,
10598
10671
  consensusResult.provenHeight
10599
10672
  );
10600
- const calldata2 = destChain.encode({
10673
+ const calldata = destChain.encode({
10601
10674
  kind: "BatchConsensusAndPostRequest",
10602
10675
  consensusProofs: consensusResult.proofs,
10603
10676
  proof: {
10604
- stateMachine: this.ctx.config.hyperbridge.config.stateMachineId,
10605
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10606
- proof: proof2,
10677
+ stateMachine: config.stateMachineId,
10678
+ consensusStateId: config.consensusStateId,
10679
+ proof,
10607
10680
  height: consensusResult.provenHeight
10608
10681
  },
10609
10682
  requests: [request],
@@ -10617,42 +10690,11 @@ var PostRequestClient = class {
10617
10690
  transactionHash: hyperbridgeDelivered.metadata.transactionHash,
10618
10691
  // @ts-ignore
10619
10692
  timestamp: hyperbridgeDelivered.metadata.timestamp,
10620
- calldata: calldata2
10693
+ calldata
10621
10694
  }
10622
10695
  };
10623
10696
  }
10624
- const hyperbridgeFinality = await this.queries.queryStateMachineUpdateByHeight({
10625
- statemachineId: this.ctx.config.hyperbridge.config.stateMachineId,
10626
- height: hyperbridgeDelivered.metadata.blockNumber,
10627
- chain: request.dest
10628
- });
10629
- if (!hyperbridgeFinality) return void 0;
10630
- const proof = await hyperbridge.queryProof(
10631
- { Requests: [postRequestCommitment(request).commitment] },
10632
- request.dest,
10633
- BigInt(hyperbridgeFinality.height)
10634
- );
10635
- const calldata = destChain.encode({
10636
- kind: "PostRequest",
10637
- proof: {
10638
- stateMachine: this.ctx.config.hyperbridge.config.stateMachineId,
10639
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10640
- proof,
10641
- height: BigInt(hyperbridgeFinality.height)
10642
- },
10643
- requests: [request],
10644
- signer: pad("0x")
10645
- });
10646
- return {
10647
- status: RequestStatus.HYPERBRIDGE_FINALIZED,
10648
- metadata: {
10649
- blockHash: hyperbridgeFinality.blockHash,
10650
- blockNumber: hyperbridgeFinality.height,
10651
- transactionHash: hyperbridgeFinality.transactionHash,
10652
- timestamp: hyperbridgeFinality.timestamp,
10653
- calldata
10654
- }
10655
- };
10697
+ return void 0;
10656
10698
  }
10657
10699
  /**
10658
10700
  * Streaming helper: waits for the consensus proof, fetches the messaging
@@ -10666,14 +10708,19 @@ var PostRequestClient = class {
10666
10708
  const stateMachineId = this.ctx.config.hyperbridge.config.stateMachineId;
10667
10709
  const neededHeight = BigInt(request.statuses[hyperbridgeDeliveredIndex].metadata.blockNumber);
10668
10710
  this.logger.trace(`[streamFinalized] neededHeight=${neededHeight}`);
10669
- if (destChain instanceof EvmChain) {
10711
+ const commitment = postRequestCommitment(request).commitment;
10712
+ let finality = await this.queries.queryStateMachineUpdateByHeight({
10713
+ statemachineId: stateMachineId,
10714
+ height: Number(neededHeight),
10715
+ chain: stateMachineId
10716
+ });
10717
+ if (!finality && destChain instanceof EvmChain) {
10670
10718
  const hyperbridgeSubstrate = hyperbridge;
10671
10719
  const currentEpoch = await destChain.currentEpoch();
10672
10720
  const consensusResult = await waitOrAbort(this.ctx, {
10673
10721
  signal,
10674
10722
  promise: () => hyperbridgeSubstrate.queryConsensusProofs(neededHeight, currentEpoch)
10675
10723
  });
10676
- const commitment = postRequestCommitment(request).commitment;
10677
10724
  this.logger.trace(
10678
10725
  `[streamFinalized] consensusProofs found (${consensusResult.proofs.length} proofs), provenHeight=${consensusResult.provenHeight}, commitment=${commitment}, dest=${request.dest}`
10679
10726
  );
@@ -10705,45 +10752,45 @@ var PostRequestClient = class {
10705
10752
  }
10706
10753
  };
10707
10754
  }
10708
- const hyperbridgeFinalized = await waitOrAbort(this.ctx, {
10709
- signal,
10710
- promise: () => this.queries.queryStateMachineUpdateByHeight({
10711
- statemachineId: stateMachineId,
10712
- height: Number(neededHeight),
10713
- chain: request.dest
10714
- })
10715
- });
10755
+ if (!finality) {
10756
+ finality = await waitOrAbort(this.ctx, {
10757
+ signal,
10758
+ promise: () => this.queries.queryStateMachineUpdateByHeight({
10759
+ statemachineId: stateMachineId,
10760
+ height: Number(neededHeight),
10761
+ chain: stateMachineId
10762
+ })
10763
+ });
10764
+ }
10716
10765
  const proof = await this.fetchProofWithRetry(
10717
10766
  signal,
10718
- () => hyperbridge.queryProof(
10719
- { Requests: [postRequestCommitment(request).commitment] },
10720
- request.dest,
10721
- BigInt(hyperbridgeFinalized.height)
10722
- )
10767
+ () => hyperbridge.queryProof({ Requests: [commitment] }, request.dest, BigInt(finality.height))
10723
10768
  );
10769
+ if (!(destChain instanceof EvmChain)) {
10770
+ const { stateId } = parseStateMachineId(stateMachineId);
10771
+ await waitForChallengePeriod(destChain, {
10772
+ height: BigInt(finality.height),
10773
+ id: { stateId, consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId }
10774
+ });
10775
+ }
10724
10776
  const calldata = destChain.encode({
10725
10777
  kind: "PostRequest",
10726
10778
  proof: {
10727
10779
  stateMachine: stateMachineId,
10728
10780
  consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10729
10781
  proof,
10730
- height: BigInt(hyperbridgeFinalized.height)
10782
+ height: BigInt(finality.height)
10731
10783
  },
10732
10784
  requests: [request],
10733
10785
  signer: pad("0x")
10734
10786
  });
10735
- const { stateId } = parseStateMachineId(stateMachineId);
10736
- await waitForChallengePeriod(destChain, {
10737
- height: BigInt(hyperbridgeFinalized.height),
10738
- id: { stateId, consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId }
10739
- });
10740
10787
  return {
10741
10788
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10742
10789
  metadata: {
10743
- blockHash: hyperbridgeFinalized.blockHash,
10744
- blockNumber: hyperbridgeFinalized.height,
10745
- transactionHash: hyperbridgeFinalized.transactionHash,
10746
- timestamp: hyperbridgeFinalized.timestamp,
10790
+ blockHash: finality.blockHash,
10791
+ blockNumber: finality.height,
10792
+ transactionHash: finality.transactionHash,
10793
+ timestamp: finality.timestamp,
10747
10794
  calldata
10748
10795
  }
10749
10796
  };
@@ -14676,6 +14723,7 @@ function orderCommitment(order) {
14676
14723
  return keccak256(encoded);
14677
14724
  }
14678
14725
  async function convertGasToFeeToken(ctx, gasEstimate, gasEstimateIn, evmChainID, gasPriceOverride) {
14726
+ if (TESTNET_CHAINS.has(evmChainID)) return 1n;
14679
14727
  const chain = ctx[gasEstimateIn];
14680
14728
  const client = chain.client;
14681
14729
  const gasPrice = gasPriceOverride ?? await retryPromise(() => client.getGasPrice(), {
@@ -14710,6 +14758,7 @@ async function convertGasToFeeToken(ctx, gasEstimate, gasEstimateIn, evmChainID,
14710
14758
  }
14711
14759
  }
14712
14760
  async function convertFeeTokenToWei(ctx, feeTokenAmount, feeTokenIn, evmChainID) {
14761
+ if (TESTNET_CHAINS.has(evmChainID)) return 1n;
14713
14762
  const chain = ctx[feeTokenIn];
14714
14763
  const client = chain.client;
14715
14764
  const wethAddr = chain.configService.getWrappedNativeAssetWithDecimals(evmChainID).asset;
@@ -14825,16 +14874,16 @@ var OrderPlacer = class {
14825
14874
  return { order, receipt };
14826
14875
  }
14827
14876
  };
14877
+
14878
+ // src/protocols/intents/OrderExecutor.ts
14828
14879
  var USED_USEROPS_STORAGE_KEY = (commitment) => `used-userops:${commitment.toLowerCase()}`;
14829
14880
  var OrderExecutor = class {
14830
- constructor(ctx, bidManager, crypto) {
14881
+ constructor(ctx, bidManager) {
14831
14882
  this.ctx = ctx;
14832
14883
  this.bidManager = bidManager;
14833
- this.crypto = crypto;
14834
14884
  }
14835
14885
  ctx;
14836
14886
  bidManager;
14837
- crypto;
14838
14887
  /**
14839
14888
  * Sleeps until the order's block deadline is reached, then yields EXPIRED.
14840
14889
  * Uses the chain's block time to calculate the sleep duration.
@@ -14905,17 +14954,6 @@ var OrderExecutor = class {
14905
14954
  }
14906
14955
  return fetchedBids;
14907
14956
  }
14908
- /**
14909
- * Selects the best bid from the provided candidates, submits the
14910
- * UserOperation, and persists the dedup entry to prevent resubmission.
14911
- */
14912
- async submitBid(params) {
14913
- const { order, freshBids, sessionPrivateKey, commitment, usedUserOps, userOpHashKey } = params;
14914
- const result = await this.bidManager.selectBid(order, freshBids, sessionPrivateKey);
14915
- usedUserOps.add(userOpHashKey(result.userOp));
14916
- await this.persistUsedUserOps(commitment, usedUserOps);
14917
- return result;
14918
- }
14919
14957
  /**
14920
14958
  * Processes a fill result and returns updated fill accumulators,
14921
14959
  * the status update to yield (if any), and whether the order is
@@ -14983,7 +15021,15 @@ var OrderExecutor = class {
14983
15021
  }
14984
15022
  /**
14985
15023
  * Executes an intent order by racing bid polling against the order's
14986
- * block deadline. Yields status updates at each lifecycle stage.
15024
+ * block deadline. Yields status updates at each lifecycle stage and hands
15025
+ * bid selection to the consumer.
15026
+ *
15027
+ * This is a **bidirectional** generator: when it yields `BIDS_RECEIVED`, the
15028
+ * consumer picks a bid, calls `bid.execute()`, and feeds the resulting
15029
+ * {@link SelectBidResult} back via `gen.next(result)`. The generator then
15030
+ * records the dedup entry, emits `BID_SELECTED`, tracks the fill, and either
15031
+ * terminates or continues polling for the remaining amount. Feeding back
15032
+ * `undefined` (no bid executed this round) causes it to keep polling.
14987
15033
  *
14988
15034
  * **Same-chain:** `AWAITING_BIDS` → `BIDS_RECEIVED` → `BID_SELECTED`
14989
15035
  * → (`FILLED` | `PARTIAL_FILL`)* → (`FILLED` | `EXPIRED`)
@@ -14994,7 +15040,6 @@ var OrderExecutor = class {
14994
15040
  async *executeOrder(options) {
14995
15041
  const { order, sessionPrivateKey, auctionTimeMs, pollIntervalMs = DEFAULT_POLL_INTERVAL, solver } = options;
14996
15042
  const commitment = order.id;
14997
- order.source === order.destination;
14998
15043
  if (!this.ctx.intentsCoprocessor) {
14999
15044
  yield { status: "FAILED", error: "IntentsCoprocessor required for order execution" };
15000
15045
  return;
@@ -15022,11 +15067,24 @@ var OrderExecutor = class {
15022
15067
  remainingAssets
15023
15068
  });
15024
15069
  const deadlineTimeout = this.deadlineStream(order.deadline, commitment);
15025
- const combined = mergeRace(deadlineTimeout, executionStream);
15070
+ const deadlinePromise = deadlineTimeout.next();
15026
15071
  try {
15027
- for await (const update of combined) {
15028
- yield update;
15029
- if (update.status === "EXPIRED" || update.status === "FILLED") return;
15072
+ let input;
15073
+ while (true) {
15074
+ const winner = input !== void 0 ? { from: "exec", r: await executionStream.next(input) } : await Promise.race([
15075
+ executionStream.next(void 0).then((r) => ({ from: "exec", r })),
15076
+ deadlinePromise.then((r) => ({ from: "deadline", r }))
15077
+ ]);
15078
+ input = void 0;
15079
+ if (winner.from === "deadline") {
15080
+ if (!winner.r.done && winner.r.value) yield winner.r.value;
15081
+ return;
15082
+ }
15083
+ const { value, done } = winner.r;
15084
+ if (done) return;
15085
+ const fed = yield value;
15086
+ if (value.status === "BIDS_RECEIVED") input = fed;
15087
+ if (value.status === "EXPIRED" || value.status === "FILLED") return;
15030
15088
  }
15031
15089
  } finally {
15032
15090
  console.log(`[OrderExecutor] Tearing down streams for commitment=${commitment}`);
@@ -15035,9 +15093,16 @@ var OrderExecutor = class {
15035
15093
  }
15036
15094
  }
15037
15095
  /**
15038
- * Core execution loop that polls for bids, submits UserOperations,
15039
- * and tracks fill progress. Yields between each poll iteration so
15040
- * that `mergeRace` can interleave the deadline stream.
15096
+ * Core execution loop that polls for bids and tracks fill progress. Builds
15097
+ * first-class {@link Bid} objects from the raw filler bids and yields them to
15098
+ * the consumer, which picks one, calls `bid.execute()`, and feeds the result
15099
+ * back via `gen.next(result)`. The loop then records the dedup entry, emits
15100
+ * `BID_SELECTED`, processes the fill, and continues polling for the remaining
15101
+ * amount on partial fills.
15102
+ *
15103
+ * Bidirectional: the value passed to `.next()` after a `BIDS_RECEIVED` yield is
15104
+ * the {@link SelectBidResult} from the executed bid (or `undefined` to skip the
15105
+ * round and keep polling).
15041
15106
  */
15042
15107
  async *executionStream(params) {
15043
15108
  const {
@@ -15052,12 +15117,7 @@ var OrderExecutor = class {
15052
15117
  targetAssets
15053
15118
  } = params;
15054
15119
  let { totalFilledAssets, remainingAssets } = params;
15055
- const MAX_BID_ATTEMPTS = 2;
15056
- const bidFailCounts = /* @__PURE__ */ new Map();
15057
- const isFreshBid = (bid) => {
15058
- const key = userOpHashKey(bid.userOp);
15059
- return !usedUserOps.has(key) && (bidFailCounts.get(key) ?? 0) < MAX_BID_ATTEMPTS;
15060
- };
15120
+ const isFreshBid = (bid) => !usedUserOps.has(userOpHashKey(bid.userOp));
15061
15121
  const solverLockStartTime = Date.now();
15062
15122
  yield { status: "AWAITING_BIDS", commitment, totalFilledAssets, remainingAssets };
15063
15123
  try {
@@ -15066,13 +15126,13 @@ var OrderExecutor = class {
15066
15126
  while (Date.now() < auctionEnd) {
15067
15127
  try {
15068
15128
  const bids = await this.fetchBids({ commitment, solver, solverLockStartTime });
15069
- const freshBids = bids.filter((bid) => !usedUserOps.has(userOpHashKey(bid.userOp)));
15070
- const newBids = freshBids.filter((bid) => !auctionSeenBids.has(userOpHashKey(bid.userOp)));
15071
- if (newBids.length > 0) {
15072
- for (const bid of newBids) {
15073
- auctionSeenBids.add(userOpHashKey(bid.userOp));
15074
- }
15075
- yield { status: "NEW_BID", commitment, bidCount: freshBids.length, bids: freshBids };
15129
+ const newBids = bids.filter(
15130
+ (bid) => isFreshBid(bid) && !auctionSeenBids.has(userOpHashKey(bid.userOp))
15131
+ );
15132
+ for (const fillerBid of newBids) {
15133
+ auctionSeenBids.add(userOpHashKey(fillerBid.userOp));
15134
+ const [bid] = this.bidManager.buildBids(order, [fillerBid], sessionPrivateKey);
15135
+ if (bid) yield { status: "NEW_BID", commitment, bid };
15076
15136
  }
15077
15137
  } catch {
15078
15138
  }
@@ -15084,8 +15144,8 @@ var OrderExecutor = class {
15084
15144
  while (true) {
15085
15145
  let freshBids;
15086
15146
  try {
15087
- const bids = await this.fetchBids({ commitment, solver, solverLockStartTime });
15088
- freshBids = bids.filter(isFreshBid);
15147
+ const bids2 = await this.fetchBids({ commitment, solver, solverLockStartTime });
15148
+ freshBids = bids2.filter(isFreshBid);
15089
15149
  } catch {
15090
15150
  await sleep(pollIntervalMs);
15091
15151
  continue;
@@ -15094,56 +15154,33 @@ var OrderExecutor = class {
15094
15154
  await sleep(pollIntervalMs);
15095
15155
  continue;
15096
15156
  }
15097
- yield { status: "BIDS_RECEIVED", commitment, bidCount: freshBids.length, bids: freshBids };
15098
- let submitResult;
15099
- try {
15100
- submitResult = await this.submitBid({
15101
- order,
15102
- freshBids,
15103
- sessionPrivateKey,
15104
- commitment,
15105
- usedUserOps,
15106
- userOpHashKey
15107
- });
15108
- } catch (err) {
15109
- yield {
15110
- status: "FAILED",
15111
- commitment,
15112
- totalFilledAssets,
15113
- remainingAssets,
15114
- error: `Failed to select bid and submit: ${err instanceof Error ? err.message : String(err)}`
15115
- };
15116
- try {
15117
- const sorted = await this.bidManager.validateAndSortBids(freshBids, order);
15118
- if (sorted.length > 0) {
15119
- const key = userOpHashKey(sorted[0].bid.userOp);
15120
- bidFailCounts.set(key, (bidFailCounts.get(key) ?? 0) + 1);
15121
- }
15122
- } catch {
15123
- }
15157
+ const bids = this.bidManager.buildBids(order, freshBids, sessionPrivateKey);
15158
+ if (bids.length === 0) {
15159
+ await sleep(pollIntervalMs);
15160
+ continue;
15161
+ }
15162
+ const result = yield { status: "BIDS_RECEIVED", commitment, bidCount: bids.length, bids };
15163
+ if (!result) {
15124
15164
  await sleep(pollIntervalMs);
15125
15165
  continue;
15126
15166
  }
15167
+ usedUserOps.add(userOpHashKey(result.userOp));
15168
+ await this.persistUsedUserOps(commitment, usedUserOps);
15127
15169
  yield {
15128
15170
  status: "BID_SELECTED",
15129
15171
  commitment,
15130
- selectedSolver: submitResult.solverAddress,
15131
- userOpHash: submitResult.userOpHash,
15132
- userOp: submitResult.userOp,
15133
- transactionHash: submitResult.txnHash
15172
+ selectedSolver: result.solverAddress,
15173
+ userOpHash: result.userOpHash,
15174
+ userOp: result.userOp,
15175
+ transactionHash: result.txnHash
15134
15176
  };
15135
- const fill = this.processFillResult(
15136
- submitResult,
15137
- commitment,
15138
- targetAssets,
15139
- totalFilledAssets,
15140
- remainingAssets
15141
- );
15177
+ const fill = this.processFillResult(result, commitment, targetAssets, totalFilledAssets, remainingAssets);
15142
15178
  totalFilledAssets = fill.totalFilledAssets;
15143
15179
  remainingAssets = fill.remainingAssets;
15144
15180
  if (fill.update) {
15145
15181
  yield fill.update;
15146
15182
  }
15183
+ if (fill.done) return;
15147
15184
  }
15148
15185
  } catch (err) {
15149
15186
  yield {
@@ -15618,183 +15655,148 @@ var OrderCanceller = class {
15618
15655
  return feeInDestFeeToken * 1005n / 1000n;
15619
15656
  }
15620
15657
  };
15621
- var BidManager = class {
15622
- /**
15623
- * @param ctx - Shared IntentsV2 context providing the destination chain
15624
- * client, coprocessor, bundler URL, and session-key storage.
15625
- * @param crypto - Crypto utilities used for gas packing, UserOp hashing,
15626
- * EIP-712 signing, and bundler calls.
15627
- */
15628
- constructor(ctx, crypto) {
15629
- this.ctx = ctx;
15630
- this.crypto = crypto;
15631
- }
15658
+ var BidImpl = class {
15659
+ solverAddress;
15660
+ outputs;
15661
+ relayerFee;
15662
+ nativeDispatchFee;
15663
+ userOp;
15632
15664
  ctx;
15633
15665
  crypto;
15634
- /**
15635
- * Constructs a signed `PackedUserOperation` that a solver can submit to the
15636
- * Hyperbridge coprocessor as a bid to fill an order.
15637
- *
15638
- * The solver's signature covers a hash that binds the UserOperation to the
15639
- * order commitment and the session key address, so the IntentGatewayV2
15640
- * contract can verify the solver's intent on-chain.
15641
- *
15642
- * @param options - Parameters describing the solver account, gas limits, fee
15643
- * market values, and pre-built `callData` for the fill operation.
15644
- * @returns A `PackedUserOperation` with the solver's signature prepended
15645
- * with the order commitment.
15646
- */
15647
- async prepareSubmitBid(options) {
15648
- const {
15649
- order,
15650
- solverAccount,
15651
- solverSigner,
15652
- nonce,
15653
- entryPointAddress,
15654
- callGasLimit,
15655
- verificationGasLimit,
15656
- preVerificationGas,
15657
- maxFeePerGas,
15658
- maxPriorityFeePerGas,
15659
- callData,
15660
- paymasterAndData = "0x"
15661
- } = options;
15662
- const chainId = BigInt(
15666
+ order;
15667
+ fillOptions;
15668
+ priceOutputs;
15669
+ sessionPrivateKey;
15670
+ intentGatewayV2Address;
15671
+ domainSeparator;
15672
+ /** Cached session-key signature over the `SelectSolver` message. */
15673
+ cachedSignature;
15674
+ constructor(params) {
15675
+ this.ctx = params.ctx;
15676
+ this.crypto = params.crypto;
15677
+ this.order = params.order;
15678
+ this.fillOptions = params.fillOptions;
15679
+ this.priceOutputs = params.priceOutputs;
15680
+ this.sessionPrivateKey = params.sessionPrivateKey;
15681
+ this.solverAddress = params.fillerBid.userOp.sender;
15682
+ this.outputs = params.fillOptions.outputs;
15683
+ this.relayerFee = params.fillOptions.relayerFee;
15684
+ this.nativeDispatchFee = params.fillOptions.nativeDispatchFee;
15685
+ this.userOp = params.fillerBid.userOp;
15686
+ this.intentGatewayV2Address = this.ctx.dest.configService.getIntentGatewayAddress(
15687
+ normalizeStateMachineId(this.order.destination)
15688
+ );
15689
+ this.domainSeparator = CryptoUtils.getDomainSeparator(
15690
+ "IntentGateway",
15691
+ "2",
15692
+ this.chainId(),
15693
+ this.intentGatewayV2Address
15694
+ );
15695
+ }
15696
+ /** Resolves the destination chain id from the client or the state-machine id. */
15697
+ chainId() {
15698
+ return BigInt(
15663
15699
  this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15664
15700
  );
15665
- const accountGasLimits = CryptoUtils.packGasLimits(verificationGasLimit, callGasLimit);
15666
- const gasFees = CryptoUtils.packGasFees(maxPriorityFeePerGas, maxFeePerGas);
15667
- const userOp = {
15668
- sender: solverAccount,
15669
- nonce,
15670
- initCode: "0x",
15671
- callData,
15672
- accountGasLimits,
15673
- preVerificationGas,
15674
- gasFees,
15675
- paymasterAndData,
15676
- signature: "0x"
15677
- };
15678
- const userOpHash = CryptoUtils.computeUserOpHash(userOp, entryPointAddress, chainId);
15679
- const sessionKey = order.session;
15680
- const messageHash = keccak256(concat([userOpHash, order.id, sessionKey]));
15681
- const solverSignature = await solverSigner.signMessage(messageHash, Number(chainId));
15682
- const signature = concat([order.id, solverSignature]);
15683
- return { ...userOp, signature };
15684
15701
  }
15685
15702
  /**
15686
- * Selects the best available bid, simulates it on-chain, signs the
15687
- * solver-selection EIP-712 message with the session key, and submits the
15688
- * UserOperation to the bundler.
15689
- *
15690
- * **Selection algorithm:**
15691
- * 1. Decodes `fillOrder` calldata from each bid's `callData`.
15692
- * 2. Sorts bids by output value (single-output: amount; all-stables: normalised
15693
- * USD; mixed: DEX-quoted USD; fallback: raw amount).
15694
- * 3. Iterates sorted bids, simulating each with `eth_call` until one passes.
15695
- * 4. Appends the session-key's `SelectSolver` signature to the solver's
15696
- * existing signature and submits via `eth_sendUserOperation`.
15697
- * 5. For same-chain orders, waits for the transaction receipt and reads
15698
- * `OrderFilled` / `PartialFill` events to determine fill status.
15703
+ * Resolves the session key, signs the `SelectSolver` message for this bid's
15704
+ * solver, and caches the signature. Signs at most once per bid.
15699
15705
  *
15700
- * @param order - The placed order for which to select a bid.
15701
- * @param bids - Raw bids fetched from the Hyperbridge coprocessor.
15702
- * @param sessionPrivateKey - Optional override; if omitted, the key is
15703
- * looked up from `sessionKeyStorage` using `order.session`.
15704
- * @returns A {@link SelectBidResult} containing the submitted UserOperation,
15705
- * its hash, the winning solver address, transaction hash, and fill status.
15706
- * @throws If the session key is not found, no valid bids exist, all
15707
- * simulations fail, or the bundler rejects the UserOperation.
15706
+ * @throws If the session key is missing or signing fails.
15708
15707
  */
15709
- async selectBid(order, bids, sessionPrivateKey) {
15710
- const commitment = order.id;
15711
- const sessionKeyAddress = order.session;
15712
- console.log(`[BidManager] selectBid called for commitment=${commitment}, received ${bids.length} bid(s)`);
15713
- const sessionKeyData = sessionPrivateKey ? { privateKey: sessionPrivateKey } : await this.ctx.sessionKeyStorage.getSessionKeyByAddress(sessionKeyAddress);
15708
+ async signSelection() {
15709
+ if (this.cachedSignature) return this.cachedSignature;
15710
+ const commitment = this.order.id;
15711
+ const sessionKeyAddress = this.order.session;
15712
+ const sessionKeyData = this.sessionPrivateKey ? { privateKey: this.sessionPrivateKey } : await this.ctx.sessionKeyStorage.getSessionKeyByAddress(sessionKeyAddress);
15714
15713
  if (!sessionKeyData) {
15715
15714
  throw new Error("SessionKey not found for commitment: " + commitment);
15716
15715
  }
15717
- if (!this.ctx.bundlerUrl) {
15718
- throw new Error("Bundler URL not configured");
15716
+ const signature = await CryptoUtils.signSolverSelection(
15717
+ commitment,
15718
+ this.solverAddress,
15719
+ this.domainSeparator,
15720
+ sessionKeyData.privateKey
15721
+ );
15722
+ if (!signature) {
15723
+ throw new Error("Failed to sign solver selection");
15719
15724
  }
15720
- if (!this.ctx.intentsCoprocessor) {
15721
- throw new Error("IntentsCoprocessor required");
15722
- }
15723
- const sortedBids = await this.validateAndSortBids(bids, order);
15724
- console.log(`[BidManager] ${sortedBids.length}/${bids.length} bid(s) passed validation and sorting`);
15725
- if (sortedBids.length === 0) {
15726
- throw new Error("No valid bids found");
15727
- }
15728
- const intentGatewayV2Address = this.ctx.dest.configService.getIntentGatewayAddress(
15729
- normalizeStateMachineId(order.destination)
15730
- );
15731
- const domainSeparator = CryptoUtils.getDomainSeparator(
15732
- "IntentGateway",
15733
- "2",
15734
- BigInt(
15735
- this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15736
- ),
15737
- intentGatewayV2Address
15725
+ this.cachedSignature = signature;
15726
+ return signature;
15727
+ }
15728
+ /**
15729
+ * Simulates this bid on-chain by batching the `select` and `fillOrder` calls
15730
+ * via `eth_call` from the solver's account, using the IntentGatewayV2 ERC-7821
15731
+ * batch-execute pattern.
15732
+ *
15733
+ * The native value forwarded to the simulation is the sum of any native-token
15734
+ * (`address(0)`) output amounts plus the Hyperbridge dispatch fee.
15735
+ *
15736
+ * @throws If the `eth_call` simulation reverts or errors.
15737
+ */
15738
+ async simulate() {
15739
+ const signature = await this.signSelection();
15740
+ const selectOptions = {
15741
+ commitment: this.order.id,
15742
+ solver: this.solverAddress,
15743
+ signature
15744
+ };
15745
+ const nativeOutputs = this.fillOptions.outputs.reduce(
15746
+ (acc, o) => bytes32ToBytes20(o.token) === ADDRESS_ZERO2 ? acc + o.amount : acc,
15747
+ 0n
15738
15748
  );
15739
- let selectedBid = null;
15740
- let sessionSignature = null;
15741
- console.log(`[BidManager] Simulating ${sortedBids.length} sorted bid(s) to find a valid one`);
15742
- for (let idx = 0; idx < sortedBids.length; idx++) {
15743
- const bidWithOptions = sortedBids[idx];
15744
- const solverAddress2 = bidWithOptions.bid.userOp.sender;
15745
- console.log(`[BidManager] Simulating bid ${idx + 1}/${sortedBids.length} from solver=${solverAddress2}`);
15746
- const signature = await CryptoUtils.signSolverSelection(
15747
- commitment,
15748
- solverAddress2,
15749
- domainSeparator,
15750
- sessionKeyData.privateKey
15751
- );
15752
- if (!signature) {
15753
- console.warn(`[BidManager] Bid ${idx + 1}: failed to sign solver selection, skipping`);
15754
- continue;
15755
- }
15756
- const selectOptions = {
15757
- commitment,
15758
- solver: solverAddress2,
15759
- signature
15760
- };
15761
- try {
15762
- await this.simulate(bidWithOptions.bid, bidWithOptions.options, selectOptions, intentGatewayV2Address);
15763
- console.log(`[BidManager] Bid ${idx + 1} from solver=${solverAddress2}: simulation PASSED`);
15764
- selectedBid = bidWithOptions;
15765
- sessionSignature = signature;
15766
- break;
15767
- } catch (err) {
15768
- console.warn(
15769
- `[BidManager] Bid ${idx + 1} from solver=${solverAddress2}: simulation FAILED: ${err instanceof Error ? err.message : String(err)}`
15770
- );
15771
- continue;
15772
- }
15749
+ const simulationValue = nativeOutputs + this.fillOptions.nativeDispatchFee;
15750
+ const selectCalldata = encodeFunctionData({
15751
+ abi: ABI3,
15752
+ functionName: "select",
15753
+ args: [selectOptions]
15754
+ });
15755
+ const calls = [
15756
+ { target: this.intentGatewayV2Address, value: 0n, data: selectCalldata },
15757
+ { target: this.solverAddress, value: simulationValue, data: this.userOp.callData }
15758
+ ];
15759
+ const batchedCalldata = this.crypto.encodeERC7821Execute(calls);
15760
+ try {
15761
+ await this.ctx.dest.client.call({
15762
+ account: this.solverAddress,
15763
+ to: this.solverAddress,
15764
+ data: batchedCalldata,
15765
+ value: simulationValue
15766
+ });
15767
+ } catch (e) {
15768
+ throw new Error(`Simulation failed: ${e instanceof Error ? e.message : String(e)}`);
15773
15769
  }
15774
- if (!selectedBid || !sessionSignature) {
15775
- console.error(`[BidManager] All ${sortedBids.length} bid(s) failed simulation for commitment=${commitment}`);
15776
- throw new Error("No bids passed simulation");
15770
+ }
15771
+ /**
15772
+ * Signs the `SelectSolver` message with the session key, appends it to the
15773
+ * solver's existing UserOp signature, and submits the UserOperation to the
15774
+ * bundler. For same-chain orders, waits for the receipt and reads
15775
+ * `OrderFilled` / `PartialFill` logs to determine fill status.
15776
+ *
15777
+ * @returns A {@link SelectBidResult} with the submitted UserOperation, its hash,
15778
+ * the solver address, transaction hash, and fill status.
15779
+ * @throws If the bundler is not configured, the session key is missing, or the
15780
+ * bundler rejects the UserOperation.
15781
+ */
15782
+ async execute() {
15783
+ const commitment = this.order.id;
15784
+ if (!this.ctx.bundlerUrl) {
15785
+ throw new Error("Bundler URL not configured");
15777
15786
  }
15778
- const solverAddress = selectedBid.bid.userOp.sender;
15779
- const finalSignature = concat([
15780
- selectedBid.bid.userOp.signature,
15781
- sessionSignature
15782
- ]);
15787
+ const sessionSignature = await this.signSelection();
15788
+ const finalSignature = concat([this.userOp.signature, sessionSignature]);
15783
15789
  const signedUserOp = {
15784
- ...selectedBid.bid.userOp,
15790
+ ...this.userOp,
15785
15791
  signature: finalSignature
15786
15792
  };
15787
15793
  const entryPointAddress = this.ctx.dest.configService.getEntryPointV08Address(
15788
- normalizeStateMachineId(order.destination)
15794
+ normalizeStateMachineId(this.order.destination)
15789
15795
  );
15790
- BigInt(
15791
- this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15792
- );
15793
- const bundlerResult = await this.crypto.sendBundler(BundlerMethod.ETH_SEND_USER_OPERATION, [
15796
+ const userOpHash = await this.crypto.sendBundler(BundlerMethod.ETH_SEND_USER_OPERATION, [
15794
15797
  CryptoUtils.prepareBundlerCall(signedUserOp),
15795
15798
  entryPointAddress
15796
15799
  ]);
15797
- const userOpHash = bundlerResult;
15798
15800
  let txnHash;
15799
15801
  let fillStatus;
15800
15802
  let filledAssets;
@@ -15810,7 +15812,7 @@ var BidManager = class {
15810
15812
  { maxRetries: 5, backoffMs: 2e3, logMessage: "Fetching user operation receipt" }
15811
15813
  );
15812
15814
  txnHash = receipt.receipt.transactionHash;
15813
- if (order.source === order.destination) {
15815
+ if (this.order.source === this.order.destination) {
15814
15816
  try {
15815
15817
  const chainReceipt = await this.ctx.dest.client.waitForTransactionReceipt({
15816
15818
  hash: txnHash,
@@ -15839,12 +15841,12 @@ var BidManager = class {
15839
15841
  }
15840
15842
  }
15841
15843
  } catch (err) {
15842
- throw new Error(`Failed to select bid: ${err instanceof Error ? err.message : String(err)}`);
15844
+ throw new Error(`Failed to execute bid: ${err instanceof Error ? err.message : String(err)}`);
15843
15845
  }
15844
15846
  return {
15845
15847
  userOp: signedUserOp,
15846
15848
  userOpHash,
15847
- solverAddress,
15849
+ solverAddress: this.solverAddress,
15848
15850
  commitment,
15849
15851
  txnHash,
15850
15852
  fillStatus,
@@ -15852,7 +15854,177 @@ var BidManager = class {
15852
15854
  };
15853
15855
  }
15854
15856
  /**
15855
- * Validates and sorts a list of raw bids for the given order.
15857
+ * Prices this bid's outputs in USD using the destination chain's DEX-quote
15858
+ * helpers. Returns `null` when any output token cannot be priced.
15859
+ */
15860
+ async outputUsdValue() {
15861
+ return this.priceOutputs(this.outputs);
15862
+ }
15863
+ };
15864
+ var BidManager = class {
15865
+ /**
15866
+ * @param ctx - Shared IntentsV2 context providing the destination chain
15867
+ * client, coprocessor, bundler URL, and session-key storage.
15868
+ * @param crypto - Crypto utilities used for gas packing, UserOp hashing,
15869
+ * EIP-712 signing, and bundler calls.
15870
+ */
15871
+ constructor(ctx, crypto) {
15872
+ this.ctx = ctx;
15873
+ this.crypto = crypto;
15874
+ }
15875
+ ctx;
15876
+ crypto;
15877
+ /**
15878
+ * Constructs a signed `PackedUserOperation` that a solver can submit to the
15879
+ * Hyperbridge coprocessor as a bid to fill an order.
15880
+ *
15881
+ * The solver's signature covers a hash that binds the UserOperation to the
15882
+ * order commitment and the session key address, so the IntentGatewayV2
15883
+ * contract can verify the solver's intent on-chain.
15884
+ *
15885
+ * @param options - Parameters describing the solver account, gas limits, fee
15886
+ * market values, and pre-built `callData` for the fill operation.
15887
+ * @returns A `PackedUserOperation` with the solver's signature prepended
15888
+ * with the order commitment.
15889
+ */
15890
+ async prepareSubmitBid(options) {
15891
+ const {
15892
+ order,
15893
+ solverAccount,
15894
+ solverSigner,
15895
+ nonce,
15896
+ entryPointAddress,
15897
+ callGasLimit,
15898
+ verificationGasLimit,
15899
+ preVerificationGas,
15900
+ maxFeePerGas,
15901
+ maxPriorityFeePerGas,
15902
+ callData,
15903
+ paymasterAndData = "0x"
15904
+ } = options;
15905
+ const chainId = BigInt(
15906
+ this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15907
+ );
15908
+ const accountGasLimits = CryptoUtils.packGasLimits(verificationGasLimit, callGasLimit);
15909
+ const gasFees = CryptoUtils.packGasFees(maxPriorityFeePerGas, maxFeePerGas);
15910
+ const userOp = {
15911
+ sender: solverAccount,
15912
+ nonce,
15913
+ initCode: "0x",
15914
+ callData,
15915
+ accountGasLimits,
15916
+ preVerificationGas,
15917
+ gasFees,
15918
+ paymasterAndData,
15919
+ signature: "0x"
15920
+ };
15921
+ const userOpHash = CryptoUtils.computeUserOpHash(userOp, entryPointAddress, chainId);
15922
+ const sessionKey = order.session;
15923
+ const messageHash = keccak256(concat([userOpHash, order.id, sessionKey]));
15924
+ const solverSignature = await solverSigner.signMessage(messageHash, Number(chainId));
15925
+ const signature = concat([order.id, solverSignature]);
15926
+ return { ...userOp, signature };
15927
+ }
15928
+ /**
15929
+ * Decodes raw filler bids into first-class {@link Bid} objects.
15930
+ *
15931
+ * Each bid's `fillOrder` fill-options are decoded from its ERC-7821 calldata;
15932
+ * bids whose calldata cannot be decoded into a valid `fillOrder` call are
15933
+ * silently dropped with a warning. The returned `Bid` instances are ready to
15934
+ * be ranked, simulated, and executed by the consumer.
15935
+ *
15936
+ * @param order - The placed order the bids are competing to fill.
15937
+ * @param bids - Raw filler bids fetched from the coprocessor.
15938
+ * @param sessionPrivateKey - Optional session-key override; looked up from
15939
+ * storage by `order.session` if omitted.
15940
+ * @returns Array of executable `Bid` objects (one per successfully decoded bid).
15941
+ */
15942
+ buildBids(order, bids, sessionPrivateKey) {
15943
+ const chainId = this.ctx.dest.config.stateMachineId;
15944
+ const priceOutputs = (outputs) => this.computeOutputsUsdValue(outputs, chainId);
15945
+ const result = [];
15946
+ for (const fillerBid of bids) {
15947
+ const fillOptions = this.decodeBidFillOptions(fillerBid);
15948
+ if (!fillOptions) {
15949
+ console.warn(`[BidManager] Failed to decode fillOptions from bid by solver=${fillerBid.userOp.sender}`);
15950
+ continue;
15951
+ }
15952
+ result.push(
15953
+ new BidImpl({
15954
+ ctx: this.ctx,
15955
+ crypto: this.crypto,
15956
+ order,
15957
+ fillerBid,
15958
+ fillOptions,
15959
+ priceOutputs,
15960
+ sessionPrivateKey
15961
+ })
15962
+ );
15963
+ }
15964
+ console.log(`[BidManager] Built ${result.length}/${bids.length} bid(s) successfully`);
15965
+ return result;
15966
+ }
15967
+ /**
15968
+ * Decodes raw filler bids, sorts them, simulates each until one passes, signs
15969
+ * the `SelectSolver` message, and submits — all with no per-bid input from the
15970
+ * caller.
15971
+ *
15972
+ * Equivalent to `selectAndExecuteBest(order, buildBids(order, bids, key))`.
15973
+ *
15974
+ * @param order - The placed order to fill.
15975
+ * @param bids - Raw filler bids fetched from the coprocessor.
15976
+ * @param sessionPrivateKey - Optional session-key override; looked up from
15977
+ * storage by `order.session` if omitted.
15978
+ * @returns A {@link SelectBidResult} for the executed bid.
15979
+ */
15980
+ async selectBid(order, bids, sessionPrivateKey) {
15981
+ return this.selectAndExecuteBest(order, this.buildBids(order, bids, sessionPrivateKey));
15982
+ }
15983
+ /**
15984
+ * Autopilot bid selection: sorts the given bids by output value, simulates
15985
+ * each in order until one passes, then executes that bid. For consumers that
15986
+ * do not need custom selection logic.
15987
+ *
15988
+ * @param order - The placed order to fill.
15989
+ * @param bids - Candidate bids (from {@link buildBids}).
15990
+ * @returns A {@link SelectBidResult} for the executed bid.
15991
+ * @throws If no valid bids exist, all simulations fail, or the bundler rejects
15992
+ * the UserOperation.
15993
+ */
15994
+ async selectAndExecuteBest(order, bids) {
15995
+ const commitment = order.id;
15996
+ console.log(`[BidManager] selectAndExecuteBest called for commitment=${commitment}, ${bids.length} bid(s)`);
15997
+ if (!this.ctx.bundlerUrl) {
15998
+ throw new Error("Bundler URL not configured");
15999
+ }
16000
+ if (!this.ctx.intentsCoprocessor) {
16001
+ throw new Error("IntentsCoprocessor required");
16002
+ }
16003
+ const sortedBids = await this.sortBids(order, bids);
16004
+ console.log(`[BidManager] ${sortedBids.length}/${bids.length} bid(s) passed validation and sorting`);
16005
+ if (sortedBids.length === 0) {
16006
+ throw new Error("No valid bids found");
16007
+ }
16008
+ console.log(`[BidManager] Simulating ${sortedBids.length} sorted bid(s) to find a valid one`);
16009
+ for (let idx = 0; idx < sortedBids.length; idx++) {
16010
+ const bid = sortedBids[idx];
16011
+ console.log(`[BidManager] Simulating bid ${idx + 1}/${sortedBids.length} from solver=${bid.solverAddress}`);
16012
+ try {
16013
+ await bid.simulate();
16014
+ } catch (err) {
16015
+ console.warn(
16016
+ `[BidManager] Bid ${idx + 1} from solver=${bid.solverAddress}: simulation FAILED: ${err instanceof Error ? err.message : String(err)}`
16017
+ );
16018
+ continue;
16019
+ }
16020
+ console.log(`[BidManager] Bid ${idx + 1} from solver=${bid.solverAddress}: simulation PASSED`);
16021
+ return bid.execute();
16022
+ }
16023
+ console.error(`[BidManager] All ${sortedBids.length} bid(s) failed simulation for commitment=${commitment}`);
16024
+ throw new Error("No bids passed simulation");
16025
+ }
16026
+ /**
16027
+ * Sorts a list of bids for the given order by output value.
15856
16028
  *
15857
16029
  * Delegates to one of three strategies based on the order's output token
15858
16030
  * composition:
@@ -15861,47 +16033,26 @@ var BidManager = class {
15861
16033
  * - Mixed outputs: sort by DEX-quoted USD value descending, with a raw-amount
15862
16034
  * fallback if pricing fails.
15863
16035
  *
15864
- * @param bids - Raw filler bids from the coprocessor.
16036
+ * Bids that cannot satisfy the order's token set are dropped.
16037
+ *
15865
16038
  * @param order - The placed order whose output spec drives sorting logic.
15866
- * @returns Sorted array of `{ bid, options }` pairs ready for simulation.
16039
+ * @param bids - Executable bids to sort (from {@link buildBids}).
16040
+ * @returns Sorted array of `Bid` objects ready for simulation.
15867
16041
  */
15868
- async validateAndSortBids(bids, order) {
16042
+ async sortBids(order, bids) {
15869
16043
  const outputs = order.output.assets;
15870
- const decodedBids = this.decodeBids(bids);
15871
16044
  if (outputs.length <= 1) {
15872
16045
  console.log(`[BidManager] Using single-output sorting (1 output asset)`);
15873
- return this.sortSingleOutput(decodedBids, outputs[0]);
16046
+ return this.sortSingleOutput(bids, outputs[0]);
15874
16047
  }
15875
16048
  const chainId = this.ctx.dest.config.stateMachineId;
15876
16049
  const allStables = outputs.every((o) => this.isStableToken(bytes32ToBytes20(o.token), chainId));
15877
16050
  if (allStables) {
15878
16051
  console.log(`[BidManager] Using all-stables sorting (${outputs.length} stable output assets)`);
15879
- return this.sortAllStables(decodedBids, outputs, chainId);
16052
+ return this.sortAllStables(bids, outputs, chainId);
15880
16053
  }
15881
16054
  console.log(`[BidManager] Using mixed-output sorting (${outputs.length} output assets, some non-stable)`);
15882
- return this.sortMixedOutputs(decodedBids, outputs, chainId);
15883
- }
15884
- /**
15885
- * Decodes the `fillOrder` fill-options from each bid's ERC-7821 calldata.
15886
- *
15887
- * Bids whose calldata cannot be decoded or do not contain a valid
15888
- * `fillOrder` call are silently dropped with a warning.
15889
- *
15890
- * @param bids - Raw bids to decode.
15891
- * @returns Array of successfully decoded `{ bid, options }` pairs.
15892
- */
15893
- decodeBids(bids) {
15894
- const result = [];
15895
- for (const bid of bids) {
15896
- const fillOptions = this.decodeBidFillOptions(bid);
15897
- if (fillOptions) {
15898
- result.push({ bid, options: fillOptions });
15899
- } else {
15900
- console.warn(`[BidManager] Failed to decode fillOptions from bid by solver=${bid.userOp.sender}`);
15901
- }
15902
- }
15903
- console.log(`[BidManager] Decoded ${result.length}/${bids.length} bid(s) successfully`);
15904
- return result;
16055
+ return this.sortMixedOutputs(bids, outputs, chainId);
15905
16056
  }
15906
16057
  /**
15907
16058
  * Extracts the `FillOptions` struct from a single bid's ERC-7821
@@ -15934,149 +16085,103 @@ var BidManager = class {
15934
16085
  }
15935
16086
  return null;
15936
16087
  }
15937
- /**
15938
- * Simulates a bid on-chain by batching the `select` and `fillOrder` calls
15939
- * via `eth_call` from the solver's account, using the IntentGatewayV2
15940
- * ERC-7821 batch-execute pattern.
15941
- *
15942
- * The native value forwarded to the simulation is computed from the fill options:
15943
- * sum of any native-token (address(0)) output amounts plus the dispatch fee.
15944
- *
15945
- * @param bid - The filler bid to simulate.
15946
- * @param fillOptions - Decoded fill options from the bid's calldata.
15947
- * @param selectOptions - The signed solver-selection parameters.
15948
- * @param intentGatewayV2Address - Address of the IntentGatewayV2 contract on the destination chain.
15949
- * @throws If the `eth_call` simulation reverts or errors.
15950
- */
15951
- async simulate(bid, fillOptions, selectOptions, intentGatewayV2Address) {
15952
- const solverAddress = bid.userOp.sender;
15953
- const nativeOutputs = fillOptions.outputs.reduce(
15954
- (acc, o) => bytes32ToBytes20(o.token) === ADDRESS_ZERO2 ? acc + o.amount : acc,
15955
- 0n
15956
- );
15957
- const simulationValue = nativeOutputs + fillOptions.nativeDispatchFee;
15958
- const selectCalldata = encodeFunctionData({
15959
- abi: ABI3,
15960
- functionName: "select",
15961
- args: [selectOptions]
15962
- });
15963
- const calls = [
15964
- { target: intentGatewayV2Address, value: 0n, data: selectCalldata },
15965
- { target: solverAddress, value: simulationValue, data: bid.userOp.callData }
15966
- ];
15967
- const batchedCalldata = this.crypto.encodeERC7821Execute(calls);
15968
- try {
15969
- await this.ctx.dest.client.call({
15970
- account: solverAddress,
15971
- to: solverAddress,
15972
- data: batchedCalldata,
15973
- value: simulationValue
15974
- });
15975
- } catch (e) {
15976
- throw new Error(`Simulation failed: ${e instanceof Error ? e.message : String(e)}`);
15977
- }
15978
- }
15979
16088
  /**
15980
16089
  * Case A: single output token.
15981
16090
  * Filter bids by token match only, sort descending by amount.
15982
16091
  * Partial fill bids are allowed — the contract determines fill status.
15983
16092
  */
15984
- sortSingleOutput(decodedBids, requiredAsset) {
16093
+ sortSingleOutput(bids, requiredAsset) {
15985
16094
  const requiredAmount = new Decimal2(requiredAsset.amount.toString());
15986
16095
  console.log(
15987
16096
  `[BidManager] sortSingleOutput: required token=${requiredAsset.token}, amount=${requiredAmount.toString()}`
15988
16097
  );
15989
16098
  const validBids = [];
15990
- for (const { bid, options } of decodedBids) {
15991
- const bidOutput = options.outputs[0];
16099
+ for (const bid of bids) {
16100
+ const bidOutput = bid.outputs[0];
15992
16101
  const bidAmount = new Decimal2(bidOutput.amount.toString());
15993
16102
  if (bidOutput.token.toLowerCase() !== requiredAsset.token.toLowerCase()) {
15994
16103
  console.warn(
15995
- `[BidManager] Bid from solver=${bid.userOp.sender} REJECTED: token mismatch (bid=${bidOutput.token}, required=${requiredAsset.token})`
16104
+ `[BidManager] Bid from solver=${bid.solverAddress} REJECTED: token mismatch (bid=${bidOutput.token}, required=${requiredAsset.token})`
15996
16105
  );
15997
16106
  continue;
15998
16107
  }
15999
16108
  if (bidAmount.lt(requiredAmount)) {
16000
16109
  console.log(
16001
- `[BidManager] Bid from solver=${bid.userOp.sender}: partial fill candidate (bid=${bidAmount.toString()}, required=${requiredAmount.toString()}, covers=${bidAmount.div(requiredAmount).mul(100).toFixed(2)}%)`
16110
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (bid=${bidAmount.toString()}, required=${requiredAmount.toString()}, covers=${bidAmount.div(requiredAmount).mul(100).toFixed(2)}%)`
16002
16111
  );
16003
16112
  } else {
16004
16113
  console.log(
16005
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED: amount=${bidAmount.toString()} (surplus=${bidAmount.minus(requiredAmount).toString()})`
16114
+ `[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED: amount=${bidAmount.toString()} (surplus=${bidAmount.minus(requiredAmount).toString()})`
16006
16115
  );
16007
16116
  }
16008
- validBids.push({ bid, options, amount: bidOutput.amount });
16117
+ validBids.push({ bid, amount: bidOutput.amount });
16009
16118
  }
16010
16119
  validBids.sort((a, b) => {
16011
16120
  const aAmt = new Decimal2(a.amount.toString());
16012
16121
  const bAmt = new Decimal2(b.amount.toString());
16013
16122
  return bAmt.comparedTo(aAmt);
16014
16123
  });
16015
- return validBids.map(({ amount: _, ...rest }) => rest);
16124
+ return validBids.map(({ bid }) => bid);
16016
16125
  }
16017
16126
  /**
16018
16127
  * Case B: all outputs are USDC/USDT.
16019
16128
  * Sum normalised USD values (treating each stable as $1) and sort descending.
16020
16129
  * Partial fill bids are allowed.
16021
16130
  */
16022
- sortAllStables(decodedBids, orderOutputs, chainId) {
16131
+ sortAllStables(bids, orderOutputs, chainId) {
16023
16132
  const requiredUsd = this.computeStablesUsdValue(orderOutputs, chainId);
16024
16133
  console.log(`[BidManager] sortAllStables: required USD value=${requiredUsd.toString()}`);
16025
16134
  const validBids = [];
16026
- for (const { bid, options } of decodedBids) {
16027
- const bidUsd = this.computeStablesUsdValue(options.outputs, chainId);
16135
+ for (const bid of bids) {
16136
+ const bidUsd = this.computeStablesUsdValue(bid.outputs, chainId);
16028
16137
  if (bidUsd === null) {
16029
- console.warn(`[BidManager] Bid from solver=${bid.userOp.sender} REJECTED: unable to compute USD value`);
16138
+ console.warn(`[BidManager] Bid from solver=${bid.solverAddress} REJECTED: unable to compute USD value`);
16030
16139
  continue;
16031
16140
  }
16032
16141
  if (bidUsd.lt(requiredUsd)) {
16033
16142
  console.log(
16034
- `[BidManager] Bid from solver=${bid.userOp.sender}: partial fill candidate (bid=${bidUsd.toString()}, required=${requiredUsd.toString()}, covers=${bidUsd.div(requiredUsd).mul(100).toFixed(2)}%)`
16143
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (bid=${bidUsd.toString()}, required=${requiredUsd.toString()}, covers=${bidUsd.div(requiredUsd).mul(100).toFixed(2)}%)`
16035
16144
  );
16036
16145
  } else {
16037
- console.log(
16038
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED: USD value=${bidUsd.toString()}`
16039
- );
16146
+ console.log(`[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED: USD value=${bidUsd.toString()}`);
16040
16147
  }
16041
- validBids.push({ bid, options, usdValue: bidUsd });
16148
+ validBids.push({ bid, usdValue: bidUsd });
16042
16149
  }
16043
16150
  validBids.sort((a, b) => b.usdValue.comparedTo(a.usdValue));
16044
- return validBids.map(({ usdValue: _, ...rest }) => rest);
16151
+ return validBids.map(({ bid }) => bid);
16045
16152
  }
16046
16153
  /**
16047
16154
  * Case C: mixed output tokens (at least one non-stable).
16048
16155
  * Price every token via on-chain DEX quotes, fall back to raw amounts
16049
16156
  * if pricing is unavailable. Partial fill bids are allowed.
16050
16157
  */
16051
- async sortMixedOutputs(decodedBids, orderOutputs, chainId) {
16158
+ async sortMixedOutputs(bids, orderOutputs, chainId) {
16052
16159
  const requiredUsd = await this.computeOutputsUsdValue(orderOutputs, chainId);
16053
16160
  if (requiredUsd === null) {
16054
16161
  console.warn("[BidManager] sortMixedOutputs: output tokens unpriceable, falling back to raw-amount sort");
16055
- return this.sortByRawAmountFallback(decodedBids, orderOutputs);
16162
+ return this.sortByRawAmountFallback(bids, orderOutputs);
16056
16163
  }
16057
16164
  console.log(`[BidManager] sortMixedOutputs: required USD value=${requiredUsd.toString()}`);
16058
16165
  const validBids = [];
16059
- for (const { bid, options } of decodedBids) {
16060
- const bidUsd = await this.computeOutputsUsdValue(options.outputs, chainId);
16166
+ for (const bid of bids) {
16167
+ const bidUsd = await this.computeOutputsUsdValue(bid.outputs, chainId);
16061
16168
  if (bidUsd === null) {
16062
- console.warn(
16063
- `[BidManager] Bid from solver=${bid.userOp.sender} REJECTED: unable to price mixed outputs`
16064
- );
16169
+ console.warn(`[BidManager] Bid from solver=${bid.solverAddress} REJECTED: unable to price mixed outputs`);
16065
16170
  continue;
16066
16171
  }
16067
16172
  if (bidUsd.lt(requiredUsd)) {
16068
16173
  console.log(
16069
- `[BidManager] Bid from solver=${bid.userOp.sender}: partial fill candidate (bid=${bidUsd.toString()}, required=${requiredUsd.toString()}, covers=${bidUsd.div(requiredUsd).mul(100).toFixed(2)}%)`
16174
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (bid=${bidUsd.toString()}, required=${requiredUsd.toString()}, covers=${bidUsd.div(requiredUsd).mul(100).toFixed(2)}%)`
16070
16175
  );
16071
16176
  } else {
16072
16177
  console.log(
16073
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED: mixed USD value=${bidUsd.toString()}`
16178
+ `[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED: mixed USD value=${bidUsd.toString()}`
16074
16179
  );
16075
16180
  }
16076
- validBids.push({ bid, options, usdValue: bidUsd });
16181
+ validBids.push({ bid, usdValue: bidUsd });
16077
16182
  }
16078
16183
  validBids.sort((a, b) => b.usdValue.comparedTo(a.usdValue));
16079
- return validBids.map(({ usdValue: _, ...rest }) => rest);
16184
+ return validBids.map(({ bid }) => bid);
16080
16185
  }
16081
16186
  /**
16082
16187
  * Fallback when DEX pricing is unavailable.
@@ -16084,17 +16189,17 @@ var BidManager = class {
16084
16189
  * Bids offering less than required for a token are allowed (partial fill).
16085
16190
  * Sorted by total offered amount descending.
16086
16191
  */
16087
- sortByRawAmountFallback(decodedBids, orderOutputs) {
16192
+ sortByRawAmountFallback(bids, orderOutputs) {
16088
16193
  console.log(
16089
- `[BidManager] sortByRawAmountFallback: checking ${decodedBids.length} bid(s) against ${orderOutputs.length} required output(s)`
16194
+ `[BidManager] sortByRawAmountFallback: checking ${bids.length} bid(s) against ${orderOutputs.length} required output(s)`
16090
16195
  );
16091
16196
  const validBids = [];
16092
- for (const { bid, options } of decodedBids) {
16197
+ for (const bid of bids) {
16093
16198
  let valid = true;
16094
16199
  let totalOffered = new Decimal2(0);
16095
16200
  let rejectReason = "";
16096
16201
  for (const required of orderOutputs) {
16097
- const matching = options.outputs.find((o) => o.token.toLowerCase() === required.token.toLowerCase());
16202
+ const matching = bid.outputs.find((o) => o.token.toLowerCase() === required.token.toLowerCase());
16098
16203
  if (!matching) {
16099
16204
  valid = false;
16100
16205
  rejectReason = `missing output token=${required.token}`;
@@ -16103,7 +16208,7 @@ var BidManager = class {
16103
16208
  totalOffered = totalOffered.plus(new Decimal2(matching.amount.toString()));
16104
16209
  }
16105
16210
  if (!valid) {
16106
- console.warn(`[BidManager] Bid from solver=${bid.userOp.sender} REJECTED (fallback): ${rejectReason}`);
16211
+ console.warn(`[BidManager] Bid from solver=${bid.solverAddress} REJECTED (fallback): ${rejectReason}`);
16107
16212
  continue;
16108
16213
  }
16109
16214
  const totalRequired = orderOutputs.reduce(
@@ -16112,17 +16217,17 @@ var BidManager = class {
16112
16217
  );
16113
16218
  if (totalOffered.lt(totalRequired)) {
16114
16219
  console.log(
16115
- `[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)}%)`
16220
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (fallback) (offered=${totalOffered.toString()}, required=${totalRequired.toString()}, covers=${totalOffered.div(totalRequired).mul(100).toFixed(2)}%)`
16116
16221
  );
16117
16222
  } else {
16118
16223
  console.log(
16119
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED (fallback): totalOffered=${totalOffered.toString()}`
16224
+ `[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED (fallback): totalOffered=${totalOffered.toString()}`
16120
16225
  );
16121
16226
  }
16122
- validBids.push({ bid, options, totalOffered });
16227
+ validBids.push({ bid, totalOffered });
16123
16228
  }
16124
16229
  validBids.sort((a, b) => b.totalOffered.comparedTo(a.totalOffered));
16125
- return validBids.map(({ totalOffered: _, ...rest }) => rest);
16230
+ return validBids.map(({ bid }) => bid);
16126
16231
  }
16127
16232
  // ── Token classification helpers ──────────────────────────────────
16128
16233
  /**
@@ -16731,6 +16836,262 @@ var OrderStatusChecker = class {
16731
16836
  }
16732
16837
  };
16733
16838
 
16839
+ // src/protocols/intents/quote/types.ts
16840
+ var UnsupportedIntentQuoteStrategyError = class extends Error {
16841
+ constructor(strategy) {
16842
+ super(`Unsupported intent quote strategy: ${strategy}`);
16843
+ this.name = "UnsupportedIntentQuoteStrategyError";
16844
+ }
16845
+ };
16846
+ var UnsupportedIntentQuotePairError = class extends Error {
16847
+ constructor(params) {
16848
+ super(
16849
+ `No Uniswap v4 pool config found for ${params.tokenIn.symbol ?? params.tokenIn.address} -> ${params.tokenOut.symbol ?? params.tokenOut.address} on ${params.source} -> ${params.destination}`
16850
+ );
16851
+ this.name = "UnsupportedIntentQuotePairError";
16852
+ }
16853
+ };
16854
+
16855
+ // src/protocols/intents/quote/uniswapV4.ts
16856
+ var UNISWAP_INTENT_QUOTE_CHAIN = "EVM-8453" /* BASE_MAINNET */;
16857
+ var BPS_DENOMINATOR = 10000n;
16858
+ var UniswapV4IntentQuoteStrategy = class {
16859
+ constructor(chainConfigService) {
16860
+ this.chainConfigService = chainConfigService;
16861
+ }
16862
+ chainConfigService;
16863
+ baseQuoteClient;
16864
+ async quote(params, source, destination) {
16865
+ this.validateQuoteParams(params);
16866
+ const protocolFeeBps = await this.readProtocolFeeBps(source.client, source.stateMachineId);
16867
+ const quoteClient = this.resolveQuoteClient(source, destination);
16868
+ const poolConfig = this.resolvePoolConfig(params, source.stateMachineId, UNISWAP_INTENT_QUOTE_CHAIN);
16869
+ return params.amountIn !== void 0 ? this.quoteExactInput({ params, client: quoteClient, protocolFeeBps, poolConfig }) : this.quoteExactOutput({ params, client: quoteClient, protocolFeeBps, poolConfig });
16870
+ }
16871
+ resolveQuoteClient(source, destination) {
16872
+ if (source.stateMachineId === UNISWAP_INTENT_QUOTE_CHAIN) return source.client;
16873
+ if (destination.stateMachineId === UNISWAP_INTENT_QUOTE_CHAIN) return destination.client;
16874
+ if (this.baseQuoteClient) return this.baseQuoteClient;
16875
+ const rpcUrl = this.chainConfigService.getRpcUrl(UNISWAP_INTENT_QUOTE_CHAIN);
16876
+ if (!rpcUrl) throw new Error(`RPC URL is not configured for ${UNISWAP_INTENT_QUOTE_CHAIN}`);
16877
+ const baseQuoteClient = createPublicClient({
16878
+ chain: base,
16879
+ transport: http(rpcUrl)
16880
+ });
16881
+ this.baseQuoteClient = baseQuoteClient;
16882
+ return baseQuoteClient;
16883
+ }
16884
+ validateQuoteParams(params) {
16885
+ const hasAmountIn = params.amountIn !== void 0;
16886
+ const hasAmountOut = params.amountOut !== void 0;
16887
+ if (hasAmountIn === hasAmountOut) throw new Error("Provide exactly one of amountIn or amountOut");
16888
+ if (hasAmountIn && params.amountIn <= 0n) throw new Error("amountIn must be greater than zero");
16889
+ if (hasAmountOut && params.amountOut <= 0n) throw new Error("amountOut must be greater than zero");
16890
+ if (params.tokenIn.address.toLowerCase() === params.tokenOut.address.toLowerCase()) {
16891
+ throw new Error("tokenIn and tokenOut cannot be the same");
16892
+ }
16893
+ }
16894
+ async readProtocolFeeBps(client, chain) {
16895
+ const gatewayAddress = this.chainConfigService.getIntentGatewayAddress(chain);
16896
+ if (!gatewayAddress || gatewayAddress === "0x" || gatewayAddress === zeroAddress) {
16897
+ throw new Error(`IntentGatewayV2 is not configured for chain ${chain}`);
16898
+ }
16899
+ const gatewayParams = await client.readContract({
16900
+ address: gatewayAddress,
16901
+ abi: IntentGatewayV2_default.ABI,
16902
+ functionName: "params"
16903
+ });
16904
+ if (isGatewayParamsTuple(gatewayParams)) return BigInt(gatewayParams[4]);
16905
+ return BigInt(gatewayParams.protocolFeeBps ?? 0);
16906
+ }
16907
+ resolvePoolConfig(params, source, destination) {
16908
+ const override = params.uniswapV4?.poolKey;
16909
+ if (override) {
16910
+ const poolKey = normalizePoolKey(override);
16911
+ const tokenInForQuote = getAddress(override.currencyIn ?? params.tokenIn.address);
16912
+ if (tokenInForQuote !== poolKey.currency0 && tokenInForQuote !== poolKey.currency1) {
16913
+ throw new Error(
16914
+ `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.`
16915
+ );
16916
+ }
16917
+ return {
16918
+ poolKey,
16919
+ quoterAddress: this.resolveQuoterAddress(destination, override.quoterAddress),
16920
+ tokenInForQuote
16921
+ };
16922
+ }
16923
+ const poolConfig = this.resolveConfiguredPool(params, destination);
16924
+ if (poolConfig) return poolConfig;
16925
+ throw new UnsupportedIntentQuotePairError({
16926
+ source,
16927
+ destination,
16928
+ tokenIn: params.tokenIn,
16929
+ tokenOut: params.tokenOut
16930
+ });
16931
+ }
16932
+ resolveConfiguredPool(params, chain) {
16933
+ for (const pool of this.chainConfigService.getUniswapV4PoolConfigs(chain)) {
16934
+ const resolvedPool = this.resolveConfiguredPoolTokens(chain, pool);
16935
+ if (!resolvedPool) continue;
16936
+ const tokenInForQuote = matchPoolToken(params.tokenIn, resolvedPool);
16937
+ const tokenOutForQuote = matchPoolToken(params.tokenOut, resolvedPool);
16938
+ if (!tokenInForQuote || !tokenOutForQuote || tokenInForQuote.symbol === tokenOutForQuote.symbol) continue;
16939
+ const { currency0, currency1 } = sortCurrencies(resolvedPool[0].address, resolvedPool[1].address);
16940
+ return {
16941
+ poolKey: {
16942
+ currency0,
16943
+ currency1,
16944
+ fee: pool.fee,
16945
+ tickSpacing: pool.tickSpacing,
16946
+ hooks: getAddress(pool.hooks ?? zeroAddress)
16947
+ },
16948
+ quoterAddress: this.resolveQuoterAddress(chain),
16949
+ tokenInForQuote: tokenInForQuote.address
16950
+ };
16951
+ }
16952
+ return null;
16953
+ }
16954
+ resolveQuoterAddress(chain, override) {
16955
+ const address = override ?? this.chainConfigService.getUniswapV4QuoterAddress(chain);
16956
+ if (!address || address === "0x" || address === zeroAddress) {
16957
+ throw new Error(`Uniswap V4 quoter is not configured for chain ${chain}`);
16958
+ }
16959
+ return getAddress(address);
16960
+ }
16961
+ resolveConfiguredPoolTokens(chain, pool) {
16962
+ const first = this.resolveConfiguredPoolToken(chain, pool.tokens[0]);
16963
+ const second = this.resolveConfiguredPoolToken(chain, pool.tokens[1]);
16964
+ return first && second ? [first, second] : null;
16965
+ }
16966
+ resolveConfiguredPoolToken(chain, symbol) {
16967
+ const address = this.chainConfigService.getAssetAddress(chain, symbol);
16968
+ if (!address || address === "0x") return null;
16969
+ return { symbol, address: getAddress(address) };
16970
+ }
16971
+ async quoteExactInput(args) {
16972
+ const amountIn = args.params.amountIn;
16973
+ const swapAmountIn = deductProtocolFee(amountIn, args.protocolFeeBps);
16974
+ const amountOut = await this.readV4QuoteExactInput(args.client, args.poolConfig, swapAmountIn);
16975
+ return {
16976
+ strategy: "uniswap_v4",
16977
+ tradeType: "EXACT_INPUT",
16978
+ amountIn,
16979
+ amountOut,
16980
+ quoteMetadata: {
16981
+ quoteChain: UNISWAP_INTENT_QUOTE_CHAIN,
16982
+ poolKey: args.poolConfig.poolKey,
16983
+ quoterAddress: args.poolConfig.quoterAddress,
16984
+ protocolFeeBps: args.protocolFeeBps
16985
+ }
16986
+ };
16987
+ }
16988
+ async quoteExactOutput(args) {
16989
+ const amountOut = args.params.amountOut;
16990
+ const swapAmountIn = await this.readV4QuoteExactOutput(args.client, args.poolConfig, amountOut);
16991
+ const amountIn = grossUpForProtocolFee(swapAmountIn, args.protocolFeeBps);
16992
+ return {
16993
+ strategy: "uniswap_v4",
16994
+ tradeType: "EXACT_OUTPUT",
16995
+ amountIn,
16996
+ amountOut,
16997
+ quoteMetadata: {
16998
+ quoteChain: UNISWAP_INTENT_QUOTE_CHAIN,
16999
+ poolKey: args.poolConfig.poolKey,
17000
+ quoterAddress: args.poolConfig.quoterAddress,
17001
+ protocolFeeBps: args.protocolFeeBps
17002
+ }
17003
+ };
17004
+ }
17005
+ async readV4QuoteExactInput(client, poolConfig, amountIn) {
17006
+ const data = encodeFunctionData({
17007
+ abi: UNISWAP_V4_QUOTER_ABI,
17008
+ functionName: "quoteExactInputSingle",
17009
+ args: [
17010
+ {
17011
+ poolKey: poolConfig.poolKey,
17012
+ zeroForOne: getZeroForOne(poolConfig.tokenInForQuote, poolConfig.poolKey),
17013
+ exactAmount: amountIn,
17014
+ hookData: "0x"
17015
+ }
17016
+ ]
17017
+ });
17018
+ const response = await client.call({ to: poolConfig.quoterAddress, data });
17019
+ if (!response.data || response.data === "0x") {
17020
+ throw new Error(`Uniswap V4 quoter at ${poolConfig.quoterAddress} returned no data`);
17021
+ }
17022
+ const [amountOut] = decodeFunctionResult({
17023
+ abi: UNISWAP_V4_QUOTER_ABI,
17024
+ functionName: "quoteExactInputSingle",
17025
+ data: response.data
17026
+ });
17027
+ return amountOut;
17028
+ }
17029
+ async readV4QuoteExactOutput(client, poolConfig, amountOut) {
17030
+ const data = encodeFunctionData({
17031
+ abi: UNISWAP_V4_QUOTER_ABI,
17032
+ functionName: "quoteExactOutputSingle",
17033
+ args: [
17034
+ {
17035
+ poolKey: poolConfig.poolKey,
17036
+ zeroForOne: getZeroForOne(poolConfig.tokenInForQuote, poolConfig.poolKey),
17037
+ exactAmount: amountOut,
17038
+ hookData: "0x"
17039
+ }
17040
+ ]
17041
+ });
17042
+ const response = await client.call({ to: poolConfig.quoterAddress, data });
17043
+ if (!response.data || response.data === "0x") {
17044
+ throw new Error(`Uniswap V4 quoter at ${poolConfig.quoterAddress} returned no data`);
17045
+ }
17046
+ const [amountIn] = decodeFunctionResult({
17047
+ abi: UNISWAP_V4_QUOTER_ABI,
17048
+ functionName: "quoteExactOutputSingle",
17049
+ data: response.data
17050
+ });
17051
+ return amountIn;
17052
+ }
17053
+ };
17054
+ function normalizePoolKey(poolKey) {
17055
+ return {
17056
+ currency0: getAddress(poolKey.currency0),
17057
+ currency1: getAddress(poolKey.currency1),
17058
+ fee: poolKey.fee,
17059
+ tickSpacing: poolKey.tickSpacing,
17060
+ hooks: getAddress(poolKey.hooks)
17061
+ };
17062
+ }
17063
+ function sortCurrencies(tokenIn, tokenOut) {
17064
+ const input = getAddress(tokenIn);
17065
+ const output = getAddress(tokenOut);
17066
+ return BigInt(input) < BigInt(output) ? { currency0: input, currency1: output } : { currency0: output, currency1: input };
17067
+ }
17068
+ function matchPoolToken(token, poolTokens) {
17069
+ const tokenAddress = token.address.toLowerCase();
17070
+ const addressMatch = poolTokens.find((poolToken) => poolToken.address.toLowerCase() === tokenAddress);
17071
+ if (addressMatch) return addressMatch;
17072
+ const tokenSymbol = token.symbol?.toUpperCase();
17073
+ if (!tokenSymbol) return null;
17074
+ return poolTokens.find((poolToken) => poolToken.symbol.toUpperCase() === tokenSymbol) ?? null;
17075
+ }
17076
+ function getZeroForOne(tokenIn, poolKey) {
17077
+ return getAddress(tokenIn).toLowerCase() === getAddress(poolKey.currency0).toLowerCase();
17078
+ }
17079
+ function isGatewayParamsTuple(value) {
17080
+ return Array.isArray(value);
17081
+ }
17082
+ function deductProtocolFee(amount, protocolFeeBps) {
17083
+ if (protocolFeeBps <= 0n) return amount;
17084
+ const fee = amount * protocolFeeBps / BPS_DENOMINATOR;
17085
+ return amount - fee;
17086
+ }
17087
+ function grossUpForProtocolFee(netAmount, protocolFeeBps) {
17088
+ if (protocolFeeBps <= 0n) return netAmount;
17089
+ return divCeil(netAmount * BPS_DENOMINATOR, BPS_DENOMINATOR - protocolFeeBps);
17090
+ }
17091
+ function divCeil(numerator, denominator) {
17092
+ return (numerator + denominator - 1n) / denominator;
17093
+ }
17094
+
16734
17095
  // src/protocols/intents/IntentGateway.ts
16735
17096
  var IntentGateway = class _IntentGateway {
16736
17097
  /** EVM chain on which orders are placed and escrowed. */
@@ -16757,6 +17118,8 @@ var IntentGateway = class _IntentGateway {
16757
17118
  bidManager;
16758
17119
  /** Estimates gas costs for filling an order and converts them to fee-token amounts. */
16759
17120
  gasEstimator;
17121
+ /** Quote strategies for pricing orders before placement, keyed by strategy name. */
17122
+ quoteStrategies;
16760
17123
  /**
16761
17124
  * Private constructor — use {@link IntentGateway.create} instead.
16762
17125
  *
@@ -16794,12 +17157,15 @@ var IntentGateway = class _IntentGateway {
16794
17157
  const bidManager = new BidManager(this.ctx, crypto);
16795
17158
  const gasEstimator = new GasEstimator(this.ctx, crypto);
16796
17159
  this.orderPlacer = new OrderPlacer(this.ctx);
16797
- this.orderExecutor = new OrderExecutor(this.ctx, bidManager, crypto);
17160
+ this.orderExecutor = new OrderExecutor(this.ctx, bidManager);
16798
17161
  this.orderCanceller = new OrderCanceller(this.ctx);
16799
17162
  this.orderStatusChecker = new OrderStatusChecker(this.ctx);
16800
17163
  this.bidManager = bidManager;
16801
17164
  this.gasEstimator = gasEstimator;
16802
17165
  this._crypto = crypto;
17166
+ this.quoteStrategies = {
17167
+ uniswap_v4: new UniswapV4IntentQuoteStrategy(dest.configService)
17168
+ };
16803
17169
  }
16804
17170
  /**
16805
17171
  * Creates an initialized IntentGateway instance.
@@ -16844,6 +17210,33 @@ var IntentGateway = class _IntentGateway {
16844
17210
  }
16845
17211
  }
16846
17212
  }
17213
+ /**
17214
+ * Quotes an intent between this gateway's source and destination chains.
17215
+ *
17216
+ * `strategy` defaults to `uniswap_v4`, currently the only supported
17217
+ * strategy. Provide exactly one of `amountIn` or `amountOut`.
17218
+ *
17219
+ * The Uniswap quote strategy always prices against the configured Base
17220
+ * pool, regardless of this gateway's destination chain. Returned
17221
+ * `amountIn`/`amountOut` already account for the gateway's protocol fee
17222
+ * (`quoteMetadata.protocolFeeBps`), which the gateway deducts from order
17223
+ * inputs; apply only your own slippage tolerance before placing the order.
17224
+ *
17225
+ * @param params - Token pair, amount, and optional strategy/pool overrides.
17226
+ * @returns The quoted amounts plus strategy-specific metadata.
17227
+ * @throws {UnsupportedIntentQuoteStrategyError} For unknown strategies.
17228
+ * @throws {UnsupportedIntentQuotePairError} When no pool is configured for the pair.
17229
+ */
17230
+ async quoteIntent(params) {
17231
+ const strategy = params.strategy ?? "uniswap_v4";
17232
+ const handler = this.quoteStrategies[strategy];
17233
+ if (!handler) throw new UnsupportedIntentQuoteStrategyError(strategy);
17234
+ return handler.quote(
17235
+ { ...params, strategy },
17236
+ { stateMachineId: this.source.config.stateMachineId, client: this.source.client },
17237
+ { stateMachineId: this.dest.config.stateMachineId, client: this.dest.client }
17238
+ );
17239
+ }
16847
17240
  /**
16848
17241
  * Bidirectional async generator that orchestrates the full order lifecycle:
16849
17242
  * placement, fee estimation, bid collection, and execution.
@@ -16898,17 +17291,38 @@ var IntentGateway = class _IntentGateway {
16898
17291
  }
16899
17292
  const { order: finalizedOrder, receipt: placementReceipt } = placeOrderSecond.value;
16900
17293
  yield { status: "ORDER_PLACED", order: finalizedOrder, receipt: placementReceipt };
16901
- for await (const status of this.orderExecutor.executeOrder({
16902
- order: finalizedOrder,
16903
- sessionPrivateKey,
16904
- auctionTimeMs: options.auctionTimeMs,
16905
- pollIntervalMs: options.pollIntervalMs,
16906
- solver: options.solver
16907
- })) {
16908
- yield status;
16909
- }
17294
+ yield* this.driveExecution(
17295
+ this.orderExecutor.executeOrder({
17296
+ order: finalizedOrder,
17297
+ sessionPrivateKey,
17298
+ auctionTimeMs: options.auctionTimeMs,
17299
+ pollIntervalMs: options.pollIntervalMs,
17300
+ solver: options.solver
17301
+ })
17302
+ );
16910
17303
  return;
16911
17304
  }
17305
+ /**
17306
+ * Forwards updates from the executor's bidirectional generator to the caller,
17307
+ * threading the {@link SelectBidResult} the caller feeds back after a
17308
+ * `BIDS_RECEIVED` yield into the executor's `.next()`. Other yields expect no
17309
+ * feedback. This is what lets the consumer own `bid.execute()` while the
17310
+ * executor keeps tracking fills and continuing the auction.
17311
+ */
17312
+ async *driveExecution(execGen) {
17313
+ try {
17314
+ let input;
17315
+ while (true) {
17316
+ const { value, done } = await execGen.next(input);
17317
+ input = void 0;
17318
+ if (done) break;
17319
+ const fed = yield value;
17320
+ if (value.status === "BIDS_RECEIVED") input = fed;
17321
+ }
17322
+ } finally {
17323
+ await execGen.return();
17324
+ }
17325
+ }
16912
17326
  /**
16913
17327
  * Validates that an order has the minimum fields required for post-placement
16914
17328
  * resume (i.e. it was previously placed and has an on-chain identity).
@@ -16945,14 +17359,99 @@ var IntentGateway = class _IntentGateway {
16945
17359
  */
16946
17360
  async *resume(order, options) {
16947
17361
  this.assertOrderCanResume(order);
16948
- for await (const status of this.orderExecutor.executeOrder({
16949
- order,
16950
- sessionPrivateKey: options.sessionPrivateKey,
16951
- auctionTimeMs: options.auctionTimeMs,
16952
- pollIntervalMs: options.pollIntervalMs,
16953
- solver: options.solver
16954
- })) {
16955
- yield status;
17362
+ yield* this.driveExecution(
17363
+ this.orderExecutor.executeOrder({
17364
+ order,
17365
+ sessionPrivateKey: options.sessionPrivateKey,
17366
+ auctionTimeMs: options.auctionTimeMs,
17367
+ pollIntervalMs: options.pollIntervalMs,
17368
+ solver: options.solver
17369
+ })
17370
+ );
17371
+ }
17372
+ /**
17373
+ * Batteries-included variant of {@link execute}: places the order and then
17374
+ * auto-selects the best bid each round via {@link selectAndExecuteBest}, with
17375
+ * no bid-selection input from the caller.
17376
+ *
17377
+ * The caller still signs the placement transaction: this generator yields
17378
+ * `AWAITING_PLACE_ORDER` and the caller must hand the signed tx back via
17379
+ * `gen.next(signedTx)` exactly as with {@link execute}. Every other stage
17380
+ * (`BIDS_RECEIVED`, `BID_SELECTED`, `FILLED`, …) is handled automatically and
17381
+ * surfaced for observation, so the rest of the loop needs no feedback.
17382
+ *
17383
+ * @param order - The order to place and execute.
17384
+ * @param graffiti - Optional orderflow-attribution tag.
17385
+ * @param options - Same tuning parameters as {@link execute}.
17386
+ * @yields {@link IntentOrderStatusUpdate} at each lifecycle stage.
17387
+ */
17388
+ async *executeBest(order, graffiti = DEFAULT_GRAFFITI, options) {
17389
+ const gen = this.execute(order, graffiti, options);
17390
+ try {
17391
+ let input;
17392
+ while (true) {
17393
+ const { value, done } = await gen.next(input);
17394
+ input = void 0;
17395
+ if (done) break;
17396
+ if (value.status === "BIDS_RECEIVED") {
17397
+ yield value;
17398
+ input = await this.autoSelect(order, value.bids);
17399
+ } else if (value.status === "AWAITING_PLACE_ORDER") {
17400
+ input = yield value;
17401
+ } else {
17402
+ yield value;
17403
+ }
17404
+ }
17405
+ } finally {
17406
+ await gen.return();
17407
+ }
17408
+ }
17409
+ /**
17410
+ * Batteries-included variant of {@link resume}: auto-selects the best bid each
17411
+ * round via {@link selectAndExecuteBest}, with no bid-selection input from the
17412
+ * caller. A plain `for await` loop is sufficient — there is no placement step.
17413
+ *
17414
+ * @param order - A previously placed order with a valid `id` and `session`.
17415
+ * @param options - Optional tuning parameters for bid collection and execution.
17416
+ * @yields {@link IntentOrderStatusUpdate} at each execution stage.
17417
+ */
17418
+ async *resumeBest(order, options) {
17419
+ const gen = this.resume(order, options);
17420
+ try {
17421
+ let input;
17422
+ while (true) {
17423
+ const { value, done } = await gen.next(input);
17424
+ input = void 0;
17425
+ if (done) break;
17426
+ yield value;
17427
+ if (value.status === "BIDS_RECEIVED") {
17428
+ input = await this.autoSelect(order, value.bids);
17429
+ }
17430
+ }
17431
+ } finally {
17432
+ await gen.return();
17433
+ }
17434
+ }
17435
+ /**
17436
+ * Auto-select wrapper used by {@link executeBest} / {@link resumeBest}.
17437
+ *
17438
+ * Runs {@link selectAndExecuteBest} and returns the {@link SelectBidResult} to
17439
+ * feed back to the executor. If selection fails this round — all bids fail
17440
+ * simulation, no valid bids, or the bundler rejects the UserOp — it swallows
17441
+ * the error and returns `undefined`, which tells the executor to keep polling
17442
+ * for fresh bids until the deadline rather than aborting the order. Swallowing
17443
+ * the error here (rather than letting it propagate) also keeps the executor's
17444
+ * `finally` teardown intact, since nothing throws across the suspended
17445
+ * generators.
17446
+ */
17447
+ async autoSelect(order, bids) {
17448
+ try {
17449
+ return await this.selectAndExecuteBest(order, bids);
17450
+ } catch (err) {
17451
+ console.warn(
17452
+ `[IntentGateway] autoSelect: bid selection failed this round, continuing to poll: ${err instanceof Error ? err.message : String(err)}`
17453
+ );
17454
+ return void 0;
16956
17455
  }
16957
17456
  }
16958
17457
  /**
@@ -17008,10 +17507,52 @@ var IntentGateway = class _IntentGateway {
17008
17507
  return this.bidManager.prepareSubmitBid(options);
17009
17508
  }
17010
17509
  /**
17011
- * Selects the best available bid, simulates it, and submits the UserOperation
17012
- * to the bundler.
17510
+ * Decodes raw filler bids into first-class {@link Bid} objects that can be
17511
+ * ranked, simulated, and executed by the consumer.
17512
+ *
17513
+ * Delegates to {@link BidManager.buildBids}.
17514
+ *
17515
+ * @param order - The placed order the bids are competing to fill.
17516
+ * @param bids - Raw filler bids fetched from the coprocessor.
17517
+ * @param sessionPrivateKey - Optional session key override; looked up from
17518
+ * storage by `order.session` if omitted.
17519
+ * @returns Array of executable {@link Bid} objects.
17520
+ */
17521
+ buildBids(order, bids, sessionPrivateKey) {
17522
+ return this.bidManager.buildBids(order, bids, sessionPrivateKey);
17523
+ }
17524
+ /**
17525
+ * Sorts bids by output value using the same strategy the autopilot uses.
17526
+ *
17527
+ * Delegates to {@link BidManager.sortBids}.
17528
+ *
17529
+ * @param order - The placed order whose output spec drives sorting.
17530
+ * @param bids - Bids to sort (from {@link buildBids}).
17531
+ * @returns Sorted array of {@link Bid} objects.
17532
+ */
17533
+ async sortBids(order, bids) {
17534
+ return this.bidManager.sortBids(order, bids);
17535
+ }
17536
+ /**
17537
+ * Autopilot bid selection: sorts the given bids, simulates each until one
17538
+ * passes, then executes it.
17539
+ *
17540
+ * Delegates to {@link BidManager.selectAndExecuteBest}.
17541
+ *
17542
+ * @param order - The placed order to fill.
17543
+ * @param bids - Candidate bids (from {@link buildBids}).
17544
+ * @returns A {@link SelectBidResult} with the submitted UserOperation, hashes,
17545
+ * and fill status.
17546
+ */
17547
+ async selectAndExecuteBest(order, bids) {
17548
+ return this.bidManager.selectAndExecuteBest(order, bids);
17549
+ }
17550
+ /**
17551
+ * Decodes, sorts, simulates, signs, and submits the best of the given raw
17552
+ * filler bids with no per-bid input from the caller.
17013
17553
  *
17014
- * Delegates to {@link BidManager.selectBid}.
17554
+ * Delegates to {@link BidManager.selectBid}. Prefer {@link buildBids} +
17555
+ * {@link selectAndExecuteBest} (or {@link executeBest}) for new code.
17015
17556
  *
17016
17557
  * @param order - The placed order to fill.
17017
17558
  * @param bids - Raw filler bids fetched from the coprocessor.
@@ -17931,7 +18472,7 @@ var HyperFungibleTokenABI = [
17931
18472
  internalType: "uint256"
17932
18473
  }
17933
18474
  ],
17934
- stateMutability: "view"
18475
+ stateMutability: "nonpayable"
17935
18476
  },
17936
18477
  {
17937
18478
  type: "function",
@@ -17982,7 +18523,7 @@ var HyperFungibleTokenABI = [
17982
18523
  internalType: "uint256"
17983
18524
  }
17984
18525
  ],
17985
- stateMutability: "view"
18526
+ stateMutability: "nonpayable"
17986
18527
  },
17987
18528
  {
17988
18529
  type: "function",
@@ -18033,7 +18574,7 @@ var HyperFungibleTokenABI = [
18033
18574
  internalType: "uint256"
18034
18575
  }
18035
18576
  ],
18036
- stateMutability: "view"
18577
+ stateMutability: "nonpayable"
18037
18578
  },
18038
18579
  {
18039
18580
  type: "function",
@@ -19052,7 +19593,7 @@ var WrappedHyperFungibleTokenABI = [
19052
19593
  internalType: "uint256"
19053
19594
  }
19054
19595
  ],
19055
- stateMutability: "view"
19596
+ stateMutability: "nonpayable"
19056
19597
  },
19057
19598
  {
19058
19599
  type: "function",
@@ -19103,7 +19644,7 @@ var WrappedHyperFungibleTokenABI = [
19103
19644
  internalType: "uint256"
19104
19645
  }
19105
19646
  ],
19106
- stateMutability: "view"
19647
+ stateMutability: "nonpayable"
19107
19648
  },
19108
19649
  {
19109
19650
  type: "function",
@@ -19154,7 +19695,7 @@ var WrappedHyperFungibleTokenABI = [
19154
19695
  internalType: "uint256"
19155
19696
  }
19156
19697
  ],
19157
- stateMutability: "view"
19698
+ stateMutability: "nonpayable"
19158
19699
  },
19159
19700
  {
19160
19701
  type: "function",
@@ -19696,13 +20237,13 @@ var HyperFungibleToken = class {
19696
20237
  };
19697
20238
  let totalNativeCost = 0n;
19698
20239
  try {
19699
- totalNativeCost = await this.source.client.readContract({
20240
+ const { result } = await this.source.client.simulateContract({
19700
20241
  address: params.token,
19701
20242
  abi: HyperFungibleTokenABI,
19702
20243
  functionName: "quote",
19703
20244
  args: [sendParams]
19704
20245
  });
19705
- totalNativeCost = totalNativeCost * 101n / 100n;
20246
+ totalNativeCost = result * 101n / 100n;
19706
20247
  } catch {
19707
20248
  }
19708
20249
  return {
@@ -21610,6 +22151,6 @@ async function teleportDot(param_) {
21610
22151
  return stream;
21611
22152
  }
21612
22153
 
21613
- 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 };
22154
+ 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 };
21614
22155
  //# sourceMappingURL=index.js.map
21615
22156
  //# sourceMappingURL=index.js.map