@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.
@@ -2596,7 +2596,7 @@ var chainConfigs = {
2596
2596
  UniswapV3Quoter: "0x0000000000000000000000000000000000000000",
2597
2597
  UniswapV4Quoter: "0x0000000000000000000000000000000000000000",
2598
2598
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
2599
- SolverAccount: "0x07FeC66d967800998060194EaECDd7C66dA4a1B1"
2599
+ SolverAccount: "0x110C7E1814c923127469Ca8939a12dAa70B96a17"
2600
2600
  },
2601
2601
  rpcEnvKey: "BSC_CHAPEL",
2602
2602
  defaultRpcUrl: "https://bnb-testnet.api.onfinality.io/public",
@@ -2704,7 +2704,7 @@ var chainConfigs = {
2704
2704
  },
2705
2705
  addresses: {
2706
2706
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2707
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2707
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
2708
2708
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2709
2709
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2710
2710
  UniswapRouter02: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
@@ -2759,7 +2759,7 @@ var chainConfigs = {
2759
2759
  },
2760
2760
  addresses: {
2761
2761
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2762
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2762
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
2763
2763
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2764
2764
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2765
2765
  UniswapRouter02: "0x10ED43C718714eb63d5aA57B78B54704E256024E",
@@ -2815,7 +2815,7 @@ var chainConfigs = {
2815
2815
  },
2816
2816
  addresses: {
2817
2817
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2818
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2818
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
2819
2819
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2820
2820
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2821
2821
  UniswapRouter02: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
@@ -2872,7 +2872,7 @@ var chainConfigs = {
2872
2872
  },
2873
2873
  addresses: {
2874
2874
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2875
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2875
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
2876
2876
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
2877
2877
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2878
2878
  UniswapRouter02: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
@@ -2931,7 +2931,7 @@ var chainConfigs = {
2931
2931
  },
2932
2932
  addresses: {
2933
2933
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
2934
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
2934
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
2935
2935
  TokenGateway: "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E",
2936
2936
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
2937
2937
  UniswapRouter02: "0xd2f9496824951D5237cC71245D659E48d0d5f9E8",
@@ -3018,7 +3018,7 @@ var chainConfigs = {
3018
3018
  Calldispatcher: "0x876F1891982E260026630c233A4897160A281Fb8",
3019
3019
  Permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
3020
3020
  EntryPointV08: "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
3021
- SolverAccount: "0x07FeC66d967800998060194EaECDd7C66dA4a1B1"
3021
+ SolverAccount: "0x110C7E1814c923127469Ca8939a12dAa70B96a17"
3022
3022
  },
3023
3023
  rpcEnvKey: "POLYGON_AMOY",
3024
3024
  defaultRpcUrl: "https://rpc-amoy.polygon.technology",
@@ -3042,7 +3042,7 @@ var chainConfigs = {
3042
3042
  },
3043
3043
  addresses: {
3044
3044
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
3045
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
3045
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
3046
3046
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
3047
3047
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
3048
3048
  UniswapRouter02: "0x4A7b5Da61326A6379179b40d00F57E5bbDC962c2",
@@ -3077,7 +3077,7 @@ var chainConfigs = {
3077
3077
  },
3078
3078
  addresses: {
3079
3079
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
3080
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
3080
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
3081
3081
  TokenGateway: "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE",
3082
3082
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
3083
3083
  UniswapRouter02: "0xB2e26652e4BAd1e56055A051f922E06760cA0BFE",
@@ -3232,7 +3232,7 @@ var chainConfigs = {
3232
3232
  },
3233
3233
  addresses: {
3234
3234
  IntentGateway: "0xAe041F7B0CB581876832830baeB6a2Aa2a3C9716",
3235
- SolverAccount: "0x975e80B476cB1d4Cd06c292ce36898f2bE4159ea",
3235
+ SolverAccount: "0x3bdB532d91F165BeFad5542700205f5BB5152a82",
3236
3236
  Host: "0x620128E2B19193d6Bd244a3AC8D3bBa0541B19c3",
3237
3237
  Calldispatcher: "0xE2C7e576E26E0bE7aC97c6fE925bcDAbD87c4bEd"
3238
3238
  },
@@ -7044,6 +7044,11 @@ var ExpectedError = class _ExpectedError extends Error {
7044
7044
  return error instanceof _ExpectedError;
7045
7045
  }
7046
7046
  };
7047
+
7048
+ // src/configs/constants.ts
7049
+ var ISMP_PREFIX = ":child_storage:default:ISMPv2";
7050
+
7051
+ // src/chains/substrate.ts
7047
7052
  var HttpRpcClient = class {
7048
7053
  constructor(url) {
7049
7054
  this.url = url;
@@ -7167,7 +7172,7 @@ var SubstrateChain = class _SubstrateChain {
7167
7172
  * @returns {Promise<HexString | undefined>} The commitment data if found, undefined otherwise.
7168
7173
  */
7169
7174
  async queryRequestCommitment(commitment) {
7170
- const prefix = viem.toHex(":child_storage:default:ISMP");
7175
+ const prefix = viem.toHex(ISMP_PREFIX);
7171
7176
  const key = this.requestCommitmentKey(commitment);
7172
7177
  const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7173
7178
  return item;
@@ -7178,7 +7183,7 @@ var SubstrateChain = class _SubstrateChain {
7178
7183
  * @returns {Promise<HexString | undefined>} The relayer address responsible for delivering the request.
7179
7184
  */
7180
7185
  async queryRequestReceipt(commitment) {
7181
- const prefix = viem.toHex(":child_storage:default:ISMP");
7186
+ const prefix = viem.toHex(ISMP_PREFIX);
7182
7187
  const key = this.requestReceiptKey(commitment);
7183
7188
  const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7184
7189
  return item;
@@ -7202,7 +7207,7 @@ var SubstrateChain = class _SubstrateChain {
7202
7207
  * @returns {Promise<HexString | undefined>} The receipt data if present, otherwise undefined.
7203
7208
  */
7204
7209
  async queryResponseReceipt(commitment) {
7205
- const prefix = viem.toHex(":child_storage:default:ISMP");
7210
+ const prefix = viem.toHex(ISMP_PREFIX);
7206
7211
  const key = this.responseReceiptKey(commitment);
7207
7212
  const item = await this.rpcClient.call("childstate_getStorage", [prefix, key]);
7208
7213
  return item;
@@ -14769,6 +14774,67 @@ var CryptoUtils = class _CryptoUtils {
14769
14774
  viem.encodePacked(["bytes1", "bytes1", "bytes32", "bytes32"], ["0x19", "0x01", domainSeparator, structHash])
14770
14775
  );
14771
14776
  }
14777
+ /**
14778
+ * Derives the ERC-4337 nonce key that binds a bid UserOperation to its
14779
+ * order and session key: the lower 192 bits of
14780
+ * `keccak256(commitment ‖ sessionKey)`. `SolverAccount` rejects bid
14781
+ * operations whose nonce key differs — this is what lets the solver sign
14782
+ * the plain userOpHash while staying committed to the order and to the
14783
+ * session key it bid against.
14784
+ *
14785
+ * @param commitment - The order commitment (`order.id`).
14786
+ * @param sessionKey - The order's session key address (`order.session`).
14787
+ * @returns The 192-bit nonce key as a bigint (pass to `EntryPoint.getNonce`).
14788
+ */
14789
+ static bidNonceKey(commitment, sessionKey) {
14790
+ return BigInt(viem.keccak256(viem.encodePacked(["bytes32", "address"], [commitment, sessionKey]))) & (1n << 192n) - 1n;
14791
+ }
14792
+ /**
14793
+ * Builds the EIP-712 typed-data payload whose digest is the EntryPoint v0.8
14794
+ * `userOpHash` (i.e. `hashTypedData(packedUserOpTypedData(...)) ===
14795
+ * computeUserOpHash(...)`). Signing this typed data is bit-identical to
14796
+ * signing the raw userOpHash, but keeps the full operation visible to
14797
+ * signing infrastructure (hardware wallets, MPC/TEE policy engines) instead
14798
+ * of an opaque 32-byte digest.
14799
+ *
14800
+ * @param userOp - The packed UserOperation to sign (signature field ignored).
14801
+ * @param entryPoint - Address of the EntryPoint v0.8 contract.
14802
+ * @param chainId - Chain ID of the network on which the operation will execute.
14803
+ * @returns A viem `TypedDataDefinition` for the operation.
14804
+ */
14805
+ static packedUserOpTypedData(userOp, entryPoint, chainId) {
14806
+ return {
14807
+ domain: {
14808
+ name: "ERC4337",
14809
+ version: "1",
14810
+ chainId,
14811
+ verifyingContract: entryPoint
14812
+ },
14813
+ types: {
14814
+ PackedUserOperation: [
14815
+ { name: "sender", type: "address" },
14816
+ { name: "nonce", type: "uint256" },
14817
+ { name: "initCode", type: "bytes" },
14818
+ { name: "callData", type: "bytes" },
14819
+ { name: "accountGasLimits", type: "bytes32" },
14820
+ { name: "preVerificationGas", type: "uint256" },
14821
+ { name: "gasFees", type: "bytes32" },
14822
+ { name: "paymasterAndData", type: "bytes" }
14823
+ ]
14824
+ },
14825
+ primaryType: "PackedUserOperation",
14826
+ message: {
14827
+ sender: userOp.sender,
14828
+ nonce: userOp.nonce,
14829
+ initCode: userOp.initCode,
14830
+ callData: userOp.callData,
14831
+ accountGasLimits: userOp.accountGasLimits,
14832
+ preVerificationGas: userOp.preVerificationGas,
14833
+ gasFees: userOp.gasFees,
14834
+ paymasterAndData: userOp.paymasterAndData
14835
+ }
14836
+ };
14837
+ }
14772
14838
  /**
14773
14839
  * Computes the EIP-712 struct hash of a `PackedUserOperation`.
14774
14840
  *
@@ -15310,7 +15376,11 @@ var OrderExecutor = class {
15310
15376
  */
15311
15377
  async fetchBids(params) {
15312
15378
  const { commitment, solver, solverLockStartTime } = params;
15313
- const fetchedBids = await this.ctx.intentsCoprocessor.getBidsForOrder(commitment);
15379
+ const intentsCoprocessor = this.ctx.intentsCoprocessor;
15380
+ if (!intentsCoprocessor) {
15381
+ throw new Error("IntentsCoprocessor required for order execution");
15382
+ }
15383
+ const fetchedBids = await intentsCoprocessor.getBidsForOrder(commitment);
15314
15384
  if (solver) {
15315
15385
  const { address, timeoutMs } = solver;
15316
15386
  const solverLockActive = Date.now() - solverLockStartTime < timeoutMs;
@@ -15399,7 +15469,7 @@ var OrderExecutor = class {
15399
15469
  * → (`FILLED` | `PARTIAL_FILL`)* → (`FILLED` | `EXPIRED`)
15400
15470
  *
15401
15471
  * **Cross-chain:** `AWAITING_BIDS` → `BIDS_RECEIVED` → `BID_SELECTED`
15402
- * (terminates — settlement is confirmed async via Hyperbridge)
15472
+ * `FILLED`
15403
15473
  */
15404
15474
  async *executeOrder(options) {
15405
15475
  const { order, sessionPrivateKey, auctionTimeMs, pollIntervalMs = DEFAULT_POLL_INTERVAL, solver } = options;
@@ -15538,7 +15608,13 @@ var OrderExecutor = class {
15538
15608
  userOp: result.userOp,
15539
15609
  transactionHash: result.txnHash
15540
15610
  };
15541
- const fill = this.processFillResult(result, commitment, targetAssets, totalFilledAssets, remainingAssets);
15611
+ const fill = this.processFillResult(
15612
+ result,
15613
+ commitment,
15614
+ targetAssets,
15615
+ totalFilledAssets,
15616
+ remainingAssets
15617
+ );
15542
15618
  totalFilledAssets = fill.totalFilledAssets;
15543
15619
  remainingAssets = fill.remainingAssets;
15544
15620
  if (fill.update) {
@@ -15564,6 +15640,10 @@ var OrderCanceller = class {
15564
15640
  this.ctx = ctx;
15565
15641
  }
15566
15642
  ctx;
15643
+ logger = consola.createConsola({
15644
+ level: consola.LogLevels.info,
15645
+ formatOptions: { columns: 80, colors: true, compact: true, date: false }
15646
+ }).withTag("[OrderCanceller]");
15567
15647
  /**
15568
15648
  * Returns both the native token cost and the relayer fee for cancelling an
15569
15649
  * order. Frontends can use `relayerFee` to approve the ERC-20 spend before
@@ -15979,32 +16059,55 @@ var OrderCanceller = class {
15979
16059
  }
15980
16060
  /**
15981
16061
  * Submits an unsigned GET request message to Hyperbridge and waits until
15982
- * the request receipt is confirmed on-chain.
16062
+ * the GET response receipt is confirmed on-chain.
15983
16063
  *
15984
- * If the initial submission fails, the method waits 30 seconds and then
15985
- * retries querying for the receipt up to 10 times with 5-second back-off.
16064
+ * GET handling on Hyperbridge creates a response receipt keyed by the
16065
+ * request commitment. That receipt is the durable delivery signal, so a
16066
+ * duplicate unsigned submission is considered successful only if the
16067
+ * response receipt can be observed.
15986
16068
  *
15987
16069
  * @param hyperbridge - Hyperbridge Substrate chain client.
15988
16070
  * @param commitment - The GET request commitment hash used to poll for the receipt.
15989
16071
  * @param message - The fully constructed GET request message to submit.
15990
16072
  */
15991
16073
  async submitAndConfirmReceipt(hyperbridge, commitment, message) {
15992
- let storageValue = await hyperbridge.queryRequestReceipt(commitment);
15993
- if (!storageValue) {
15994
- try {
15995
- await hyperbridge.submitUnsigned(message);
15996
- } catch {
15997
- }
16074
+ this.logger.info(`Checking GET response receipt before Hyperbridge delivery (${commitment})`);
16075
+ if (await this.queryDeliveredReceipt(hyperbridge, commitment)) {
16076
+ this.logger.info(`GET ${commitment} already delivered to Hyperbridge; skipping unsigned submission`);
16077
+ return;
16078
+ }
16079
+ try {
16080
+ this.logger.info(`Submitting unsigned GET ${commitment} to Hyperbridge`);
16081
+ await hyperbridge.submitUnsigned(message);
16082
+ this.logger.info(`Unsigned GET ${commitment} submitted; waiting for Hyperbridge response receipt`);
15998
16083
  await sleep(3e4);
15999
- storageValue = await retryPromise(
16000
- async () => {
16001
- const value = await hyperbridge.queryRequestReceipt(commitment);
16002
- if (!value) throw new Error("Receipt not found");
16003
- return value;
16004
- },
16005
- { maxRetries: 10, backoffMs: 5e3, logMessage: "Checking for receipt" }
16084
+ } catch (error) {
16085
+ this.logger.warn(
16086
+ `Unsigned GET submit failed for ${commitment}; polling response receipt before failing: ${String(error)}`
16006
16087
  );
16007
16088
  }
16089
+ try {
16090
+ await this.pollDeliveredReceipt(hyperbridge, commitment);
16091
+ this.logger.info(`Confirmed Hyperbridge GET delivery for ${commitment}`);
16092
+ } catch (error) {
16093
+ const message2 = `Failed to deliver GET request to Hyperbridge; no response receipt found for ${commitment}: ${String(error)}`;
16094
+ this.logger.error(message2);
16095
+ throw new Error(message2);
16096
+ }
16097
+ }
16098
+ async queryDeliveredReceipt(hyperbridge, commitment) {
16099
+ return hyperbridge.queryResponseReceipt(commitment);
16100
+ }
16101
+ async pollDeliveredReceipt(hyperbridge, commitment) {
16102
+ this.logger.info(`Polling Hyperbridge GET response receipt for ${commitment}`);
16103
+ return retryPromise(
16104
+ async () => {
16105
+ const value = await this.queryDeliveredReceipt(hyperbridge, commitment);
16106
+ if (!value) throw new Error(`GET response receipt not found for ${commitment}`);
16107
+ return value;
16108
+ },
16109
+ { maxRetries: 10, backoffMs: 5e3, logMessage: `Checking GET response receipt ${commitment}` }
16110
+ );
16008
16111
  }
16009
16112
  /**
16010
16113
  * Estimates the relayer fee for delivering a POST from dest to source.
@@ -16075,7 +16178,7 @@ var BidImpl = class {
16075
16178
  const sessionKeyAddress = this.order.session;
16076
16179
  const sessionKeyData = this.sessionPrivateKey ? { privateKey: this.sessionPrivateKey } : await this.ctx.sessionKeyStorage.getSessionKeyByAddress(sessionKeyAddress);
16077
16180
  if (!sessionKeyData) {
16078
- throw new Error("SessionKey not found for commitment: " + commitment);
16181
+ throw new Error(`SessionKey not found for commitment: ${commitment}`);
16079
16182
  }
16080
16183
  const signature = await CryptoUtils.signSolverSelection(
16081
16184
  commitment,
@@ -16135,8 +16238,8 @@ var BidImpl = class {
16135
16238
  /**
16136
16239
  * Signs the `SelectSolver` message with the session key, appends it to the
16137
16240
  * solver's existing UserOp signature, and submits the UserOperation to the
16138
- * bundler. For same-chain orders, waits for the receipt and reads
16139
- * `OrderFilled` / `PartialFill` logs to determine fill status.
16241
+ * bundler. Waits for the receipt and reads `OrderFilled` / `PartialFill`
16242
+ * logs to determine fill status.
16140
16243
  *
16141
16244
  * @returns A {@link SelectBidResult} with the submitted UserOperation, its hash,
16142
16245
  * the solver address, transaction hash, and fill status.
@@ -16176,33 +16279,31 @@ var BidImpl = class {
16176
16279
  { maxRetries: 5, backoffMs: 2e3, logMessage: "Fetching user operation receipt" }
16177
16280
  );
16178
16281
  txnHash = receipt.receipt.transactionHash;
16179
- if (this.order.source === this.order.destination) {
16180
- try {
16181
- const chainReceipt = await this.ctx.dest.client.waitForTransactionReceipt({
16182
- hash: txnHash,
16183
- confirmations: 1
16184
- });
16185
- const events = viem.parseEventLogs({
16186
- abi: ABI3,
16187
- logs: chainReceipt.logs,
16188
- eventName: ["OrderFilled", "PartialFill"]
16189
- });
16190
- const matched = events.find((e) => {
16191
- if (e.eventName === "OrderFilled")
16192
- return e.args.commitment.toLowerCase() === commitment.toLowerCase();
16193
- if (e.eventName === "PartialFill")
16194
- return e.args.commitment.toLowerCase() === commitment.toLowerCase();
16195
- return false;
16196
- });
16197
- if (matched?.eventName === "OrderFilled") {
16198
- fillStatus = "full";
16199
- } else if (matched?.eventName === "PartialFill") {
16200
- fillStatus = "partial";
16201
- filledAssets = matched.args.outputs ?? [];
16202
- }
16203
- } catch {
16204
- throw new Error("Failed to determine fill status from logs");
16282
+ try {
16283
+ const chainReceipt = await this.ctx.dest.client.waitForTransactionReceipt({
16284
+ hash: txnHash,
16285
+ confirmations: 1
16286
+ });
16287
+ const events = viem.parseEventLogs({
16288
+ abi: ABI3,
16289
+ logs: chainReceipt.logs,
16290
+ eventName: ["OrderFilled", "PartialFill"]
16291
+ });
16292
+ const matched = events.find((e) => {
16293
+ if (e.eventName === "OrderFilled")
16294
+ return e.args.commitment.toLowerCase() === commitment.toLowerCase();
16295
+ if (e.eventName === "PartialFill")
16296
+ return e.args.commitment.toLowerCase() === commitment.toLowerCase();
16297
+ return false;
16298
+ });
16299
+ if (matched?.eventName === "OrderFilled") {
16300
+ fillStatus = "full";
16301
+ } else if (matched?.eventName === "PartialFill") {
16302
+ fillStatus = "partial";
16303
+ filledAssets = matched.args.outputs ?? [];
16205
16304
  }
16305
+ } catch {
16306
+ throw new Error("Failed to determine fill status from logs");
16206
16307
  }
16207
16308
  } catch (err) {
16208
16309
  throw new Error(`Failed to execute bid: ${err instanceof Error ? err.message : String(err)}`);
@@ -16242,9 +16343,12 @@ var BidManager = class {
16242
16343
  * Constructs a signed `PackedUserOperation` that a solver can submit to the
16243
16344
  * Hyperbridge coprocessor as a bid to fill an order.
16244
16345
  *
16245
- * The solver's signature covers a hash that binds the UserOperation to the
16246
- * order commitment and the session key address, so the IntentGatewayV2
16247
- * contract can verify the solver's intent on-chain.
16346
+ * The solver signs the operation as EntryPoint v0.8 EIP-712 typed data,
16347
+ * whose digest is the plain userOpHash. The binding to the order lives in
16348
+ * the operation itself: the 4337 nonce key must be the lower 192 bits of
16349
+ * the order commitment (`SolverAccount` enforces this during validation),
16350
+ * and the callData carries the order. This keeps the signed payload fully
16351
+ * transparent to signing infrastructure instead of an opaque digest.
16248
16352
  *
16249
16353
  * @param options - Parameters describing the solver account, gas limits, fee
16250
16354
  * market values, and pre-built `callData` for the fill operation.
@@ -16282,10 +16386,17 @@ var BidManager = class {
16282
16386
  paymasterAndData,
16283
16387
  signature: "0x"
16284
16388
  };
16285
- const userOpHash = CryptoUtils.computeUserOpHash(userOp, entryPointAddress, chainId);
16286
- const sessionKey = order.session;
16287
- const messageHash = viem.keccak256(viem.concat([userOpHash, order.id, sessionKey]));
16288
- const solverSignature = await solverSigner.signMessage(messageHash, Number(chainId));
16389
+ const nonceKey = BigInt(nonce) >> 64n;
16390
+ const expectedKey = CryptoUtils.bidNonceKey(order.id, order.session);
16391
+ if (nonceKey !== expectedKey) {
16392
+ console.warn(
16393
+ `[BidManager] bid nonce key does not bind the order commitment and session key; on-chain validation will fail (order=${order.id})`
16394
+ );
16395
+ }
16396
+ const solverSignature = await solverSigner.signTypedData(
16397
+ CryptoUtils.packedUserOpTypedData(userOp, entryPointAddress, chainId),
16398
+ Number(chainId)
16399
+ );
16289
16400
  const signature = viem.concat([order.id, solverSignature]);
16290
16401
  return { ...userOp, signature };
16291
16402
  }