@hyperbridge/sdk 2.3.2 → 2.4.0

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.
@@ -5293,6 +5293,57 @@ declare class CryptoUtils {
5293
5293
  * @returns The UserOperation hash as a hex string.
5294
5294
  */
5295
5295
  static computeUserOpHash(userOp: PackedUserOperation, entryPoint: Hex, chainId: bigint): Hex;
5296
+ /**
5297
+ * Derives the ERC-4337 nonce key that binds a bid UserOperation to its
5298
+ * order and session key: the lower 192 bits of
5299
+ * `keccak256(commitment ‖ sessionKey)`. `SolverAccount` rejects bid
5300
+ * operations whose nonce key differs — this is what lets the solver sign
5301
+ * the plain userOpHash while staying committed to the order and to the
5302
+ * session key it bid against.
5303
+ *
5304
+ * @param commitment - The order commitment (`order.id`).
5305
+ * @param sessionKey - The order's session key address (`order.session`).
5306
+ * @returns The 192-bit nonce key as a bigint (pass to `EntryPoint.getNonce`).
5307
+ */
5308
+ static bidNonceKey(commitment: HexString, sessionKey: HexString): bigint;
5309
+ /**
5310
+ * Builds the EIP-712 typed-data payload whose digest is the EntryPoint v0.8
5311
+ * `userOpHash` (i.e. `hashTypedData(packedUserOpTypedData(...)) ===
5312
+ * computeUserOpHash(...)`). Signing this typed data is bit-identical to
5313
+ * signing the raw userOpHash, but keeps the full operation visible to
5314
+ * signing infrastructure (hardware wallets, MPC/TEE policy engines) instead
5315
+ * of an opaque 32-byte digest.
5316
+ *
5317
+ * @param userOp - The packed UserOperation to sign (signature field ignored).
5318
+ * @param entryPoint - Address of the EntryPoint v0.8 contract.
5319
+ * @param chainId - Chain ID of the network on which the operation will execute.
5320
+ * @returns A viem `TypedDataDefinition` for the operation.
5321
+ */
5322
+ static packedUserOpTypedData(userOp: PackedUserOperation, entryPoint: Hex, chainId: bigint): {
5323
+ domain: {
5324
+ name: string;
5325
+ version: string;
5326
+ chainId: bigint;
5327
+ verifyingContract: `0x${string}`;
5328
+ };
5329
+ types: {
5330
+ PackedUserOperation: {
5331
+ name: string;
5332
+ type: string;
5333
+ }[];
5334
+ };
5335
+ primaryType: "PackedUserOperation";
5336
+ message: {
5337
+ sender: `0x${string}`;
5338
+ nonce: bigint;
5339
+ initCode: `0x${string}`;
5340
+ callData: `0x${string}`;
5341
+ accountGasLimits: `0x${string}`;
5342
+ preVerificationGas: bigint;
5343
+ gasFees: `0x${string}`;
5344
+ paymasterAndData: `0x${string}`;
5345
+ };
5346
+ };
5296
5347
  /**
5297
5348
  * Computes the EIP-712 struct hash of a `PackedUserOperation`.
5298
5349
  *
@@ -2635,7 +2635,7 @@ var chainConfigs = {
2635
2635
  UniswapV3Quoter: "0x0000000000000000000000000000000000000000",
2636
2636
  UniswapV4Quoter: "0x0000000000000000000000000000000000000000",
2637
2637
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
2638
- SolverAccount: "0x07FeC66d967800998060194EaECDd7C66dA4a1B1"
2638
+ SolverAccount: "0x110C7E1814c923127469Ca8939a12dAa70B96a17"
2639
2639
  },
2640
2640
  rpcEnvKey: "BSC_CHAPEL",
2641
2641
  defaultRpcUrl: "https://bnb-testnet.api.onfinality.io/public",
@@ -2743,7 +2743,7 @@ var chainConfigs = {
2743
2743
  },
2744
2744
  addresses: {
2745
2745
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2746
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2746
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
2747
2747
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2748
2748
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2749
2749
  UniswapRouter02: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
@@ -2798,7 +2798,7 @@ var chainConfigs = {
2798
2798
  },
2799
2799
  addresses: {
2800
2800
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2801
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2801
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
2802
2802
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2803
2803
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2804
2804
  UniswapRouter02: "0x10ED43C718714eb63d5aA57B78B54704E256024E",
@@ -2854,7 +2854,7 @@ var chainConfigs = {
2854
2854
  },
2855
2855
  addresses: {
2856
2856
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2857
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2857
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
2858
2858
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2859
2859
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2860
2860
  UniswapRouter02: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
@@ -2911,7 +2911,7 @@ var chainConfigs = {
2911
2911
  },
2912
2912
  addresses: {
2913
2913
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2914
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2914
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
2915
2915
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2916
2916
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2917
2917
  UniswapRouter02: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
@@ -2970,7 +2970,7 @@ var chainConfigs = {
2970
2970
  },
2971
2971
  addresses: {
2972
2972
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2973
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2973
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
2974
2974
  TokenGateway: "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E",
2975
2975
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2976
2976
  UniswapRouter02: "0xd2f9496824951D5237cC71245D659E48d0d5f9E8",
@@ -3057,7 +3057,7 @@ var chainConfigs = {
3057
3057
  Calldispatcher: "0x876F1891982E260026630c233A4897160A281Fb8",
3058
3058
  Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
3059
3059
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
3060
- SolverAccount: "0x07FeC66d967800998060194EaECDd7C66dA4a1B1"
3060
+ SolverAccount: "0x110C7E1814c923127469Ca8939a12dAa70B96a17"
3061
3061
  },
3062
3062
  rpcEnvKey: "POLYGON_AMOY",
3063
3063
  defaultRpcUrl: "https://rpc-amoy.polygon.technology",
@@ -3081,7 +3081,7 @@ var chainConfigs = {
3081
3081
  },
3082
3082
  addresses: {
3083
3083
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
3084
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
3084
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
3085
3085
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
3086
3086
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
3087
3087
  UniswapRouter02: "0x4A7b5Da61326A6379179b40d00F57E5bbDC962c2",
@@ -3116,7 +3116,7 @@ var chainConfigs = {
3116
3116
  },
3117
3117
  addresses: {
3118
3118
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
3119
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
3119
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
3120
3120
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
3121
3121
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
3122
3122
  UniswapRouter02: "0xB2e26652e4BAd1e56055A051f922E06760cA0BFE",
@@ -3271,7 +3271,7 @@ var chainConfigs = {
3271
3271
  },
3272
3272
  addresses: {
3273
3273
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
3274
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
3274
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
3275
3275
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
3276
3276
  Calldispatcher: "0xE2C7e576E26E0bE7aC97c6fE925bcDAbD87c4bEd"
3277
3277
  },
@@ -7083,6 +7083,11 @@ var ExpectedError = class _ExpectedError extends Error {
7083
7083
  return error instanceof _ExpectedError;
7084
7084
  }
7085
7085
  };
7086
+
7087
+ // src/configs/constants.ts
7088
+ var ISMP_PREFIX = ":child_storage:default:ISMPv2";
7089
+
7090
+ // src/chains/substrate.ts
7086
7091
  var HttpRpcClient = class {
7087
7092
  constructor(url) {
7088
7093
  this.url = url;
@@ -7206,7 +7211,7 @@ var SubstrateChain = class _SubstrateChain {
7206
7211
  * @returns {Promise<HexString | undefined>} The commitment data if found, undefined otherwise.
7207
7212
  */
7208
7213
  async queryRequestCommitment(commitment) {
7209
- const prefix = toHex(":child_storage:default:ISMP");
7214
+ const prefix = toHex(ISMP_PREFIX);
7210
7215
  const key = this.requestCommitmentKey(commitment);
7211
7216
  const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7212
7217
  return item;
@@ -7217,7 +7222,7 @@ var SubstrateChain = class _SubstrateChain {
7217
7222
  * @returns {Promise<HexString | undefined>} The relayer address responsible for delivering the request.
7218
7223
  */
7219
7224
  async queryRequestReceipt(commitment) {
7220
- const prefix = toHex(":child_storage:default:ISMP");
7225
+ const prefix = toHex(ISMP_PREFIX);
7221
7226
  const key = this.requestReceiptKey(commitment);
7222
7227
  const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7223
7228
  return item;
@@ -7241,7 +7246,7 @@ var SubstrateChain = class _SubstrateChain {
7241
7246
  * @returns {Promise<HexString | undefined>} The receipt data if present, otherwise undefined.
7242
7247
  */
7243
7248
  async queryResponseReceipt(commitment) {
7244
- const prefix = toHex(":child_storage:default:ISMP");
7249
+ const prefix = toHex(ISMP_PREFIX);
7245
7250
  const key = this.responseReceiptKey(commitment);
7246
7251
  const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7247
7252
  return item;
@@ -14818,6 +14823,67 @@ var CryptoUtils = class _CryptoUtils {
14818
14823
  encodePacked(["bytes1", "bytes1", "bytes32", "bytes32"], ["0x19", "0x01", domainSeparator, structHash])
14819
14824
  );
14820
14825
  }
14826
+ /**
14827
+ * Derives the ERC-4337 nonce key that binds a bid UserOperation to its
14828
+ * order and session key: the lower 192 bits of
14829
+ * `keccak256(commitment ‖ sessionKey)`. `SolverAccount` rejects bid
14830
+ * operations whose nonce key differs — this is what lets the solver sign
14831
+ * the plain userOpHash while staying committed to the order and to the
14832
+ * session key it bid against.
14833
+ *
14834
+ * @param commitment - The order commitment (`order.id`).
14835
+ * @param sessionKey - The order's session key address (`order.session`).
14836
+ * @returns The 192-bit nonce key as a bigint (pass to `EntryPoint.getNonce`).
14837
+ */
14838
+ static bidNonceKey(commitment, sessionKey) {
14839
+ return BigInt(keccak256(encodePacked(["bytes32", "address"], [commitment, sessionKey]))) & (1n << 192n) - 1n;
14840
+ }
14841
+ /**
14842
+ * Builds the EIP-712 typed-data payload whose digest is the EntryPoint v0.8
14843
+ * `userOpHash` (i.e. `hashTypedData(packedUserOpTypedData(...)) ===
14844
+ * computeUserOpHash(...)`). Signing this typed data is bit-identical to
14845
+ * signing the raw userOpHash, but keeps the full operation visible to
14846
+ * signing infrastructure (hardware wallets, MPC/TEE policy engines) instead
14847
+ * of an opaque 32-byte digest.
14848
+ *
14849
+ * @param userOp - The packed UserOperation to sign (signature field ignored).
14850
+ * @param entryPoint - Address of the EntryPoint v0.8 contract.
14851
+ * @param chainId - Chain ID of the network on which the operation will execute.
14852
+ * @returns A viem `TypedDataDefinition` for the operation.
14853
+ */
14854
+ static packedUserOpTypedData(userOp, entryPoint, chainId) {
14855
+ return {
14856
+ domain: {
14857
+ name: "ERC4337",
14858
+ version: "1",
14859
+ chainId,
14860
+ verifyingContract: entryPoint
14861
+ },
14862
+ types: {
14863
+ PackedUserOperation: [
14864
+ { name: "sender", type: "address" },
14865
+ { name: "nonce", type: "uint256" },
14866
+ { name: "initCode", type: "bytes" },
14867
+ { name: "callData", type: "bytes" },
14868
+ { name: "accountGasLimits", type: "bytes32" },
14869
+ { name: "preVerificationGas", type: "uint256" },
14870
+ { name: "gasFees", type: "bytes32" },
14871
+ { name: "paymasterAndData", type: "bytes" }
14872
+ ]
14873
+ },
14874
+ primaryType: "PackedUserOperation",
14875
+ message: {
14876
+ sender: userOp.sender,
14877
+ nonce: userOp.nonce,
14878
+ initCode: userOp.initCode,
14879
+ callData: userOp.callData,
14880
+ accountGasLimits: userOp.accountGasLimits,
14881
+ preVerificationGas: userOp.preVerificationGas,
14882
+ gasFees: userOp.gasFees,
14883
+ paymasterAndData: userOp.paymasterAndData
14884
+ }
14885
+ };
14886
+ }
14821
14887
  /**
14822
14888
  * Computes the EIP-712 struct hash of a `PackedUserOperation`.
14823
14889
  *
@@ -15359,7 +15425,11 @@ var OrderExecutor = class {
15359
15425
  */
15360
15426
  async fetchBids(params) {
15361
15427
  const { commitment, solver, solverLockStartTime } = params;
15362
- const fetchedBids = await this.ctx.intentsCoprocessor.getBidsForOrder(commitment);
15428
+ const intentsCoprocessor = this.ctx.intentsCoprocessor;
15429
+ if (!intentsCoprocessor) {
15430
+ throw new Error("IntentsCoprocessor required for order execution");
15431
+ }
15432
+ const fetchedBids = await intentsCoprocessor.getBidsForOrder(commitment);
15363
15433
  if (solver) {
15364
15434
  const { address, timeoutMs } = solver;
15365
15435
  const solverLockActive = Date.now() - solverLockStartTime < timeoutMs;
@@ -15448,7 +15518,7 @@ var OrderExecutor = class {
15448
15518
  * → (`FILLED` | `PARTIAL_FILL`)* → (`FILLED` | `EXPIRED`)
15449
15519
  *
15450
15520
  * **Cross-chain:** `AWAITING_BIDS` → `BIDS_RECEIVED` → `BID_SELECTED`
15451
- * (terminates — settlement is confirmed async via Hyperbridge)
15521
+ * `FILLED`
15452
15522
  */
15453
15523
  async *executeOrder(options) {
15454
15524
  const { order, sessionPrivateKey, auctionTimeMs, pollIntervalMs = DEFAULT_POLL_INTERVAL, solver } = options;
@@ -15587,7 +15657,13 @@ var OrderExecutor = class {
15587
15657
  userOp: result.userOp,
15588
15658
  transactionHash: result.txnHash
15589
15659
  };
15590
- const fill = this.processFillResult(result, commitment, targetAssets, totalFilledAssets, remainingAssets);
15660
+ const fill = this.processFillResult(
15661
+ result,
15662
+ commitment,
15663
+ targetAssets,
15664
+ totalFilledAssets,
15665
+ remainingAssets
15666
+ );
15591
15667
  totalFilledAssets = fill.totalFilledAssets;
15592
15668
  remainingAssets = fill.remainingAssets;
15593
15669
  if (fill.update) {
@@ -15613,6 +15689,10 @@ var OrderCanceller = class {
15613
15689
  this.ctx = ctx;
15614
15690
  }
15615
15691
  ctx;
15692
+ logger = createConsola({
15693
+ level: LogLevels.info,
15694
+ formatOptions: { columns: 80, colors: true, compact: true, date: false }
15695
+ }).withTag("[OrderCanceller]");
15616
15696
  /**
15617
15697
  * Returns both the native token cost and the relayer fee for cancelling an
15618
15698
  * order. Frontends can use `relayerFee` to approve the ERC-20 spend before
@@ -16028,32 +16108,55 @@ var OrderCanceller = class {
16028
16108
  }
16029
16109
  /**
16030
16110
  * Submits an unsigned GET request message to Hyperbridge and waits until
16031
- * the request receipt is confirmed on-chain.
16111
+ * the GET response receipt is confirmed on-chain.
16032
16112
  *
16033
- * If the initial submission fails, the method waits 30 seconds and then
16034
- * retries querying for the receipt up to 10 times with 5-second back-off.
16113
+ * GET handling on Hyperbridge creates a response receipt keyed by the
16114
+ * request commitment. That receipt is the durable delivery signal, so a
16115
+ * duplicate unsigned submission is considered successful only if the
16116
+ * response receipt can be observed.
16035
16117
  *
16036
16118
  * @param hyperbridge - Hyperbridge Substrate chain client.
16037
16119
  * @param commitment - The GET request commitment hash used to poll for the receipt.
16038
16120
  * @param message - The fully constructed GET request message to submit.
16039
16121
  */
16040
16122
  async submitAndConfirmReceipt(hyperbridge, commitment, message) {
16041
- let storageValue = await hyperbridge.queryRequestReceipt(commitment);
16042
- if (!storageValue) {
16043
- try {
16044
- await hyperbridge.submitUnsigned(message);
16045
- } catch {
16046
- }
16123
+ this.logger.info(`Checking GET response receipt before Hyperbridge delivery (${commitment})`);
16124
+ if (await this.queryDeliveredReceipt(hyperbridge, commitment)) {
16125
+ this.logger.info(`GET ${commitment} already delivered to Hyperbridge; skipping unsigned submission`);
16126
+ return;
16127
+ }
16128
+ try {
16129
+ this.logger.info(`Submitting unsigned GET ${commitment} to Hyperbridge`);
16130
+ await hyperbridge.submitUnsigned(message);
16131
+ this.logger.info(`Unsigned GET ${commitment} submitted; waiting for Hyperbridge response receipt`);
16047
16132
  await sleep(3e4);
16048
- storageValue = await retryPromise(
16049
- async () => {
16050
- const value = await hyperbridge.queryRequestReceipt(commitment);
16051
- if (!value) throw new Error("Receipt not found");
16052
- return value;
16053
- },
16054
- { maxRetries: 10, backoffMs: 5e3, logMessage: "Checking for receipt" }
16133
+ } catch (error) {
16134
+ this.logger.warn(
16135
+ `Unsigned GET submit failed for ${commitment}; polling response receipt before failing: ${String(error)}`
16055
16136
  );
16056
16137
  }
16138
+ try {
16139
+ await this.pollDeliveredReceipt(hyperbridge, commitment);
16140
+ this.logger.info(`Confirmed Hyperbridge GET delivery for ${commitment}`);
16141
+ } catch (error) {
16142
+ const message2 = `Failed to deliver GET request to Hyperbridge; no response receipt found for ${commitment}: ${String(error)}`;
16143
+ this.logger.error(message2);
16144
+ throw new Error(message2);
16145
+ }
16146
+ }
16147
+ async queryDeliveredReceipt(hyperbridge, commitment) {
16148
+ return hyperbridge.queryResponseReceipt(commitment);
16149
+ }
16150
+ async pollDeliveredReceipt(hyperbridge, commitment) {
16151
+ this.logger.info(`Polling Hyperbridge GET response receipt for ${commitment}`);
16152
+ return retryPromise(
16153
+ async () => {
16154
+ const value = await this.queryDeliveredReceipt(hyperbridge, commitment);
16155
+ if (!value) throw new Error(`GET response receipt not found for ${commitment}`);
16156
+ return value;
16157
+ },
16158
+ { maxRetries: 10, backoffMs: 5e3, logMessage: `Checking GET response receipt ${commitment}` }
16159
+ );
16057
16160
  }
16058
16161
  /**
16059
16162
  * Estimates the relayer fee for delivering a POST from dest to source.
@@ -16124,7 +16227,7 @@ var BidImpl = class {
16124
16227
  const sessionKeyAddress = this.order.session;
16125
16228
  const sessionKeyData = this.sessionPrivateKey ? { privateKey: this.sessionPrivateKey } : await this.ctx.sessionKeyStorage.getSessionKeyByAddress(sessionKeyAddress);
16126
16229
  if (!sessionKeyData) {
16127
- throw new Error("SessionKey not found for commitment: " + commitment);
16230
+ throw new Error(`SessionKey not found for commitment: ${commitment}`);
16128
16231
  }
16129
16232
  const signature = await CryptoUtils.signSolverSelection(
16130
16233
  commitment,
@@ -16184,8 +16287,8 @@ var BidImpl = class {
16184
16287
  /**
16185
16288
  * Signs the `SelectSolver` message with the session key, appends it to the
16186
16289
  * solver's existing UserOp signature, and submits the UserOperation to the
16187
- * bundler. For same-chain orders, waits for the receipt and reads
16188
- * `OrderFilled` / `PartialFill` logs to determine fill status.
16290
+ * bundler. Waits for the receipt and reads `OrderFilled` / `PartialFill`
16291
+ * logs to determine fill status.
16189
16292
  *
16190
16293
  * @returns A {@link SelectBidResult} with the submitted UserOperation, its hash,
16191
16294
  * the solver address, transaction hash, and fill status.
@@ -16225,33 +16328,31 @@ var BidImpl = class {
16225
16328
  { maxRetries: 5, backoffMs: 2e3, logMessage: "Fetching user operation receipt" }
16226
16329
  );
16227
16330
  txnHash = receipt.receipt.transactionHash;
16228
- if (this.order.source === this.order.destination) {
16229
- try {
16230
- const chainReceipt = await this.ctx.dest.client.waitForTransactionReceipt({
16231
- hash: txnHash,
16232
- confirmations: 1
16233
- });
16234
- const events = parseEventLogs({
16235
- abi: ABI3,
16236
- logs: chainReceipt.logs,
16237
- eventName: ["OrderFilled", "PartialFill"]
16238
- });
16239
- const matched = events.find((e) => {
16240
- if (e.eventName === "OrderFilled")
16241
- return e.args.commitment.toLowerCase() === commitment.toLowerCase();
16242
- if (e.eventName === "PartialFill")
16243
- return e.args.commitment.toLowerCase() === commitment.toLowerCase();
16244
- return false;
16245
- });
16246
- if (matched?.eventName === "OrderFilled") {
16247
- fillStatus = "full";
16248
- } else if (matched?.eventName === "PartialFill") {
16249
- fillStatus = "partial";
16250
- filledAssets = matched.args.outputs ?? [];
16251
- }
16252
- } catch {
16253
- throw new Error("Failed to determine fill status from logs");
16331
+ try {
16332
+ const chainReceipt = await this.ctx.dest.client.waitForTransactionReceipt({
16333
+ hash: txnHash,
16334
+ confirmations: 1
16335
+ });
16336
+ const events = parseEventLogs({
16337
+ abi: ABI3,
16338
+ logs: chainReceipt.logs,
16339
+ eventName: ["OrderFilled", "PartialFill"]
16340
+ });
16341
+ const matched = events.find((e) => {
16342
+ if (e.eventName === "OrderFilled")
16343
+ return e.args.commitment.toLowerCase() === commitment.toLowerCase();
16344
+ if (e.eventName === "PartialFill")
16345
+ return e.args.commitment.toLowerCase() === commitment.toLowerCase();
16346
+ return false;
16347
+ });
16348
+ if (matched?.eventName === "OrderFilled") {
16349
+ fillStatus = "full";
16350
+ } else if (matched?.eventName === "PartialFill") {
16351
+ fillStatus = "partial";
16352
+ filledAssets = matched.args.outputs ?? [];
16254
16353
  }
16354
+ } catch {
16355
+ throw new Error("Failed to determine fill status from logs");
16255
16356
  }
16256
16357
  } catch (err) {
16257
16358
  throw new Error(`Failed to execute bid: ${err instanceof Error ? err.message : String(err)}`);
@@ -16291,9 +16392,12 @@ var BidManager = class {
16291
16392
  * Constructs a signed `PackedUserOperation` that a solver can submit to the
16292
16393
  * Hyperbridge coprocessor as a bid to fill an order.
16293
16394
  *
16294
- * The solver's signature covers a hash that binds the UserOperation to the
16295
- * order commitment and the session key address, so the IntentGatewayV2
16296
- * contract can verify the solver's intent on-chain.
16395
+ * The solver signs the operation as EntryPoint v0.8 EIP-712 typed data,
16396
+ * whose digest is the plain userOpHash. The binding to the order lives in
16397
+ * the operation itself: the 4337 nonce key must be the lower 192 bits of
16398
+ * the order commitment (`SolverAccount` enforces this during validation),
16399
+ * and the callData carries the order. This keeps the signed payload fully
16400
+ * transparent to signing infrastructure instead of an opaque digest.
16297
16401
  *
16298
16402
  * @param options - Parameters describing the solver account, gas limits, fee
16299
16403
  * market values, and pre-built `callData` for the fill operation.
@@ -16331,10 +16435,17 @@ var BidManager = class {
16331
16435
  paymasterAndData,
16332
16436
  signature: "0x"
16333
16437
  };
16334
- const userOpHash = CryptoUtils.computeUserOpHash(userOp, entryPointAddress, chainId);
16335
- const sessionKey = order.session;
16336
- const messageHash = keccak256(concat([userOpHash, order.id, sessionKey]));
16337
- const solverSignature = await solverSigner.signMessage(messageHash, Number(chainId));
16438
+ const nonceKey = BigInt(nonce) >> 64n;
16439
+ const expectedKey = CryptoUtils.bidNonceKey(order.id, order.session);
16440
+ if (nonceKey !== expectedKey) {
16441
+ console.warn(
16442
+ `[BidManager] bid nonce key does not bind the order commitment and session key; on-chain validation will fail (order=${order.id})`
16443
+ );
16444
+ }
16445
+ const solverSignature = await solverSigner.signTypedData(
16446
+ CryptoUtils.packedUserOpTypedData(userOp, entryPointAddress, chainId),
16447
+ Number(chainId)
16448
+ );
16338
16449
  const signature = concat([order.id, solverSignature]);
16339
16450
  return { ...userOp, signature };
16340
16451
  }