@hyperbridge/sdk 2.2.0 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
  };
@@ -10584,6 +10622,40 @@ var PostRequestClient = class {
10584
10622
  async buildFinalized(request, hyperbridgeDelivered) {
10585
10623
  const destChain = this.ctx.config.dest;
10586
10624
  const hyperbridge = this.ctx.config.hyperbridge;
10625
+ const { config } = hyperbridge;
10626
+ const finality = await this.queries.queryStateMachineUpdateByHeight({
10627
+ statemachineId: config.stateMachineId,
10628
+ height: hyperbridgeDelivered.metadata.blockNumber,
10629
+ chain: config.stateMachineId
10630
+ });
10631
+ if (finality) {
10632
+ const proof = await hyperbridge.queryProof(
10633
+ { Requests: [postRequestCommitment(request).commitment] },
10634
+ request.dest,
10635
+ BigInt(finality.height)
10636
+ );
10637
+ const calldata = destChain.encode({
10638
+ kind: "PostRequest",
10639
+ proof: {
10640
+ stateMachine: config.stateMachineId,
10641
+ consensusStateId: config.consensusStateId,
10642
+ proof,
10643
+ height: BigInt(finality.height)
10644
+ },
10645
+ requests: [request],
10646
+ signer: pad("0x")
10647
+ });
10648
+ return {
10649
+ status: RequestStatus.HYPERBRIDGE_FINALIZED,
10650
+ metadata: {
10651
+ blockHash: finality.blockHash,
10652
+ blockNumber: finality.height,
10653
+ transactionHash: finality.transactionHash,
10654
+ timestamp: finality.timestamp,
10655
+ calldata
10656
+ }
10657
+ };
10658
+ }
10587
10659
  if (destChain instanceof EvmChain) {
10588
10660
  const hyperbridgeSubstrate = hyperbridge;
10589
10661
  const currentEpoch = await destChain.currentEpoch();
@@ -10592,18 +10664,18 @@ var PostRequestClient = class {
10592
10664
  currentEpoch
10593
10665
  );
10594
10666
  if (!consensusResult) return void 0;
10595
- const proof2 = await hyperbridge.queryProof(
10667
+ const proof = await hyperbridge.queryProof(
10596
10668
  { Requests: [postRequestCommitment(request).commitment] },
10597
10669
  request.dest,
10598
10670
  consensusResult.provenHeight
10599
10671
  );
10600
- const calldata2 = destChain.encode({
10672
+ const calldata = destChain.encode({
10601
10673
  kind: "BatchConsensusAndPostRequest",
10602
10674
  consensusProofs: consensusResult.proofs,
10603
10675
  proof: {
10604
- stateMachine: this.ctx.config.hyperbridge.config.stateMachineId,
10605
- consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10606
- proof: proof2,
10676
+ stateMachine: config.stateMachineId,
10677
+ consensusStateId: config.consensusStateId,
10678
+ proof,
10607
10679
  height: consensusResult.provenHeight
10608
10680
  },
10609
10681
  requests: [request],
@@ -10617,42 +10689,11 @@ var PostRequestClient = class {
10617
10689
  transactionHash: hyperbridgeDelivered.metadata.transactionHash,
10618
10690
  // @ts-ignore
10619
10691
  timestamp: hyperbridgeDelivered.metadata.timestamp,
10620
- calldata: calldata2
10692
+ calldata
10621
10693
  }
10622
10694
  };
10623
10695
  }
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
- };
10696
+ return void 0;
10656
10697
  }
10657
10698
  /**
10658
10699
  * Streaming helper: waits for the consensus proof, fetches the messaging
@@ -10666,14 +10707,19 @@ var PostRequestClient = class {
10666
10707
  const stateMachineId = this.ctx.config.hyperbridge.config.stateMachineId;
10667
10708
  const neededHeight = BigInt(request.statuses[hyperbridgeDeliveredIndex].metadata.blockNumber);
10668
10709
  this.logger.trace(`[streamFinalized] neededHeight=${neededHeight}`);
10669
- if (destChain instanceof EvmChain) {
10710
+ const commitment = postRequestCommitment(request).commitment;
10711
+ let finality = await this.queries.queryStateMachineUpdateByHeight({
10712
+ statemachineId: stateMachineId,
10713
+ height: Number(neededHeight),
10714
+ chain: stateMachineId
10715
+ });
10716
+ if (!finality && destChain instanceof EvmChain) {
10670
10717
  const hyperbridgeSubstrate = hyperbridge;
10671
10718
  const currentEpoch = await destChain.currentEpoch();
10672
10719
  const consensusResult = await waitOrAbort(this.ctx, {
10673
10720
  signal,
10674
10721
  promise: () => hyperbridgeSubstrate.queryConsensusProofs(neededHeight, currentEpoch)
10675
10722
  });
10676
- const commitment = postRequestCommitment(request).commitment;
10677
10723
  this.logger.trace(
10678
10724
  `[streamFinalized] consensusProofs found (${consensusResult.proofs.length} proofs), provenHeight=${consensusResult.provenHeight}, commitment=${commitment}, dest=${request.dest}`
10679
10725
  );
@@ -10705,45 +10751,45 @@ var PostRequestClient = class {
10705
10751
  }
10706
10752
  };
10707
10753
  }
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
- });
10754
+ if (!finality) {
10755
+ finality = await waitOrAbort(this.ctx, {
10756
+ signal,
10757
+ promise: () => this.queries.queryStateMachineUpdateByHeight({
10758
+ statemachineId: stateMachineId,
10759
+ height: Number(neededHeight),
10760
+ chain: stateMachineId
10761
+ })
10762
+ });
10763
+ }
10716
10764
  const proof = await this.fetchProofWithRetry(
10717
10765
  signal,
10718
- () => hyperbridge.queryProof(
10719
- { Requests: [postRequestCommitment(request).commitment] },
10720
- request.dest,
10721
- BigInt(hyperbridgeFinalized.height)
10722
- )
10766
+ () => hyperbridge.queryProof({ Requests: [commitment] }, request.dest, BigInt(finality.height))
10723
10767
  );
10768
+ if (!(destChain instanceof EvmChain)) {
10769
+ const { stateId } = parseStateMachineId(stateMachineId);
10770
+ await waitForChallengePeriod(destChain, {
10771
+ height: BigInt(finality.height),
10772
+ id: { stateId, consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId }
10773
+ });
10774
+ }
10724
10775
  const calldata = destChain.encode({
10725
10776
  kind: "PostRequest",
10726
10777
  proof: {
10727
10778
  stateMachine: stateMachineId,
10728
10779
  consensusStateId: this.ctx.config.hyperbridge.config.consensusStateId,
10729
10780
  proof,
10730
- height: BigInt(hyperbridgeFinalized.height)
10781
+ height: BigInt(finality.height)
10731
10782
  },
10732
10783
  requests: [request],
10733
10784
  signer: pad("0x")
10734
10785
  });
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
10786
  return {
10741
10787
  status: RequestStatus.HYPERBRIDGE_FINALIZED,
10742
10788
  metadata: {
10743
- blockHash: hyperbridgeFinalized.blockHash,
10744
- blockNumber: hyperbridgeFinalized.height,
10745
- transactionHash: hyperbridgeFinalized.transactionHash,
10746
- timestamp: hyperbridgeFinalized.timestamp,
10789
+ blockHash: finality.blockHash,
10790
+ blockNumber: finality.height,
10791
+ transactionHash: finality.transactionHash,
10792
+ timestamp: finality.timestamp,
10747
10793
  calldata
10748
10794
  }
10749
10795
  };
@@ -14676,6 +14722,7 @@ function orderCommitment(order) {
14676
14722
  return keccak256(encoded);
14677
14723
  }
14678
14724
  async function convertGasToFeeToken(ctx, gasEstimate, gasEstimateIn, evmChainID, gasPriceOverride) {
14725
+ if (TESTNET_CHAINS.has(evmChainID)) return 1n;
14679
14726
  const chain = ctx[gasEstimateIn];
14680
14727
  const client = chain.client;
14681
14728
  const gasPrice = gasPriceOverride ?? await retryPromise(() => client.getGasPrice(), {
@@ -14710,6 +14757,7 @@ async function convertGasToFeeToken(ctx, gasEstimate, gasEstimateIn, evmChainID,
14710
14757
  }
14711
14758
  }
14712
14759
  async function convertFeeTokenToWei(ctx, feeTokenAmount, feeTokenIn, evmChainID) {
14760
+ if (TESTNET_CHAINS.has(evmChainID)) return 1n;
14713
14761
  const chain = ctx[feeTokenIn];
14714
14762
  const client = chain.client;
14715
14763
  const wethAddr = chain.configService.getWrappedNativeAssetWithDecimals(evmChainID).asset;
@@ -14825,16 +14873,16 @@ var OrderPlacer = class {
14825
14873
  return { order, receipt };
14826
14874
  }
14827
14875
  };
14876
+
14877
+ // src/protocols/intents/OrderExecutor.ts
14828
14878
  var USED_USEROPS_STORAGE_KEY = (commitment) => `used-userops:${commitment.toLowerCase()}`;
14829
14879
  var OrderExecutor = class {
14830
- constructor(ctx, bidManager, crypto) {
14880
+ constructor(ctx, bidManager) {
14831
14881
  this.ctx = ctx;
14832
14882
  this.bidManager = bidManager;
14833
- this.crypto = crypto;
14834
14883
  }
14835
14884
  ctx;
14836
14885
  bidManager;
14837
- crypto;
14838
14886
  /**
14839
14887
  * Sleeps until the order's block deadline is reached, then yields EXPIRED.
14840
14888
  * Uses the chain's block time to calculate the sleep duration.
@@ -14905,17 +14953,6 @@ var OrderExecutor = class {
14905
14953
  }
14906
14954
  return fetchedBids;
14907
14955
  }
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
14956
  /**
14920
14957
  * Processes a fill result and returns updated fill accumulators,
14921
14958
  * the status update to yield (if any), and whether the order is
@@ -14983,7 +15020,15 @@ var OrderExecutor = class {
14983
15020
  }
14984
15021
  /**
14985
15022
  * Executes an intent order by racing bid polling against the order's
14986
- * block deadline. Yields status updates at each lifecycle stage.
15023
+ * block deadline. Yields status updates at each lifecycle stage and hands
15024
+ * bid selection to the consumer.
15025
+ *
15026
+ * This is a **bidirectional** generator: when it yields `BIDS_RECEIVED`, the
15027
+ * consumer picks a bid, calls `bid.execute()`, and feeds the resulting
15028
+ * {@link SelectBidResult} back via `gen.next(result)`. The generator then
15029
+ * records the dedup entry, emits `BID_SELECTED`, tracks the fill, and either
15030
+ * terminates or continues polling for the remaining amount. Feeding back
15031
+ * `undefined` (no bid executed this round) causes it to keep polling.
14987
15032
  *
14988
15033
  * **Same-chain:** `AWAITING_BIDS` → `BIDS_RECEIVED` → `BID_SELECTED`
14989
15034
  * → (`FILLED` | `PARTIAL_FILL`)* → (`FILLED` | `EXPIRED`)
@@ -14994,7 +15039,6 @@ var OrderExecutor = class {
14994
15039
  async *executeOrder(options) {
14995
15040
  const { order, sessionPrivateKey, auctionTimeMs, pollIntervalMs = DEFAULT_POLL_INTERVAL, solver } = options;
14996
15041
  const commitment = order.id;
14997
- order.source === order.destination;
14998
15042
  if (!this.ctx.intentsCoprocessor) {
14999
15043
  yield { status: "FAILED", error: "IntentsCoprocessor required for order execution" };
15000
15044
  return;
@@ -15022,11 +15066,24 @@ var OrderExecutor = class {
15022
15066
  remainingAssets
15023
15067
  });
15024
15068
  const deadlineTimeout = this.deadlineStream(order.deadline, commitment);
15025
- const combined = mergeRace(deadlineTimeout, executionStream);
15069
+ const deadlinePromise = deadlineTimeout.next();
15026
15070
  try {
15027
- for await (const update of combined) {
15028
- yield update;
15029
- if (update.status === "EXPIRED" || update.status === "FILLED") return;
15071
+ let input;
15072
+ while (true) {
15073
+ const winner = input !== void 0 ? { from: "exec", r: await executionStream.next(input) } : await Promise.race([
15074
+ executionStream.next(void 0).then((r) => ({ from: "exec", r })),
15075
+ deadlinePromise.then((r) => ({ from: "deadline", r }))
15076
+ ]);
15077
+ input = void 0;
15078
+ if (winner.from === "deadline") {
15079
+ if (!winner.r.done && winner.r.value) yield winner.r.value;
15080
+ return;
15081
+ }
15082
+ const { value, done } = winner.r;
15083
+ if (done) return;
15084
+ const fed = yield value;
15085
+ if (value.status === "BIDS_RECEIVED") input = fed;
15086
+ if (value.status === "EXPIRED" || value.status === "FILLED") return;
15030
15087
  }
15031
15088
  } finally {
15032
15089
  console.log(`[OrderExecutor] Tearing down streams for commitment=${commitment}`);
@@ -15035,9 +15092,16 @@ var OrderExecutor = class {
15035
15092
  }
15036
15093
  }
15037
15094
  /**
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.
15095
+ * Core execution loop that polls for bids and tracks fill progress. Builds
15096
+ * first-class {@link Bid} objects from the raw filler bids and yields them to
15097
+ * the consumer, which picks one, calls `bid.execute()`, and feeds the result
15098
+ * back via `gen.next(result)`. The loop then records the dedup entry, emits
15099
+ * `BID_SELECTED`, processes the fill, and continues polling for the remaining
15100
+ * amount on partial fills.
15101
+ *
15102
+ * Bidirectional: the value passed to `.next()` after a `BIDS_RECEIVED` yield is
15103
+ * the {@link SelectBidResult} from the executed bid (or `undefined` to skip the
15104
+ * round and keep polling).
15041
15105
  */
15042
15106
  async *executionStream(params) {
15043
15107
  const {
@@ -15052,12 +15116,7 @@ var OrderExecutor = class {
15052
15116
  targetAssets
15053
15117
  } = params;
15054
15118
  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
- };
15119
+ const isFreshBid = (bid) => !usedUserOps.has(userOpHashKey(bid.userOp));
15061
15120
  const solverLockStartTime = Date.now();
15062
15121
  yield { status: "AWAITING_BIDS", commitment, totalFilledAssets, remainingAssets };
15063
15122
  try {
@@ -15066,13 +15125,13 @@ var OrderExecutor = class {
15066
15125
  while (Date.now() < auctionEnd) {
15067
15126
  try {
15068
15127
  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 };
15128
+ const newBids = bids.filter(
15129
+ (bid) => isFreshBid(bid) && !auctionSeenBids.has(userOpHashKey(bid.userOp))
15130
+ );
15131
+ for (const fillerBid of newBids) {
15132
+ auctionSeenBids.add(userOpHashKey(fillerBid.userOp));
15133
+ const [bid] = this.bidManager.buildBids(order, [fillerBid], sessionPrivateKey);
15134
+ if (bid) yield { status: "NEW_BID", commitment, bid };
15076
15135
  }
15077
15136
  } catch {
15078
15137
  }
@@ -15084,8 +15143,8 @@ var OrderExecutor = class {
15084
15143
  while (true) {
15085
15144
  let freshBids;
15086
15145
  try {
15087
- const bids = await this.fetchBids({ commitment, solver, solverLockStartTime });
15088
- freshBids = bids.filter(isFreshBid);
15146
+ const bids2 = await this.fetchBids({ commitment, solver, solverLockStartTime });
15147
+ freshBids = bids2.filter(isFreshBid);
15089
15148
  } catch {
15090
15149
  await sleep(pollIntervalMs);
15091
15150
  continue;
@@ -15094,56 +15153,33 @@ var OrderExecutor = class {
15094
15153
  await sleep(pollIntervalMs);
15095
15154
  continue;
15096
15155
  }
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
- }
15156
+ const bids = this.bidManager.buildBids(order, freshBids, sessionPrivateKey);
15157
+ if (bids.length === 0) {
15158
+ await sleep(pollIntervalMs);
15159
+ continue;
15160
+ }
15161
+ const result = yield { status: "BIDS_RECEIVED", commitment, bidCount: bids.length, bids };
15162
+ if (!result) {
15124
15163
  await sleep(pollIntervalMs);
15125
15164
  continue;
15126
15165
  }
15166
+ usedUserOps.add(userOpHashKey(result.userOp));
15167
+ await this.persistUsedUserOps(commitment, usedUserOps);
15127
15168
  yield {
15128
15169
  status: "BID_SELECTED",
15129
15170
  commitment,
15130
- selectedSolver: submitResult.solverAddress,
15131
- userOpHash: submitResult.userOpHash,
15132
- userOp: submitResult.userOp,
15133
- transactionHash: submitResult.txnHash
15171
+ selectedSolver: result.solverAddress,
15172
+ userOpHash: result.userOpHash,
15173
+ userOp: result.userOp,
15174
+ transactionHash: result.txnHash
15134
15175
  };
15135
- const fill = this.processFillResult(
15136
- submitResult,
15137
- commitment,
15138
- targetAssets,
15139
- totalFilledAssets,
15140
- remainingAssets
15141
- );
15176
+ const fill = this.processFillResult(result, commitment, targetAssets, totalFilledAssets, remainingAssets);
15142
15177
  totalFilledAssets = fill.totalFilledAssets;
15143
15178
  remainingAssets = fill.remainingAssets;
15144
15179
  if (fill.update) {
15145
15180
  yield fill.update;
15146
15181
  }
15182
+ if (fill.done) return;
15147
15183
  }
15148
15184
  } catch (err) {
15149
15185
  yield {
@@ -15618,183 +15654,148 @@ var OrderCanceller = class {
15618
15654
  return feeInDestFeeToken * 1005n / 1000n;
15619
15655
  }
15620
15656
  };
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
- }
15657
+ var BidImpl = class {
15658
+ solverAddress;
15659
+ outputs;
15660
+ relayerFee;
15661
+ nativeDispatchFee;
15662
+ userOp;
15632
15663
  ctx;
15633
15664
  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(
15665
+ order;
15666
+ fillOptions;
15667
+ priceOutputs;
15668
+ sessionPrivateKey;
15669
+ intentGatewayV2Address;
15670
+ domainSeparator;
15671
+ /** Cached session-key signature over the `SelectSolver` message. */
15672
+ cachedSignature;
15673
+ constructor(params) {
15674
+ this.ctx = params.ctx;
15675
+ this.crypto = params.crypto;
15676
+ this.order = params.order;
15677
+ this.fillOptions = params.fillOptions;
15678
+ this.priceOutputs = params.priceOutputs;
15679
+ this.sessionPrivateKey = params.sessionPrivateKey;
15680
+ this.solverAddress = params.fillerBid.userOp.sender;
15681
+ this.outputs = params.fillOptions.outputs;
15682
+ this.relayerFee = params.fillOptions.relayerFee;
15683
+ this.nativeDispatchFee = params.fillOptions.nativeDispatchFee;
15684
+ this.userOp = params.fillerBid.userOp;
15685
+ this.intentGatewayV2Address = this.ctx.dest.configService.getIntentGatewayAddress(
15686
+ normalizeStateMachineId(this.order.destination)
15687
+ );
15688
+ this.domainSeparator = CryptoUtils.getDomainSeparator(
15689
+ "IntentGateway",
15690
+ "2",
15691
+ this.chainId(),
15692
+ this.intentGatewayV2Address
15693
+ );
15694
+ }
15695
+ /** Resolves the destination chain id from the client or the state-machine id. */
15696
+ chainId() {
15697
+ return BigInt(
15663
15698
  this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15664
15699
  );
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
15700
  }
15685
15701
  /**
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.
15702
+ * Resolves the session key, signs the `SelectSolver` message for this bid's
15703
+ * solver, and caches the signature. Signs at most once per bid.
15689
15704
  *
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.
15699
- *
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.
15705
+ * @throws If the session key is missing or signing fails.
15708
15706
  */
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);
15707
+ async signSelection() {
15708
+ if (this.cachedSignature) return this.cachedSignature;
15709
+ const commitment = this.order.id;
15710
+ const sessionKeyAddress = this.order.session;
15711
+ const sessionKeyData = this.sessionPrivateKey ? { privateKey: this.sessionPrivateKey } : await this.ctx.sessionKeyStorage.getSessionKeyByAddress(sessionKeyAddress);
15714
15712
  if (!sessionKeyData) {
15715
15713
  throw new Error("SessionKey not found for commitment: " + commitment);
15716
15714
  }
15717
- if (!this.ctx.bundlerUrl) {
15718
- throw new Error("Bundler URL not configured");
15719
- }
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
15715
+ const signature = await CryptoUtils.signSolverSelection(
15716
+ commitment,
15717
+ this.solverAddress,
15718
+ this.domainSeparator,
15719
+ sessionKeyData.privateKey
15738
15720
  );
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
- }
15721
+ if (!signature) {
15722
+ throw new Error("Failed to sign solver selection");
15773
15723
  }
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");
15724
+ this.cachedSignature = signature;
15725
+ return signature;
15726
+ }
15727
+ /**
15728
+ * Simulates this bid on-chain by batching the `select` and `fillOrder` calls
15729
+ * via `eth_call` from the solver's account, using the IntentGatewayV2 ERC-7821
15730
+ * batch-execute pattern.
15731
+ *
15732
+ * The native value forwarded to the simulation is the sum of any native-token
15733
+ * (`address(0)`) output amounts plus the Hyperbridge dispatch fee.
15734
+ *
15735
+ * @throws If the `eth_call` simulation reverts or errors.
15736
+ */
15737
+ async simulate() {
15738
+ const signature = await this.signSelection();
15739
+ const selectOptions = {
15740
+ commitment: this.order.id,
15741
+ solver: this.solverAddress,
15742
+ signature
15743
+ };
15744
+ const nativeOutputs = this.fillOptions.outputs.reduce(
15745
+ (acc, o) => bytes32ToBytes20(o.token) === ADDRESS_ZERO2 ? acc + o.amount : acc,
15746
+ 0n
15747
+ );
15748
+ const simulationValue = nativeOutputs + this.fillOptions.nativeDispatchFee;
15749
+ const selectCalldata = encodeFunctionData({
15750
+ abi: ABI3,
15751
+ functionName: "select",
15752
+ args: [selectOptions]
15753
+ });
15754
+ const calls = [
15755
+ { target: this.intentGatewayV2Address, value: 0n, data: selectCalldata },
15756
+ { target: this.solverAddress, value: simulationValue, data: this.userOp.callData }
15757
+ ];
15758
+ const batchedCalldata = this.crypto.encodeERC7821Execute(calls);
15759
+ try {
15760
+ await this.ctx.dest.client.call({
15761
+ account: this.solverAddress,
15762
+ to: this.solverAddress,
15763
+ data: batchedCalldata,
15764
+ value: simulationValue
15765
+ });
15766
+ } catch (e) {
15767
+ throw new Error(`Simulation failed: ${e instanceof Error ? e.message : String(e)}`);
15777
15768
  }
15778
- const solverAddress = selectedBid.bid.userOp.sender;
15779
- const finalSignature = concat([
15780
- selectedBid.bid.userOp.signature,
15781
- sessionSignature
15782
- ]);
15769
+ }
15770
+ /**
15771
+ * Signs the `SelectSolver` message with the session key, appends it to the
15772
+ * solver's existing UserOp signature, and submits the UserOperation to the
15773
+ * bundler. For same-chain orders, waits for the receipt and reads
15774
+ * `OrderFilled` / `PartialFill` logs to determine fill status.
15775
+ *
15776
+ * @returns A {@link SelectBidResult} with the submitted UserOperation, its hash,
15777
+ * the solver address, transaction hash, and fill status.
15778
+ * @throws If the bundler is not configured, the session key is missing, or the
15779
+ * bundler rejects the UserOperation.
15780
+ */
15781
+ async execute() {
15782
+ const commitment = this.order.id;
15783
+ if (!this.ctx.bundlerUrl) {
15784
+ throw new Error("Bundler URL not configured");
15785
+ }
15786
+ const sessionSignature = await this.signSelection();
15787
+ const finalSignature = concat([this.userOp.signature, sessionSignature]);
15783
15788
  const signedUserOp = {
15784
- ...selectedBid.bid.userOp,
15789
+ ...this.userOp,
15785
15790
  signature: finalSignature
15786
15791
  };
15787
15792
  const entryPointAddress = this.ctx.dest.configService.getEntryPointV08Address(
15788
- normalizeStateMachineId(order.destination)
15793
+ normalizeStateMachineId(this.order.destination)
15789
15794
  );
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, [
15795
+ const userOpHash = await this.crypto.sendBundler(BundlerMethod.ETH_SEND_USER_OPERATION, [
15794
15796
  CryptoUtils.prepareBundlerCall(signedUserOp),
15795
15797
  entryPointAddress
15796
15798
  ]);
15797
- const userOpHash = bundlerResult;
15798
15799
  let txnHash;
15799
15800
  let fillStatus;
15800
15801
  let filledAssets;
@@ -15810,7 +15811,7 @@ var BidManager = class {
15810
15811
  { maxRetries: 5, backoffMs: 2e3, logMessage: "Fetching user operation receipt" }
15811
15812
  );
15812
15813
  txnHash = receipt.receipt.transactionHash;
15813
- if (order.source === order.destination) {
15814
+ if (this.order.source === this.order.destination) {
15814
15815
  try {
15815
15816
  const chainReceipt = await this.ctx.dest.client.waitForTransactionReceipt({
15816
15817
  hash: txnHash,
@@ -15839,12 +15840,12 @@ var BidManager = class {
15839
15840
  }
15840
15841
  }
15841
15842
  } catch (err) {
15842
- throw new Error(`Failed to select bid: ${err instanceof Error ? err.message : String(err)}`);
15843
+ throw new Error(`Failed to execute bid: ${err instanceof Error ? err.message : String(err)}`);
15843
15844
  }
15844
15845
  return {
15845
15846
  userOp: signedUserOp,
15846
15847
  userOpHash,
15847
- solverAddress,
15848
+ solverAddress: this.solverAddress,
15848
15849
  commitment,
15849
15850
  txnHash,
15850
15851
  fillStatus,
@@ -15852,7 +15853,177 @@ var BidManager = class {
15852
15853
  };
15853
15854
  }
15854
15855
  /**
15855
- * Validates and sorts a list of raw bids for the given order.
15856
+ * Prices this bid's outputs in USD using the destination chain's DEX-quote
15857
+ * helpers. Returns `null` when any output token cannot be priced.
15858
+ */
15859
+ async outputUsdValue() {
15860
+ return this.priceOutputs(this.outputs);
15861
+ }
15862
+ };
15863
+ var BidManager = class {
15864
+ /**
15865
+ * @param ctx - Shared IntentsV2 context providing the destination chain
15866
+ * client, coprocessor, bundler URL, and session-key storage.
15867
+ * @param crypto - Crypto utilities used for gas packing, UserOp hashing,
15868
+ * EIP-712 signing, and bundler calls.
15869
+ */
15870
+ constructor(ctx, crypto) {
15871
+ this.ctx = ctx;
15872
+ this.crypto = crypto;
15873
+ }
15874
+ ctx;
15875
+ crypto;
15876
+ /**
15877
+ * Constructs a signed `PackedUserOperation` that a solver can submit to the
15878
+ * Hyperbridge coprocessor as a bid to fill an order.
15879
+ *
15880
+ * The solver's signature covers a hash that binds the UserOperation to the
15881
+ * order commitment and the session key address, so the IntentGatewayV2
15882
+ * contract can verify the solver's intent on-chain.
15883
+ *
15884
+ * @param options - Parameters describing the solver account, gas limits, fee
15885
+ * market values, and pre-built `callData` for the fill operation.
15886
+ * @returns A `PackedUserOperation` with the solver's signature prepended
15887
+ * with the order commitment.
15888
+ */
15889
+ async prepareSubmitBid(options) {
15890
+ const {
15891
+ order,
15892
+ solverAccount,
15893
+ solverSigner,
15894
+ nonce,
15895
+ entryPointAddress,
15896
+ callGasLimit,
15897
+ verificationGasLimit,
15898
+ preVerificationGas,
15899
+ maxFeePerGas,
15900
+ maxPriorityFeePerGas,
15901
+ callData,
15902
+ paymasterAndData = "0x"
15903
+ } = options;
15904
+ const chainId = BigInt(
15905
+ this.ctx.dest.client.chain?.id ?? Number.parseInt(this.ctx.dest.config.stateMachineId.split("-")[1])
15906
+ );
15907
+ const accountGasLimits = CryptoUtils.packGasLimits(verificationGasLimit, callGasLimit);
15908
+ const gasFees = CryptoUtils.packGasFees(maxPriorityFeePerGas, maxFeePerGas);
15909
+ const userOp = {
15910
+ sender: solverAccount,
15911
+ nonce,
15912
+ initCode: "0x",
15913
+ callData,
15914
+ accountGasLimits,
15915
+ preVerificationGas,
15916
+ gasFees,
15917
+ paymasterAndData,
15918
+ signature: "0x"
15919
+ };
15920
+ const userOpHash = CryptoUtils.computeUserOpHash(userOp, entryPointAddress, chainId);
15921
+ const sessionKey = order.session;
15922
+ const messageHash = keccak256(concat([userOpHash, order.id, sessionKey]));
15923
+ const solverSignature = await solverSigner.signMessage(messageHash, Number(chainId));
15924
+ const signature = concat([order.id, solverSignature]);
15925
+ return { ...userOp, signature };
15926
+ }
15927
+ /**
15928
+ * Decodes raw filler bids into first-class {@link Bid} objects.
15929
+ *
15930
+ * Each bid's `fillOrder` fill-options are decoded from its ERC-7821 calldata;
15931
+ * bids whose calldata cannot be decoded into a valid `fillOrder` call are
15932
+ * silently dropped with a warning. The returned `Bid` instances are ready to
15933
+ * be ranked, simulated, and executed by the consumer.
15934
+ *
15935
+ * @param order - The placed order the bids are competing to fill.
15936
+ * @param bids - Raw filler bids fetched from the coprocessor.
15937
+ * @param sessionPrivateKey - Optional session-key override; looked up from
15938
+ * storage by `order.session` if omitted.
15939
+ * @returns Array of executable `Bid` objects (one per successfully decoded bid).
15940
+ */
15941
+ buildBids(order, bids, sessionPrivateKey) {
15942
+ const chainId = this.ctx.dest.config.stateMachineId;
15943
+ const priceOutputs = (outputs) => this.computeOutputsUsdValue(outputs, chainId);
15944
+ const result = [];
15945
+ for (const fillerBid of bids) {
15946
+ const fillOptions = this.decodeBidFillOptions(fillerBid);
15947
+ if (!fillOptions) {
15948
+ console.warn(`[BidManager] Failed to decode fillOptions from bid by solver=${fillerBid.userOp.sender}`);
15949
+ continue;
15950
+ }
15951
+ result.push(
15952
+ new BidImpl({
15953
+ ctx: this.ctx,
15954
+ crypto: this.crypto,
15955
+ order,
15956
+ fillerBid,
15957
+ fillOptions,
15958
+ priceOutputs,
15959
+ sessionPrivateKey
15960
+ })
15961
+ );
15962
+ }
15963
+ console.log(`[BidManager] Built ${result.length}/${bids.length} bid(s) successfully`);
15964
+ return result;
15965
+ }
15966
+ /**
15967
+ * Decodes raw filler bids, sorts them, simulates each until one passes, signs
15968
+ * the `SelectSolver` message, and submits — all with no per-bid input from the
15969
+ * caller.
15970
+ *
15971
+ * Equivalent to `selectAndExecuteBest(order, buildBids(order, bids, key))`.
15972
+ *
15973
+ * @param order - The placed order to fill.
15974
+ * @param bids - Raw filler bids fetched from the coprocessor.
15975
+ * @param sessionPrivateKey - Optional session-key override; looked up from
15976
+ * storage by `order.session` if omitted.
15977
+ * @returns A {@link SelectBidResult} for the executed bid.
15978
+ */
15979
+ async selectBid(order, bids, sessionPrivateKey) {
15980
+ return this.selectAndExecuteBest(order, this.buildBids(order, bids, sessionPrivateKey));
15981
+ }
15982
+ /**
15983
+ * Autopilot bid selection: sorts the given bids by output value, simulates
15984
+ * each in order until one passes, then executes that bid. For consumers that
15985
+ * do not need custom selection logic.
15986
+ *
15987
+ * @param order - The placed order to fill.
15988
+ * @param bids - Candidate bids (from {@link buildBids}).
15989
+ * @returns A {@link SelectBidResult} for the executed bid.
15990
+ * @throws If no valid bids exist, all simulations fail, or the bundler rejects
15991
+ * the UserOperation.
15992
+ */
15993
+ async selectAndExecuteBest(order, bids) {
15994
+ const commitment = order.id;
15995
+ console.log(`[BidManager] selectAndExecuteBest called for commitment=${commitment}, ${bids.length} bid(s)`);
15996
+ if (!this.ctx.bundlerUrl) {
15997
+ throw new Error("Bundler URL not configured");
15998
+ }
15999
+ if (!this.ctx.intentsCoprocessor) {
16000
+ throw new Error("IntentsCoprocessor required");
16001
+ }
16002
+ const sortedBids = await this.sortBids(order, bids);
16003
+ console.log(`[BidManager] ${sortedBids.length}/${bids.length} bid(s) passed validation and sorting`);
16004
+ if (sortedBids.length === 0) {
16005
+ throw new Error("No valid bids found");
16006
+ }
16007
+ console.log(`[BidManager] Simulating ${sortedBids.length} sorted bid(s) to find a valid one`);
16008
+ for (let idx = 0; idx < sortedBids.length; idx++) {
16009
+ const bid = sortedBids[idx];
16010
+ console.log(`[BidManager] Simulating bid ${idx + 1}/${sortedBids.length} from solver=${bid.solverAddress}`);
16011
+ try {
16012
+ await bid.simulate();
16013
+ } catch (err) {
16014
+ console.warn(
16015
+ `[BidManager] Bid ${idx + 1} from solver=${bid.solverAddress}: simulation FAILED: ${err instanceof Error ? err.message : String(err)}`
16016
+ );
16017
+ continue;
16018
+ }
16019
+ console.log(`[BidManager] Bid ${idx + 1} from solver=${bid.solverAddress}: simulation PASSED`);
16020
+ return bid.execute();
16021
+ }
16022
+ console.error(`[BidManager] All ${sortedBids.length} bid(s) failed simulation for commitment=${commitment}`);
16023
+ throw new Error("No bids passed simulation");
16024
+ }
16025
+ /**
16026
+ * Sorts a list of bids for the given order by output value.
15856
16027
  *
15857
16028
  * Delegates to one of three strategies based on the order's output token
15858
16029
  * composition:
@@ -15861,47 +16032,26 @@ var BidManager = class {
15861
16032
  * - Mixed outputs: sort by DEX-quoted USD value descending, with a raw-amount
15862
16033
  * fallback if pricing fails.
15863
16034
  *
15864
- * @param bids - Raw filler bids from the coprocessor.
16035
+ * Bids that cannot satisfy the order's token set are dropped.
16036
+ *
15865
16037
  * @param order - The placed order whose output spec drives sorting logic.
15866
- * @returns Sorted array of `{ bid, options }` pairs ready for simulation.
16038
+ * @param bids - Executable bids to sort (from {@link buildBids}).
16039
+ * @returns Sorted array of `Bid` objects ready for simulation.
15867
16040
  */
15868
- async validateAndSortBids(bids, order) {
16041
+ async sortBids(order, bids) {
15869
16042
  const outputs = order.output.assets;
15870
- const decodedBids = this.decodeBids(bids);
15871
16043
  if (outputs.length <= 1) {
15872
16044
  console.log(`[BidManager] Using single-output sorting (1 output asset)`);
15873
- return this.sortSingleOutput(decodedBids, outputs[0]);
16045
+ return this.sortSingleOutput(bids, outputs[0]);
15874
16046
  }
15875
16047
  const chainId = this.ctx.dest.config.stateMachineId;
15876
16048
  const allStables = outputs.every((o) => this.isStableToken(bytes32ToBytes20(o.token), chainId));
15877
16049
  if (allStables) {
15878
16050
  console.log(`[BidManager] Using all-stables sorting (${outputs.length} stable output assets)`);
15879
- return this.sortAllStables(decodedBids, outputs, chainId);
16051
+ return this.sortAllStables(bids, outputs, chainId);
15880
16052
  }
15881
16053
  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;
16054
+ return this.sortMixedOutputs(bids, outputs, chainId);
15905
16055
  }
15906
16056
  /**
15907
16057
  * Extracts the `FillOptions` struct from a single bid's ERC-7821
@@ -15934,149 +16084,103 @@ var BidManager = class {
15934
16084
  }
15935
16085
  return null;
15936
16086
  }
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
16087
  /**
15980
16088
  * Case A: single output token.
15981
16089
  * Filter bids by token match only, sort descending by amount.
15982
16090
  * Partial fill bids are allowed — the contract determines fill status.
15983
16091
  */
15984
- sortSingleOutput(decodedBids, requiredAsset) {
16092
+ sortSingleOutput(bids, requiredAsset) {
15985
16093
  const requiredAmount = new Decimal2(requiredAsset.amount.toString());
15986
16094
  console.log(
15987
16095
  `[BidManager] sortSingleOutput: required token=${requiredAsset.token}, amount=${requiredAmount.toString()}`
15988
16096
  );
15989
16097
  const validBids = [];
15990
- for (const { bid, options } of decodedBids) {
15991
- const bidOutput = options.outputs[0];
16098
+ for (const bid of bids) {
16099
+ const bidOutput = bid.outputs[0];
15992
16100
  const bidAmount = new Decimal2(bidOutput.amount.toString());
15993
16101
  if (bidOutput.token.toLowerCase() !== requiredAsset.token.toLowerCase()) {
15994
16102
  console.warn(
15995
- `[BidManager] Bid from solver=${bid.userOp.sender} REJECTED: token mismatch (bid=${bidOutput.token}, required=${requiredAsset.token})`
16103
+ `[BidManager] Bid from solver=${bid.solverAddress} REJECTED: token mismatch (bid=${bidOutput.token}, required=${requiredAsset.token})`
15996
16104
  );
15997
16105
  continue;
15998
16106
  }
15999
16107
  if (bidAmount.lt(requiredAmount)) {
16000
16108
  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)}%)`
16109
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (bid=${bidAmount.toString()}, required=${requiredAmount.toString()}, covers=${bidAmount.div(requiredAmount).mul(100).toFixed(2)}%)`
16002
16110
  );
16003
16111
  } else {
16004
16112
  console.log(
16005
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED: amount=${bidAmount.toString()} (surplus=${bidAmount.minus(requiredAmount).toString()})`
16113
+ `[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED: amount=${bidAmount.toString()} (surplus=${bidAmount.minus(requiredAmount).toString()})`
16006
16114
  );
16007
16115
  }
16008
- validBids.push({ bid, options, amount: bidOutput.amount });
16116
+ validBids.push({ bid, amount: bidOutput.amount });
16009
16117
  }
16010
16118
  validBids.sort((a, b) => {
16011
16119
  const aAmt = new Decimal2(a.amount.toString());
16012
16120
  const bAmt = new Decimal2(b.amount.toString());
16013
16121
  return bAmt.comparedTo(aAmt);
16014
16122
  });
16015
- return validBids.map(({ amount: _, ...rest }) => rest);
16123
+ return validBids.map(({ bid }) => bid);
16016
16124
  }
16017
16125
  /**
16018
16126
  * Case B: all outputs are USDC/USDT.
16019
16127
  * Sum normalised USD values (treating each stable as $1) and sort descending.
16020
16128
  * Partial fill bids are allowed.
16021
16129
  */
16022
- sortAllStables(decodedBids, orderOutputs, chainId) {
16130
+ sortAllStables(bids, orderOutputs, chainId) {
16023
16131
  const requiredUsd = this.computeStablesUsdValue(orderOutputs, chainId);
16024
16132
  console.log(`[BidManager] sortAllStables: required USD value=${requiredUsd.toString()}`);
16025
16133
  const validBids = [];
16026
- for (const { bid, options } of decodedBids) {
16027
- const bidUsd = this.computeStablesUsdValue(options.outputs, chainId);
16134
+ for (const bid of bids) {
16135
+ const bidUsd = this.computeStablesUsdValue(bid.outputs, chainId);
16028
16136
  if (bidUsd === null) {
16029
- console.warn(`[BidManager] Bid from solver=${bid.userOp.sender} REJECTED: unable to compute USD value`);
16137
+ console.warn(`[BidManager] Bid from solver=${bid.solverAddress} REJECTED: unable to compute USD value`);
16030
16138
  continue;
16031
16139
  }
16032
16140
  if (bidUsd.lt(requiredUsd)) {
16033
16141
  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)}%)`
16142
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (bid=${bidUsd.toString()}, required=${requiredUsd.toString()}, covers=${bidUsd.div(requiredUsd).mul(100).toFixed(2)}%)`
16035
16143
  );
16036
16144
  } else {
16037
- console.log(
16038
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED: USD value=${bidUsd.toString()}`
16039
- );
16145
+ console.log(`[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED: USD value=${bidUsd.toString()}`);
16040
16146
  }
16041
- validBids.push({ bid, options, usdValue: bidUsd });
16147
+ validBids.push({ bid, usdValue: bidUsd });
16042
16148
  }
16043
16149
  validBids.sort((a, b) => b.usdValue.comparedTo(a.usdValue));
16044
- return validBids.map(({ usdValue: _, ...rest }) => rest);
16150
+ return validBids.map(({ bid }) => bid);
16045
16151
  }
16046
16152
  /**
16047
16153
  * Case C: mixed output tokens (at least one non-stable).
16048
16154
  * Price every token via on-chain DEX quotes, fall back to raw amounts
16049
16155
  * if pricing is unavailable. Partial fill bids are allowed.
16050
16156
  */
16051
- async sortMixedOutputs(decodedBids, orderOutputs, chainId) {
16157
+ async sortMixedOutputs(bids, orderOutputs, chainId) {
16052
16158
  const requiredUsd = await this.computeOutputsUsdValue(orderOutputs, chainId);
16053
16159
  if (requiredUsd === null) {
16054
16160
  console.warn("[BidManager] sortMixedOutputs: output tokens unpriceable, falling back to raw-amount sort");
16055
- return this.sortByRawAmountFallback(decodedBids, orderOutputs);
16161
+ return this.sortByRawAmountFallback(bids, orderOutputs);
16056
16162
  }
16057
16163
  console.log(`[BidManager] sortMixedOutputs: required USD value=${requiredUsd.toString()}`);
16058
16164
  const validBids = [];
16059
- for (const { bid, options } of decodedBids) {
16060
- const bidUsd = await this.computeOutputsUsdValue(options.outputs, chainId);
16165
+ for (const bid of bids) {
16166
+ const bidUsd = await this.computeOutputsUsdValue(bid.outputs, chainId);
16061
16167
  if (bidUsd === null) {
16062
- console.warn(
16063
- `[BidManager] Bid from solver=${bid.userOp.sender} REJECTED: unable to price mixed outputs`
16064
- );
16168
+ console.warn(`[BidManager] Bid from solver=${bid.solverAddress} REJECTED: unable to price mixed outputs`);
16065
16169
  continue;
16066
16170
  }
16067
16171
  if (bidUsd.lt(requiredUsd)) {
16068
16172
  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)}%)`
16173
+ `[BidManager] Bid from solver=${bid.solverAddress}: partial fill candidate (bid=${bidUsd.toString()}, required=${requiredUsd.toString()}, covers=${bidUsd.div(requiredUsd).mul(100).toFixed(2)}%)`
16070
16174
  );
16071
16175
  } else {
16072
16176
  console.log(
16073
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED: mixed USD value=${bidUsd.toString()}`
16177
+ `[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED: mixed USD value=${bidUsd.toString()}`
16074
16178
  );
16075
16179
  }
16076
- validBids.push({ bid, options, usdValue: bidUsd });
16180
+ validBids.push({ bid, usdValue: bidUsd });
16077
16181
  }
16078
16182
  validBids.sort((a, b) => b.usdValue.comparedTo(a.usdValue));
16079
- return validBids.map(({ usdValue: _, ...rest }) => rest);
16183
+ return validBids.map(({ bid }) => bid);
16080
16184
  }
16081
16185
  /**
16082
16186
  * Fallback when DEX pricing is unavailable.
@@ -16084,17 +16188,17 @@ var BidManager = class {
16084
16188
  * Bids offering less than required for a token are allowed (partial fill).
16085
16189
  * Sorted by total offered amount descending.
16086
16190
  */
16087
- sortByRawAmountFallback(decodedBids, orderOutputs) {
16191
+ sortByRawAmountFallback(bids, orderOutputs) {
16088
16192
  console.log(
16089
- `[BidManager] sortByRawAmountFallback: checking ${decodedBids.length} bid(s) against ${orderOutputs.length} required output(s)`
16193
+ `[BidManager] sortByRawAmountFallback: checking ${bids.length} bid(s) against ${orderOutputs.length} required output(s)`
16090
16194
  );
16091
16195
  const validBids = [];
16092
- for (const { bid, options } of decodedBids) {
16196
+ for (const bid of bids) {
16093
16197
  let valid = true;
16094
16198
  let totalOffered = new Decimal2(0);
16095
16199
  let rejectReason = "";
16096
16200
  for (const required of orderOutputs) {
16097
- const matching = options.outputs.find((o) => o.token.toLowerCase() === required.token.toLowerCase());
16201
+ const matching = bid.outputs.find((o) => o.token.toLowerCase() === required.token.toLowerCase());
16098
16202
  if (!matching) {
16099
16203
  valid = false;
16100
16204
  rejectReason = `missing output token=${required.token}`;
@@ -16103,7 +16207,7 @@ var BidManager = class {
16103
16207
  totalOffered = totalOffered.plus(new Decimal2(matching.amount.toString()));
16104
16208
  }
16105
16209
  if (!valid) {
16106
- console.warn(`[BidManager] Bid from solver=${bid.userOp.sender} REJECTED (fallback): ${rejectReason}`);
16210
+ console.warn(`[BidManager] Bid from solver=${bid.solverAddress} REJECTED (fallback): ${rejectReason}`);
16107
16211
  continue;
16108
16212
  }
16109
16213
  const totalRequired = orderOutputs.reduce(
@@ -16112,17 +16216,17 @@ var BidManager = class {
16112
16216
  );
16113
16217
  if (totalOffered.lt(totalRequired)) {
16114
16218
  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)}%)`
16219
+ `[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
16220
  );
16117
16221
  } else {
16118
16222
  console.log(
16119
- `[BidManager] Bid from solver=${bid.userOp.sender} ACCEPTED (fallback): totalOffered=${totalOffered.toString()}`
16223
+ `[BidManager] Bid from solver=${bid.solverAddress} ACCEPTED (fallback): totalOffered=${totalOffered.toString()}`
16120
16224
  );
16121
16225
  }
16122
- validBids.push({ bid, options, totalOffered });
16226
+ validBids.push({ bid, totalOffered });
16123
16227
  }
16124
16228
  validBids.sort((a, b) => b.totalOffered.comparedTo(a.totalOffered));
16125
- return validBids.map(({ totalOffered: _, ...rest }) => rest);
16229
+ return validBids.map(({ bid }) => bid);
16126
16230
  }
16127
16231
  // ── Token classification helpers ──────────────────────────────────
16128
16232
  /**
@@ -16731,6 +16835,262 @@ var OrderStatusChecker = class {
16731
16835
  }
16732
16836
  };
16733
16837
 
16838
+ // src/protocols/intents/quote/types.ts
16839
+ var UnsupportedIntentQuoteStrategyError = class extends Error {
16840
+ constructor(strategy) {
16841
+ super(`Unsupported intent quote strategy: ${strategy}`);
16842
+ this.name = "UnsupportedIntentQuoteStrategyError";
16843
+ }
16844
+ };
16845
+ var UnsupportedIntentQuotePairError = class extends Error {
16846
+ constructor(params) {
16847
+ super(
16848
+ `No Uniswap v4 pool config found for ${params.tokenIn.symbol ?? params.tokenIn.address} -> ${params.tokenOut.symbol ?? params.tokenOut.address} on ${params.source} -> ${params.destination}`
16849
+ );
16850
+ this.name = "UnsupportedIntentQuotePairError";
16851
+ }
16852
+ };
16853
+
16854
+ // src/protocols/intents/quote/uniswapV4.ts
16855
+ var UNISWAP_INTENT_QUOTE_CHAIN = "EVM-8453" /* BASE_MAINNET */;
16856
+ var BPS_DENOMINATOR = 10000n;
16857
+ var UniswapV4IntentQuoteStrategy = class {
16858
+ constructor(chainConfigService) {
16859
+ this.chainConfigService = chainConfigService;
16860
+ }
16861
+ chainConfigService;
16862
+ baseQuoteClient;
16863
+ async quote(params, source, destination) {
16864
+ this.validateQuoteParams(params);
16865
+ const protocolFeeBps = await this.readProtocolFeeBps(source.client, source.stateMachineId);
16866
+ const quoteClient = this.resolveQuoteClient(source, destination);
16867
+ const poolConfig = this.resolvePoolConfig(params, source.stateMachineId, UNISWAP_INTENT_QUOTE_CHAIN);
16868
+ return params.amountIn !== void 0 ? this.quoteExactInput({ params, client: quoteClient, protocolFeeBps, poolConfig }) : this.quoteExactOutput({ params, client: quoteClient, protocolFeeBps, poolConfig });
16869
+ }
16870
+ resolveQuoteClient(source, destination) {
16871
+ if (source.stateMachineId === UNISWAP_INTENT_QUOTE_CHAIN) return source.client;
16872
+ if (destination.stateMachineId === UNISWAP_INTENT_QUOTE_CHAIN) return destination.client;
16873
+ if (this.baseQuoteClient) return this.baseQuoteClient;
16874
+ const rpcUrl = this.chainConfigService.getRpcUrl(UNISWAP_INTENT_QUOTE_CHAIN);
16875
+ if (!rpcUrl) throw new Error(`RPC URL is not configured for ${UNISWAP_INTENT_QUOTE_CHAIN}`);
16876
+ const baseQuoteClient = createPublicClient({
16877
+ chain: base,
16878
+ transport: http(rpcUrl)
16879
+ });
16880
+ this.baseQuoteClient = baseQuoteClient;
16881
+ return baseQuoteClient;
16882
+ }
16883
+ validateQuoteParams(params) {
16884
+ const hasAmountIn = params.amountIn !== void 0;
16885
+ const hasAmountOut = params.amountOut !== void 0;
16886
+ if (hasAmountIn === hasAmountOut) throw new Error("Provide exactly one of amountIn or amountOut");
16887
+ if (hasAmountIn && params.amountIn <= 0n) throw new Error("amountIn must be greater than zero");
16888
+ if (hasAmountOut && params.amountOut <= 0n) throw new Error("amountOut must be greater than zero");
16889
+ if (params.tokenIn.address.toLowerCase() === params.tokenOut.address.toLowerCase()) {
16890
+ throw new Error("tokenIn and tokenOut cannot be the same");
16891
+ }
16892
+ }
16893
+ async readProtocolFeeBps(client, chain) {
16894
+ const gatewayAddress = this.chainConfigService.getIntentGatewayAddress(chain);
16895
+ if (!gatewayAddress || gatewayAddress === "0x" || gatewayAddress === zeroAddress) {
16896
+ throw new Error(`IntentGatewayV2 is not configured for chain ${chain}`);
16897
+ }
16898
+ const gatewayParams = await client.readContract({
16899
+ address: gatewayAddress,
16900
+ abi: IntentGatewayV2_default.ABI,
16901
+ functionName: "params"
16902
+ });
16903
+ if (isGatewayParamsTuple(gatewayParams)) return BigInt(gatewayParams[4]);
16904
+ return BigInt(gatewayParams.protocolFeeBps ?? 0);
16905
+ }
16906
+ resolvePoolConfig(params, source, destination) {
16907
+ const override = params.uniswapV4?.poolKey;
16908
+ if (override) {
16909
+ const poolKey = normalizePoolKey(override);
16910
+ const tokenInForQuote = getAddress(override.currencyIn ?? params.tokenIn.address);
16911
+ if (tokenInForQuote !== poolKey.currency0 && tokenInForQuote !== poolKey.currency1) {
16912
+ throw new Error(
16913
+ `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.`
16914
+ );
16915
+ }
16916
+ return {
16917
+ poolKey,
16918
+ quoterAddress: this.resolveQuoterAddress(destination, override.quoterAddress),
16919
+ tokenInForQuote
16920
+ };
16921
+ }
16922
+ const poolConfig = this.resolveConfiguredPool(params, destination);
16923
+ if (poolConfig) return poolConfig;
16924
+ throw new UnsupportedIntentQuotePairError({
16925
+ source,
16926
+ destination,
16927
+ tokenIn: params.tokenIn,
16928
+ tokenOut: params.tokenOut
16929
+ });
16930
+ }
16931
+ resolveConfiguredPool(params, chain) {
16932
+ for (const pool of this.chainConfigService.getUniswapV4PoolConfigs(chain)) {
16933
+ const resolvedPool = this.resolveConfiguredPoolTokens(chain, pool);
16934
+ if (!resolvedPool) continue;
16935
+ const tokenInForQuote = matchPoolToken(params.tokenIn, resolvedPool);
16936
+ const tokenOutForQuote = matchPoolToken(params.tokenOut, resolvedPool);
16937
+ if (!tokenInForQuote || !tokenOutForQuote || tokenInForQuote.symbol === tokenOutForQuote.symbol) continue;
16938
+ const { currency0, currency1 } = sortCurrencies(resolvedPool[0].address, resolvedPool[1].address);
16939
+ return {
16940
+ poolKey: {
16941
+ currency0,
16942
+ currency1,
16943
+ fee: pool.fee,
16944
+ tickSpacing: pool.tickSpacing,
16945
+ hooks: getAddress(pool.hooks ?? zeroAddress)
16946
+ },
16947
+ quoterAddress: this.resolveQuoterAddress(chain),
16948
+ tokenInForQuote: tokenInForQuote.address
16949
+ };
16950
+ }
16951
+ return null;
16952
+ }
16953
+ resolveQuoterAddress(chain, override) {
16954
+ const address = override ?? this.chainConfigService.getUniswapV4QuoterAddress(chain);
16955
+ if (!address || address === "0x" || address === zeroAddress) {
16956
+ throw new Error(`Uniswap V4 quoter is not configured for chain ${chain}`);
16957
+ }
16958
+ return getAddress(address);
16959
+ }
16960
+ resolveConfiguredPoolTokens(chain, pool) {
16961
+ const first = this.resolveConfiguredPoolToken(chain, pool.tokens[0]);
16962
+ const second = this.resolveConfiguredPoolToken(chain, pool.tokens[1]);
16963
+ return first && second ? [first, second] : null;
16964
+ }
16965
+ resolveConfiguredPoolToken(chain, symbol) {
16966
+ const address = this.chainConfigService.getAssetAddress(chain, symbol);
16967
+ if (!address || address === "0x") return null;
16968
+ return { symbol, address: getAddress(address) };
16969
+ }
16970
+ async quoteExactInput(args) {
16971
+ const amountIn = args.params.amountIn;
16972
+ const swapAmountIn = deductProtocolFee(amountIn, args.protocolFeeBps);
16973
+ const amountOut = await this.readV4QuoteExactInput(args.client, args.poolConfig, swapAmountIn);
16974
+ return {
16975
+ strategy: "uniswap_v4",
16976
+ tradeType: "EXACT_INPUT",
16977
+ amountIn,
16978
+ amountOut,
16979
+ quoteMetadata: {
16980
+ quoteChain: UNISWAP_INTENT_QUOTE_CHAIN,
16981
+ poolKey: args.poolConfig.poolKey,
16982
+ quoterAddress: args.poolConfig.quoterAddress,
16983
+ protocolFeeBps: args.protocolFeeBps
16984
+ }
16985
+ };
16986
+ }
16987
+ async quoteExactOutput(args) {
16988
+ const amountOut = args.params.amountOut;
16989
+ const swapAmountIn = await this.readV4QuoteExactOutput(args.client, args.poolConfig, amountOut);
16990
+ const amountIn = grossUpForProtocolFee(swapAmountIn, args.protocolFeeBps);
16991
+ return {
16992
+ strategy: "uniswap_v4",
16993
+ tradeType: "EXACT_OUTPUT",
16994
+ amountIn,
16995
+ amountOut,
16996
+ quoteMetadata: {
16997
+ quoteChain: UNISWAP_INTENT_QUOTE_CHAIN,
16998
+ poolKey: args.poolConfig.poolKey,
16999
+ quoterAddress: args.poolConfig.quoterAddress,
17000
+ protocolFeeBps: args.protocolFeeBps
17001
+ }
17002
+ };
17003
+ }
17004
+ async readV4QuoteExactInput(client, poolConfig, amountIn) {
17005
+ const data = encodeFunctionData({
17006
+ abi: UNISWAP_V4_QUOTER_ABI,
17007
+ functionName: "quoteExactInputSingle",
17008
+ args: [
17009
+ {
17010
+ poolKey: poolConfig.poolKey,
17011
+ zeroForOne: getZeroForOne(poolConfig.tokenInForQuote, poolConfig.poolKey),
17012
+ exactAmount: amountIn,
17013
+ hookData: "0x"
17014
+ }
17015
+ ]
17016
+ });
17017
+ const response = await client.call({ to: poolConfig.quoterAddress, data });
17018
+ if (!response.data || response.data === "0x") {
17019
+ throw new Error(`Uniswap V4 quoter at ${poolConfig.quoterAddress} returned no data`);
17020
+ }
17021
+ const [amountOut] = decodeFunctionResult({
17022
+ abi: UNISWAP_V4_QUOTER_ABI,
17023
+ functionName: "quoteExactInputSingle",
17024
+ data: response.data
17025
+ });
17026
+ return amountOut;
17027
+ }
17028
+ async readV4QuoteExactOutput(client, poolConfig, amountOut) {
17029
+ const data = encodeFunctionData({
17030
+ abi: UNISWAP_V4_QUOTER_ABI,
17031
+ functionName: "quoteExactOutputSingle",
17032
+ args: [
17033
+ {
17034
+ poolKey: poolConfig.poolKey,
17035
+ zeroForOne: getZeroForOne(poolConfig.tokenInForQuote, poolConfig.poolKey),
17036
+ exactAmount: amountOut,
17037
+ hookData: "0x"
17038
+ }
17039
+ ]
17040
+ });
17041
+ const response = await client.call({ to: poolConfig.quoterAddress, data });
17042
+ if (!response.data || response.data === "0x") {
17043
+ throw new Error(`Uniswap V4 quoter at ${poolConfig.quoterAddress} returned no data`);
17044
+ }
17045
+ const [amountIn] = decodeFunctionResult({
17046
+ abi: UNISWAP_V4_QUOTER_ABI,
17047
+ functionName: "quoteExactOutputSingle",
17048
+ data: response.data
17049
+ });
17050
+ return amountIn;
17051
+ }
17052
+ };
17053
+ function normalizePoolKey(poolKey) {
17054
+ return {
17055
+ currency0: getAddress(poolKey.currency0),
17056
+ currency1: getAddress(poolKey.currency1),
17057
+ fee: poolKey.fee,
17058
+ tickSpacing: poolKey.tickSpacing,
17059
+ hooks: getAddress(poolKey.hooks)
17060
+ };
17061
+ }
17062
+ function sortCurrencies(tokenIn, tokenOut) {
17063
+ const input = getAddress(tokenIn);
17064
+ const output = getAddress(tokenOut);
17065
+ return BigInt(input) < BigInt(output) ? { currency0: input, currency1: output } : { currency0: output, currency1: input };
17066
+ }
17067
+ function matchPoolToken(token, poolTokens) {
17068
+ const tokenAddress = token.address.toLowerCase();
17069
+ const addressMatch = poolTokens.find((poolToken) => poolToken.address.toLowerCase() === tokenAddress);
17070
+ if (addressMatch) return addressMatch;
17071
+ const tokenSymbol = token.symbol?.toUpperCase();
17072
+ if (!tokenSymbol) return null;
17073
+ return poolTokens.find((poolToken) => poolToken.symbol.toUpperCase() === tokenSymbol) ?? null;
17074
+ }
17075
+ function getZeroForOne(tokenIn, poolKey) {
17076
+ return getAddress(tokenIn).toLowerCase() === getAddress(poolKey.currency0).toLowerCase();
17077
+ }
17078
+ function isGatewayParamsTuple(value) {
17079
+ return Array.isArray(value);
17080
+ }
17081
+ function deductProtocolFee(amount, protocolFeeBps) {
17082
+ if (protocolFeeBps <= 0n) return amount;
17083
+ const fee = amount * protocolFeeBps / BPS_DENOMINATOR;
17084
+ return amount - fee;
17085
+ }
17086
+ function grossUpForProtocolFee(netAmount, protocolFeeBps) {
17087
+ if (protocolFeeBps <= 0n) return netAmount;
17088
+ return divCeil(netAmount * BPS_DENOMINATOR, BPS_DENOMINATOR - protocolFeeBps);
17089
+ }
17090
+ function divCeil(numerator, denominator) {
17091
+ return (numerator + denominator - 1n) / denominator;
17092
+ }
17093
+
16734
17094
  // src/protocols/intents/IntentGateway.ts
16735
17095
  var IntentGateway = class _IntentGateway {
16736
17096
  /** EVM chain on which orders are placed and escrowed. */
@@ -16757,6 +17117,8 @@ var IntentGateway = class _IntentGateway {
16757
17117
  bidManager;
16758
17118
  /** Estimates gas costs for filling an order and converts them to fee-token amounts. */
16759
17119
  gasEstimator;
17120
+ /** Quote strategies for pricing orders before placement, keyed by strategy name. */
17121
+ quoteStrategies;
16760
17122
  /**
16761
17123
  * Private constructor — use {@link IntentGateway.create} instead.
16762
17124
  *
@@ -16794,12 +17156,15 @@ var IntentGateway = class _IntentGateway {
16794
17156
  const bidManager = new BidManager(this.ctx, crypto);
16795
17157
  const gasEstimator = new GasEstimator(this.ctx, crypto);
16796
17158
  this.orderPlacer = new OrderPlacer(this.ctx);
16797
- this.orderExecutor = new OrderExecutor(this.ctx, bidManager, crypto);
17159
+ this.orderExecutor = new OrderExecutor(this.ctx, bidManager);
16798
17160
  this.orderCanceller = new OrderCanceller(this.ctx);
16799
17161
  this.orderStatusChecker = new OrderStatusChecker(this.ctx);
16800
17162
  this.bidManager = bidManager;
16801
17163
  this.gasEstimator = gasEstimator;
16802
17164
  this._crypto = crypto;
17165
+ this.quoteStrategies = {
17166
+ uniswap_v4: new UniswapV4IntentQuoteStrategy(dest.configService)
17167
+ };
16803
17168
  }
16804
17169
  /**
16805
17170
  * Creates an initialized IntentGateway instance.
@@ -16844,6 +17209,33 @@ var IntentGateway = class _IntentGateway {
16844
17209
  }
16845
17210
  }
16846
17211
  }
17212
+ /**
17213
+ * Quotes an intent between this gateway's source and destination chains.
17214
+ *
17215
+ * `strategy` defaults to `uniswap_v4`, currently the only supported
17216
+ * strategy. Provide exactly one of `amountIn` or `amountOut`.
17217
+ *
17218
+ * The Uniswap quote strategy always prices against the configured Base
17219
+ * pool, regardless of this gateway's destination chain. Returned
17220
+ * `amountIn`/`amountOut` already account for the gateway's protocol fee
17221
+ * (`quoteMetadata.protocolFeeBps`), which the gateway deducts from order
17222
+ * inputs; apply only your own slippage tolerance before placing the order.
17223
+ *
17224
+ * @param params - Token pair, amount, and optional strategy/pool overrides.
17225
+ * @returns The quoted amounts plus strategy-specific metadata.
17226
+ * @throws {UnsupportedIntentQuoteStrategyError} For unknown strategies.
17227
+ * @throws {UnsupportedIntentQuotePairError} When no pool is configured for the pair.
17228
+ */
17229
+ async quoteIntent(params) {
17230
+ const strategy = params.strategy ?? "uniswap_v4";
17231
+ const handler = this.quoteStrategies[strategy];
17232
+ if (!handler) throw new UnsupportedIntentQuoteStrategyError(strategy);
17233
+ return handler.quote(
17234
+ { ...params, strategy },
17235
+ { stateMachineId: this.source.config.stateMachineId, client: this.source.client },
17236
+ { stateMachineId: this.dest.config.stateMachineId, client: this.dest.client }
17237
+ );
17238
+ }
16847
17239
  /**
16848
17240
  * Bidirectional async generator that orchestrates the full order lifecycle:
16849
17241
  * placement, fee estimation, bid collection, and execution.
@@ -16898,17 +17290,38 @@ var IntentGateway = class _IntentGateway {
16898
17290
  }
16899
17291
  const { order: finalizedOrder, receipt: placementReceipt } = placeOrderSecond.value;
16900
17292
  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
- }
17293
+ yield* this.driveExecution(
17294
+ this.orderExecutor.executeOrder({
17295
+ order: finalizedOrder,
17296
+ sessionPrivateKey,
17297
+ auctionTimeMs: options.auctionTimeMs,
17298
+ pollIntervalMs: options.pollIntervalMs,
17299
+ solver: options.solver
17300
+ })
17301
+ );
16910
17302
  return;
16911
17303
  }
17304
+ /**
17305
+ * Forwards updates from the executor's bidirectional generator to the caller,
17306
+ * threading the {@link SelectBidResult} the caller feeds back after a
17307
+ * `BIDS_RECEIVED` yield into the executor's `.next()`. Other yields expect no
17308
+ * feedback. This is what lets the consumer own `bid.execute()` while the
17309
+ * executor keeps tracking fills and continuing the auction.
17310
+ */
17311
+ async *driveExecution(execGen) {
17312
+ try {
17313
+ let input;
17314
+ while (true) {
17315
+ const { value, done } = await execGen.next(input);
17316
+ input = void 0;
17317
+ if (done) break;
17318
+ const fed = yield value;
17319
+ if (value.status === "BIDS_RECEIVED") input = fed;
17320
+ }
17321
+ } finally {
17322
+ await execGen.return();
17323
+ }
17324
+ }
16912
17325
  /**
16913
17326
  * Validates that an order has the minimum fields required for post-placement
16914
17327
  * resume (i.e. it was previously placed and has an on-chain identity).
@@ -16945,14 +17358,99 @@ var IntentGateway = class _IntentGateway {
16945
17358
  */
16946
17359
  async *resume(order, options) {
16947
17360
  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;
17361
+ yield* this.driveExecution(
17362
+ this.orderExecutor.executeOrder({
17363
+ order,
17364
+ sessionPrivateKey: options.sessionPrivateKey,
17365
+ auctionTimeMs: options.auctionTimeMs,
17366
+ pollIntervalMs: options.pollIntervalMs,
17367
+ solver: options.solver
17368
+ })
17369
+ );
17370
+ }
17371
+ /**
17372
+ * Batteries-included variant of {@link execute}: places the order and then
17373
+ * auto-selects the best bid each round via {@link selectAndExecuteBest}, with
17374
+ * no bid-selection input from the caller.
17375
+ *
17376
+ * The caller still signs the placement transaction: this generator yields
17377
+ * `AWAITING_PLACE_ORDER` and the caller must hand the signed tx back via
17378
+ * `gen.next(signedTx)` exactly as with {@link execute}. Every other stage
17379
+ * (`BIDS_RECEIVED`, `BID_SELECTED`, `FILLED`, …) is handled automatically and
17380
+ * surfaced for observation, so the rest of the loop needs no feedback.
17381
+ *
17382
+ * @param order - The order to place and execute.
17383
+ * @param graffiti - Optional orderflow-attribution tag.
17384
+ * @param options - Same tuning parameters as {@link execute}.
17385
+ * @yields {@link IntentOrderStatusUpdate} at each lifecycle stage.
17386
+ */
17387
+ async *executeBest(order, graffiti = DEFAULT_GRAFFITI, options) {
17388
+ const gen = this.execute(order, graffiti, options);
17389
+ try {
17390
+ let input;
17391
+ while (true) {
17392
+ const { value, done } = await gen.next(input);
17393
+ input = void 0;
17394
+ if (done) break;
17395
+ if (value.status === "BIDS_RECEIVED") {
17396
+ yield value;
17397
+ input = await this.autoSelect(order, value.bids);
17398
+ } else if (value.status === "AWAITING_PLACE_ORDER") {
17399
+ input = yield value;
17400
+ } else {
17401
+ yield value;
17402
+ }
17403
+ }
17404
+ } finally {
17405
+ await gen.return();
17406
+ }
17407
+ }
17408
+ /**
17409
+ * Batteries-included variant of {@link resume}: auto-selects the best bid each
17410
+ * round via {@link selectAndExecuteBest}, with no bid-selection input from the
17411
+ * caller. A plain `for await` loop is sufficient — there is no placement step.
17412
+ *
17413
+ * @param order - A previously placed order with a valid `id` and `session`.
17414
+ * @param options - Optional tuning parameters for bid collection and execution.
17415
+ * @yields {@link IntentOrderStatusUpdate} at each execution stage.
17416
+ */
17417
+ async *resumeBest(order, options) {
17418
+ const gen = this.resume(order, options);
17419
+ try {
17420
+ let input;
17421
+ while (true) {
17422
+ const { value, done } = await gen.next(input);
17423
+ input = void 0;
17424
+ if (done) break;
17425
+ yield value;
17426
+ if (value.status === "BIDS_RECEIVED") {
17427
+ input = await this.autoSelect(order, value.bids);
17428
+ }
17429
+ }
17430
+ } finally {
17431
+ await gen.return();
17432
+ }
17433
+ }
17434
+ /**
17435
+ * Auto-select wrapper used by {@link executeBest} / {@link resumeBest}.
17436
+ *
17437
+ * Runs {@link selectAndExecuteBest} and returns the {@link SelectBidResult} to
17438
+ * feed back to the executor. If selection fails this round — all bids fail
17439
+ * simulation, no valid bids, or the bundler rejects the UserOp — it swallows
17440
+ * the error and returns `undefined`, which tells the executor to keep polling
17441
+ * for fresh bids until the deadline rather than aborting the order. Swallowing
17442
+ * the error here (rather than letting it propagate) also keeps the executor's
17443
+ * `finally` teardown intact, since nothing throws across the suspended
17444
+ * generators.
17445
+ */
17446
+ async autoSelect(order, bids) {
17447
+ try {
17448
+ return await this.selectAndExecuteBest(order, bids);
17449
+ } catch (err) {
17450
+ console.warn(
17451
+ `[IntentGateway] autoSelect: bid selection failed this round, continuing to poll: ${err instanceof Error ? err.message : String(err)}`
17452
+ );
17453
+ return void 0;
16956
17454
  }
16957
17455
  }
16958
17456
  /**
@@ -17008,10 +17506,52 @@ var IntentGateway = class _IntentGateway {
17008
17506
  return this.bidManager.prepareSubmitBid(options);
17009
17507
  }
17010
17508
  /**
17011
- * Selects the best available bid, simulates it, and submits the UserOperation
17012
- * to the bundler.
17509
+ * Decodes raw filler bids into first-class {@link Bid} objects that can be
17510
+ * ranked, simulated, and executed by the consumer.
17511
+ *
17512
+ * Delegates to {@link BidManager.buildBids}.
17513
+ *
17514
+ * @param order - The placed order the bids are competing to fill.
17515
+ * @param bids - Raw filler bids fetched from the coprocessor.
17516
+ * @param sessionPrivateKey - Optional session key override; looked up from
17517
+ * storage by `order.session` if omitted.
17518
+ * @returns Array of executable {@link Bid} objects.
17519
+ */
17520
+ buildBids(order, bids, sessionPrivateKey) {
17521
+ return this.bidManager.buildBids(order, bids, sessionPrivateKey);
17522
+ }
17523
+ /**
17524
+ * Sorts bids by output value using the same strategy the autopilot uses.
17525
+ *
17526
+ * Delegates to {@link BidManager.sortBids}.
17527
+ *
17528
+ * @param order - The placed order whose output spec drives sorting.
17529
+ * @param bids - Bids to sort (from {@link buildBids}).
17530
+ * @returns Sorted array of {@link Bid} objects.
17531
+ */
17532
+ async sortBids(order, bids) {
17533
+ return this.bidManager.sortBids(order, bids);
17534
+ }
17535
+ /**
17536
+ * Autopilot bid selection: sorts the given bids, simulates each until one
17537
+ * passes, then executes it.
17538
+ *
17539
+ * Delegates to {@link BidManager.selectAndExecuteBest}.
17540
+ *
17541
+ * @param order - The placed order to fill.
17542
+ * @param bids - Candidate bids (from {@link buildBids}).
17543
+ * @returns A {@link SelectBidResult} with the submitted UserOperation, hashes,
17544
+ * and fill status.
17545
+ */
17546
+ async selectAndExecuteBest(order, bids) {
17547
+ return this.bidManager.selectAndExecuteBest(order, bids);
17548
+ }
17549
+ /**
17550
+ * Decodes, sorts, simulates, signs, and submits the best of the given raw
17551
+ * filler bids with no per-bid input from the caller.
17013
17552
  *
17014
- * Delegates to {@link BidManager.selectBid}.
17553
+ * Delegates to {@link BidManager.selectBid}. Prefer {@link buildBids} +
17554
+ * {@link selectAndExecuteBest} (or {@link executeBest}) for new code.
17015
17555
  *
17016
17556
  * @param order - The placed order to fill.
17017
17557
  * @param bids - Raw filler bids fetched from the coprocessor.
@@ -17931,7 +18471,7 @@ var HyperFungibleTokenABI = [
17931
18471
  internalType: "uint256"
17932
18472
  }
17933
18473
  ],
17934
- stateMutability: "view"
18474
+ stateMutability: "nonpayable"
17935
18475
  },
17936
18476
  {
17937
18477
  type: "function",
@@ -17982,7 +18522,7 @@ var HyperFungibleTokenABI = [
17982
18522
  internalType: "uint256"
17983
18523
  }
17984
18524
  ],
17985
- stateMutability: "view"
18525
+ stateMutability: "nonpayable"
17986
18526
  },
17987
18527
  {
17988
18528
  type: "function",
@@ -18033,7 +18573,7 @@ var HyperFungibleTokenABI = [
18033
18573
  internalType: "uint256"
18034
18574
  }
18035
18575
  ],
18036
- stateMutability: "view"
18576
+ stateMutability: "nonpayable"
18037
18577
  },
18038
18578
  {
18039
18579
  type: "function",
@@ -19052,7 +19592,7 @@ var WrappedHyperFungibleTokenABI = [
19052
19592
  internalType: "uint256"
19053
19593
  }
19054
19594
  ],
19055
- stateMutability: "view"
19595
+ stateMutability: "nonpayable"
19056
19596
  },
19057
19597
  {
19058
19598
  type: "function",
@@ -19103,7 +19643,7 @@ var WrappedHyperFungibleTokenABI = [
19103
19643
  internalType: "uint256"
19104
19644
  }
19105
19645
  ],
19106
- stateMutability: "view"
19646
+ stateMutability: "nonpayable"
19107
19647
  },
19108
19648
  {
19109
19649
  type: "function",
@@ -19154,7 +19694,7 @@ var WrappedHyperFungibleTokenABI = [
19154
19694
  internalType: "uint256"
19155
19695
  }
19156
19696
  ],
19157
- stateMutability: "view"
19697
+ stateMutability: "nonpayable"
19158
19698
  },
19159
19699
  {
19160
19700
  type: "function",
@@ -19696,13 +20236,13 @@ var HyperFungibleToken = class {
19696
20236
  };
19697
20237
  let totalNativeCost = 0n;
19698
20238
  try {
19699
- totalNativeCost = await this.source.client.readContract({
20239
+ const { result } = await this.source.client.simulateContract({
19700
20240
  address: params.token,
19701
20241
  abi: HyperFungibleTokenABI,
19702
20242
  functionName: "quote",
19703
20243
  args: [sendParams]
19704
20244
  });
19705
- totalNativeCost = totalNativeCost * 101n / 100n;
20245
+ totalNativeCost = result * 101n / 100n;
19706
20246
  } catch {
19707
20247
  }
19708
20248
  return {
@@ -21610,6 +22150,6 @@ async function teleportDot(param_) {
21610
22150
  return stream;
21611
22151
  }
21612
22152
 
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 };
22153
+ 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
22154
  //# sourceMappingURL=index.js.map
21615
22155
  //# sourceMappingURL=index.js.map