@agirails/sdk 4.4.9 → 4.5.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.
Files changed (93) hide show
  1. package/dist/builders/DeliveryProofBuilder.d.ts +224 -13
  2. package/dist/builders/DeliveryProofBuilder.d.ts.map +1 -1
  3. package/dist/builders/DeliveryProofBuilder.js +247 -13
  4. package/dist/builders/DeliveryProofBuilder.js.map +1 -1
  5. package/dist/cli/agirails.d.ts +85 -1
  6. package/dist/cli/agirails.d.ts.map +1 -1
  7. package/dist/cli/agirails.js +429 -154
  8. package/dist/cli/agirails.js.map +1 -1
  9. package/dist/cli/commands/init.d.ts +54 -0
  10. package/dist/cli/commands/init.d.ts.map +1 -1
  11. package/dist/cli/commands/init.js +193 -1
  12. package/dist/cli/commands/init.js.map +1 -1
  13. package/dist/cli/commands/receipt.d.ts +70 -2
  14. package/dist/cli/commands/receipt.d.ts.map +1 -1
  15. package/dist/cli/commands/receipt.js +218 -3
  16. package/dist/cli/commands/receipt.js.map +1 -1
  17. package/dist/cli/commands/test.d.ts +77 -1
  18. package/dist/cli/commands/test.d.ts.map +1 -1
  19. package/dist/cli/commands/test.js +264 -2
  20. package/dist/cli/commands/test.js.map +1 -1
  21. package/dist/cli/lib/runRequest.d.ts +90 -0
  22. package/dist/cli/lib/runRequest.d.ts.map +1 -1
  23. package/dist/cli/lib/runRequest.js +300 -9
  24. package/dist/cli/lib/runRequest.js.map +1 -1
  25. package/dist/cli/lib/sentinelReflections.d.ts +111 -0
  26. package/dist/cli/lib/sentinelReflections.d.ts.map +1 -0
  27. package/dist/cli/lib/sentinelReflections.js +193 -0
  28. package/dist/cli/lib/sentinelReflections.js.map +1 -0
  29. package/dist/delivery/MockDeliveryChannel.d.ts +208 -0
  30. package/dist/delivery/MockDeliveryChannel.d.ts.map +1 -0
  31. package/dist/delivery/MockDeliveryChannel.js +445 -0
  32. package/dist/delivery/MockDeliveryChannel.js.map +1 -0
  33. package/dist/delivery/RelayDeliveryChannel.d.ts +176 -0
  34. package/dist/delivery/RelayDeliveryChannel.d.ts.map +1 -0
  35. package/dist/delivery/RelayDeliveryChannel.js +377 -0
  36. package/dist/delivery/RelayDeliveryChannel.js.map +1 -0
  37. package/dist/delivery/channel.d.ts +282 -0
  38. package/dist/delivery/channel.d.ts.map +1 -0
  39. package/dist/delivery/channel.js +76 -0
  40. package/dist/delivery/channel.js.map +1 -0
  41. package/dist/delivery/channelLog.d.ts +115 -0
  42. package/dist/delivery/channelLog.d.ts.map +1 -0
  43. package/dist/delivery/channelLog.js +94 -0
  44. package/dist/delivery/channelLog.js.map +1 -0
  45. package/dist/delivery/crypto.d.ts +312 -0
  46. package/dist/delivery/crypto.d.ts.map +1 -0
  47. package/dist/delivery/crypto.js +495 -0
  48. package/dist/delivery/crypto.js.map +1 -0
  49. package/dist/delivery/eip712.d.ts +248 -0
  50. package/dist/delivery/eip712.d.ts.map +1 -0
  51. package/dist/delivery/eip712.js +397 -0
  52. package/dist/delivery/eip712.js.map +1 -0
  53. package/dist/delivery/envelopeBuilder.d.ts +531 -0
  54. package/dist/delivery/envelopeBuilder.d.ts.map +1 -0
  55. package/dist/delivery/envelopeBuilder.js +832 -0
  56. package/dist/delivery/envelopeBuilder.js.map +1 -0
  57. package/dist/delivery/index.d.ts +53 -0
  58. package/dist/delivery/index.d.ts.map +1 -0
  59. package/dist/delivery/index.js +143 -0
  60. package/dist/delivery/index.js.map +1 -0
  61. package/dist/delivery/keys.d.ts +344 -0
  62. package/dist/delivery/keys.d.ts.map +1 -0
  63. package/dist/delivery/keys.js +513 -0
  64. package/dist/delivery/keys.js.map +1 -0
  65. package/dist/delivery/nonce-keys.d.ts +93 -0
  66. package/dist/delivery/nonce-keys.d.ts.map +1 -0
  67. package/dist/delivery/nonce-keys.js +88 -0
  68. package/dist/delivery/nonce-keys.js.map +1 -0
  69. package/dist/delivery/setupBuilder.d.ts +403 -0
  70. package/dist/delivery/setupBuilder.d.ts.map +1 -0
  71. package/dist/delivery/setupBuilder.js +554 -0
  72. package/dist/delivery/setupBuilder.js.map +1 -0
  73. package/dist/delivery/types.d.ts +722 -0
  74. package/dist/delivery/types.d.ts.map +1 -0
  75. package/dist/delivery/types.js +150 -0
  76. package/dist/delivery/types.js.map +1 -0
  77. package/dist/delivery/validate.d.ts +288 -0
  78. package/dist/delivery/validate.d.ts.map +1 -0
  79. package/dist/delivery/validate.js +648 -0
  80. package/dist/delivery/validate.js.map +1 -0
  81. package/dist/level1/Agent.d.ts +130 -0
  82. package/dist/level1/Agent.d.ts.map +1 -1
  83. package/dist/level1/Agent.js +248 -0
  84. package/dist/level1/Agent.js.map +1 -1
  85. package/dist/level1/types/Options.d.ts +62 -0
  86. package/dist/level1/types/Options.d.ts.map +1 -1
  87. package/dist/level1/types/Options.js +22 -0
  88. package/dist/level1/types/Options.js.map +1 -1
  89. package/dist/runtime/MockRuntime.d.ts +32 -0
  90. package/dist/runtime/MockRuntime.d.ts.map +1 -1
  91. package/dist/runtime/MockRuntime.js +44 -0
  92. package/dist/runtime/MockRuntime.js.map +1 -1
  93. package/package.json +6 -1
@@ -0,0 +1,554 @@
1
+ "use strict";
2
+ /**
3
+ * AIP-16 Delivery Surface — Buyer Setup Builder + Verifier (Phase 2b)
4
+ * =====================================================================
5
+ *
6
+ * Constructs and verifies the buyer-signed `DeliverySetupV1` payload —
7
+ * the first artifact of the AIP-16 Rev 5 delivery surface. The buyer
8
+ * (requester) posts this signed object to the delivery channel after
9
+ * the on-chain transaction reaches `COMMITTED`, declaring:
10
+ *
11
+ * - which kernel + chain the delivery is bound to,
12
+ * - which on-chain identity is acting as the requester,
13
+ * - which EOA produced the signature (smart-wallet two-step auth),
14
+ * - the buyer's ephemeral X25519 pubkey (or canonical-empty for `public`),
15
+ * - which channels the buyer accepts the envelope on,
16
+ * - the privacy posture the buyer expects,
17
+ * - and a creation timestamp + expiry for replay / staleness bounds.
18
+ *
19
+ * ## Builder shape
20
+ *
21
+ * Per the AIP-16 builder convention (and consistent with `QuoteBuilder`,
22
+ * `CounterOfferBuilder`, etc.):
23
+ *
24
+ * - `constructor(signer?, nonceManager?)` — both optional. A signer is
25
+ * REQUIRED for `build()`; `verify()` and `computeHash()` need
26
+ * neither, so verifying SDKs (relays, peer endpoints, dispute
27
+ * workers) can instantiate a no-arg builder.
28
+ *
29
+ * - `build()` is `async` because EIP-712 signing is async on real
30
+ * wallets (`Wallet.signTypedData` returns a `Promise`).
31
+ *
32
+ * - `verify()` and `computeHash()` are `static` — they take a wire
33
+ * object and need no builder state. This mirrors the existing
34
+ * `DeliveryProofBuilder` static-verify pattern.
35
+ *
36
+ * ## Smart-wallet two-step auth (DEC-10 / V2 receipts pattern)
37
+ *
38
+ * `requesterAddress` (the on-chain participant) and `signerAddress`
39
+ * (the EOA that produced the signature) are accepted SEPARATELY and
40
+ * are NOT derived from each other in this layer. When AutoWallet
41
+ * (AIP-12 Tier 1) is active, `requesterAddress` is the Smart Wallet
42
+ * contract and `signerAddress` is the controlling EOA; the SMART-WALLET
43
+ * DERIVATION (`computeSmartWalletFromSigner(signerAddress) ===
44
+ * requesterAddress`) is the SERVER'S responsibility, not the SDK's.
45
+ * Doing it here would silently couple the SDK to the Coinbase Smart
46
+ * Wallet factory ABI and break in cross-vendor flows.
47
+ *
48
+ * What the SDK DOES enforce in `build()` is the cheaper invariant:
49
+ * `signerAddress` MUST equal the address of the supplied `signer`.
50
+ * That catches the most common bug (caller passes the wrong
51
+ * `signerAddress`) without making assumptions about the participant.
52
+ *
53
+ * ## Nonce manager use
54
+ *
55
+ * The signed `DeliverySetupV1` schema has NO `nonce` field — replay
56
+ * binding is provided by `txId` (one tx per setup) and timestamps
57
+ * (`createdAt` / `expiresAt`). The `NonceManager` is still touched
58
+ * here so we have one place to hook future per-builder counters if
59
+ * the spec evolves; we use {@link DELIVERY_NONCE_KEY_SETUP} (distinct
60
+ * from the envelope key and the AIP-4 delivery-proof key) and the
61
+ * returned counter is reported back to the caller via
62
+ * {@link BuildSetupResult.nonceManagerKey} so the caller can audit
63
+ * the path was reached. Because the value is not signed, we tolerate
64
+ * a missing `NonceManager` gracefully — `build()` does NOT throw on
65
+ * undefined `nonceManager`, it simply skips the counter bump.
66
+ *
67
+ * ## Verification order
68
+ *
69
+ * `verify()` is `static` and runs checks in a fixed coarse → fine
70
+ * order, short-circuiting at the first failure with a stable
71
+ * structured code. The order is chosen so that cheap, unambiguous
72
+ * defects are reported BEFORE the more expensive signature recovery,
73
+ * but also so that signature failures are reported before policy
74
+ * failures (timestamp skew, expiry) — a forged signature is a more
75
+ * severe class of error and we want the caller to see it first.
76
+ *
77
+ * @module delivery/setupBuilder
78
+ * @see ./types — signed/wire interfaces and `BuildSetupResult`.
79
+ * @see ./eip712 — domain, types, and `recoverSetupSigner`.
80
+ * @see ./validate — `validateSetupWire` (structural validation).
81
+ * @see ./nonce-keys — `DELIVERY_NONCE_KEY_SETUP`.
82
+ */
83
+ Object.defineProperty(exports, "__esModule", { value: true });
84
+ exports.DeliverySetupBuilder = exports.resetSecondsNowForTests = exports.setSecondsNowForTests = exports.DEFAULT_ACCEPTED_CHANNELS = exports.SETUP_TIMESTAMP_SKEW_SEC = exports.DEFAULT_SETUP_EXPIRY_SEC = void 0;
85
+ const ethers_1 = require("ethers");
86
+ const canonicalJson_1 = require("../utils/canonicalJson");
87
+ const eip712_1 = require("./eip712");
88
+ const nonce_keys_1 = require("./nonce-keys");
89
+ const types_1 = require("./types");
90
+ const validate_1 = require("./validate");
91
+ // ============================================================================
92
+ // Constants
93
+ // ============================================================================
94
+ /**
95
+ * Default expiry, in seconds, applied when callers omit `expiresInSec`.
96
+ *
97
+ * 3600 (1 hour) matches the negotiation-layer default and is bounded
98
+ * by the relay's accepted-setup TTL. Callers facing high-latency
99
+ * counterparties may pass an explicit larger value, but the relay
100
+ * SHOULD cap at its own policy ceiling.
101
+ */
102
+ exports.DEFAULT_SETUP_EXPIRY_SEC = 3600;
103
+ /**
104
+ * Maximum tolerated clock-skew, in seconds, between the signed
105
+ * `createdAt` and the verifier's wall clock. Symmetric (past + future).
106
+ *
107
+ * 900s (15 min) matches the receipts-V2 freshness window and the
108
+ * AIP-3 anchor-receipt skew bound. Tighter would penalize NTP-skewed
109
+ * client machines; looser would meaningfully extend the replay
110
+ * window an attacker has to work with a leaked setup.
111
+ */
112
+ exports.SETUP_TIMESTAMP_SKEW_SEC = 900;
113
+ /**
114
+ * Default v1 channel list applied when callers omit `acceptedChannels`.
115
+ *
116
+ * The v1 channel registry has exactly one entry; future channels MUST
117
+ * be added by callers explicitly so that channel-selection is always
118
+ * an intentional choice, not a hidden default.
119
+ */
120
+ exports.DEFAULT_ACCEPTED_CHANNELS = [
121
+ 'agirails-relay-v1',
122
+ ];
123
+ // ============================================================================
124
+ // secondsNow — Injectable Clock
125
+ // ============================================================================
126
+ //
127
+ // All timestamp reads inside this module flow through `secondsNow()`.
128
+ // Tests inject a deterministic clock via {@link setSecondsNowForTests};
129
+ // production calls fall through to the real wall clock.
130
+ //
131
+ // We do NOT call `Date.now()` directly at any other point in this file
132
+ // for the same reason `QuoteBuilder` exists: deterministic builds need
133
+ // a single seam to control. The forbidden-token discipline in higher
134
+ // PRDs also depends on this seam — there should be ONE place where a
135
+ // real clock call lives, behind a name that surfaces in stack traces.
136
+ //
137
+ /**
138
+ * Reads the real wall clock as Unix seconds (integer).
139
+ *
140
+ * Wrapped in a function (rather than inlined) so tests can replace
141
+ * it via {@link setSecondsNowForTests} and so the forbidden-token
142
+ * lint cares about exactly one site.
143
+ */
144
+ let secondsNowImpl = () => {
145
+ // Single allowed wall-clock site in this module. Math.floor produces
146
+ // an integer; integer Unix seconds round-trip cleanly through the
147
+ // EIP-712 `uint64` field.
148
+ return Math.floor(Date.now() / 1000);
149
+ };
150
+ /**
151
+ * Return the current wall-clock time in Unix seconds.
152
+ *
153
+ * Production: real `Date.now()` via {@link secondsNowImpl}.
154
+ * Tests: injected via {@link setSecondsNowForTests}.
155
+ *
156
+ * @returns Integer seconds since the Unix epoch.
157
+ */
158
+ function secondsNow() {
159
+ return secondsNowImpl();
160
+ }
161
+ /**
162
+ * Replace the wall-clock implementation used inside this module.
163
+ *
164
+ * **TEST-ONLY.** Production code MUST NOT call this. The function is
165
+ * exported because Jest spies cannot intercept top-level `let`
166
+ * assignments cleanly across ESM/CJS boundaries; an explicit setter
167
+ * keeps the seam visible and grep-able.
168
+ *
169
+ * Pass `null` (or call {@link resetSecondsNowForTests}) to restore
170
+ * the real wall-clock implementation.
171
+ *
172
+ * @param impl - Replacement function returning Unix seconds, or `null`
173
+ * to restore the default real-clock implementation.
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * setSecondsNowForTests(() => 1_750_000_000);
178
+ * try {
179
+ * const { wire } = await new DeliverySetupBuilder(wallet).build(params);
180
+ * expect(wire.signed.createdAt).toBe(1_750_000_000);
181
+ * } finally {
182
+ * resetSecondsNowForTests();
183
+ * }
184
+ * ```
185
+ */
186
+ function setSecondsNowForTests(impl) {
187
+ if (impl === null) {
188
+ resetSecondsNowForTests();
189
+ return;
190
+ }
191
+ secondsNowImpl = impl;
192
+ }
193
+ exports.setSecondsNowForTests = setSecondsNowForTests;
194
+ /**
195
+ * Restore {@link secondsNow} to its default real-clock implementation.
196
+ *
197
+ * **TEST-ONLY.** Called from `afterEach` blocks; safe to call when no
198
+ * override is active.
199
+ */
200
+ function resetSecondsNowForTests() {
201
+ secondsNowImpl = () => Math.floor(Date.now() / 1000);
202
+ }
203
+ exports.resetSecondsNowForTests = resetSecondsNowForTests;
204
+ // ============================================================================
205
+ // Setup Builder
206
+ // ============================================================================
207
+ /**
208
+ * Builder + verifier for AIP-16 delivery setup messages.
209
+ *
210
+ * Instances are cheap to construct and have no I/O side effects.
211
+ * `verify()` and `computeHash()` are static — call them without
212
+ * constructing an instance.
213
+ *
214
+ * @example Buyer signing flow
215
+ * ```typescript
216
+ * const builder = new DeliverySetupBuilder(wallet, nonceManager);
217
+ * const { wire } = await builder.build({
218
+ * txId,
219
+ * chainId: 84532,
220
+ * kernelAddress: KERNEL,
221
+ * requesterAddress: SMART_WALLET,
222
+ * signerAddress: EOA,
223
+ * buyerEphemeralPubkey: '0x' + 'aa'.repeat(32),
224
+ * expectedPrivacy: 'encrypted',
225
+ * });
226
+ * await postToRelay(wire);
227
+ * ```
228
+ *
229
+ * @example Provider verification flow
230
+ * ```typescript
231
+ * const result = DeliverySetupBuilder.verify(wire, {
232
+ * expectedKernelAddress: KERNEL,
233
+ * expectedChainId: 84532,
234
+ * });
235
+ * if (!result.ok) {
236
+ * throw new Error(`Setup verification failed: ${result.code}`);
237
+ * }
238
+ * const setup = result.signed;
239
+ * ```
240
+ */
241
+ class DeliverySetupBuilder {
242
+ /**
243
+ * Construct a new builder.
244
+ *
245
+ * @param signer - EOA signer required for {@link build}. Pass `undefined`
246
+ * to construct a verify-only instance; `verify()` and `computeHash()`
247
+ * are static and do not need a builder instance at all, but a
248
+ * no-arg constructor is supported for symmetry with peer builders.
249
+ * @param nonceManager - Optional nonce manager. The v1 setup schema
250
+ * has no `nonce` field, so this is purely an audit hook today;
251
+ * when supplied, `build()` calls `getNextNonce(DELIVERY_NONCE_KEY_SETUP)`
252
+ * to advance the counter. Missing manager is tolerated.
253
+ */
254
+ constructor(signer, nonceManager) {
255
+ this.signer = signer;
256
+ this.nonceManager = nonceManager;
257
+ }
258
+ // --------------------------------------------------------------------------
259
+ // build
260
+ // --------------------------------------------------------------------------
261
+ /**
262
+ * Construct, sign, and return a {@link DeliverySetupWireV1}.
263
+ *
264
+ * Pre-checks:
265
+ * - signer MUST be present (throws `BUILDER_NO_SIGNER` otherwise).
266
+ * - `signerAddress` MUST equal `await signer.getAddress()`
267
+ * (throws `BUILDER_SIGNER_ADDRESS_MISMATCH` otherwise).
268
+ * - For `expectedPrivacy: "public"`, `buyerEphemeralPubkey` MUST equal
269
+ * {@link CANONICAL_EMPTY_BYTES32}.
270
+ * - For `expectedPrivacy: "encrypted"`, `buyerEphemeralPubkey` MUST NOT
271
+ * be {@link CANONICAL_EMPTY_BYTES32} (a zero X25519 public key is
272
+ * rejected by RFC 7748 §6.1 anyway, but we surface a clearer error).
273
+ * - `expiresInSec` (when supplied) must be a positive integer.
274
+ *
275
+ * Signing:
276
+ * - Uses `signer.signTypedData(domain, types, signed)` with the
277
+ * canonical delivery EIP-712 domain anchored to `kernelAddress`.
278
+ *
279
+ * Nonce manager:
280
+ * - When supplied, `getNextNonce(DELIVERY_NONCE_KEY_SETUP)` is called
281
+ * purely for audit / future-compat. The returned counter is NOT
282
+ * encoded into the signed payload (the v1 schema has no nonce
283
+ * field) and the caller MAY ignore `nonceManagerKey` in the result.
284
+ *
285
+ * @param params - {@link BuildSetupParams}.
286
+ * @returns A {@link BuildSetupResult} carrying the signed wire object
287
+ * and the nonce-manager key that was touched (always
288
+ * {@link DELIVERY_NONCE_KEY_SETUP} for v1).
289
+ * @throws {DeliveryEip712Error} on signer absence, signer/address
290
+ * mismatch, or canonical-empty rule violation.
291
+ */
292
+ async build(params) {
293
+ if (!this.signer) {
294
+ throw new eip712_1.DeliveryEip712Error('BUILDER_NO_SIGNER', 'DeliverySetupBuilder.build requires a signer; construct the builder with a Signer to sign setups.');
295
+ }
296
+ // ----- Privacy / pubkey consistency -----
297
+ //
298
+ // EIP-712 cannot represent "absent field" — we sign canonical-empty
299
+ // for public privacy, and reject canonical-empty for encrypted
300
+ // privacy. The wire-side `validateSchemeConsistency` runs on the
301
+ // ENVELOPE; the setup side does its own check here in the builder
302
+ // because the spec ties `buyerEphemeralPubkey` to `expectedPrivacy`.
303
+ const pubkeyIsEmpty = params.buyerEphemeralPubkey.toLowerCase() === types_1.CANONICAL_EMPTY_BYTES32.toLowerCase();
304
+ if (params.expectedPrivacy === 'public' && !pubkeyIsEmpty) {
305
+ throw new eip712_1.DeliveryEip712Error('BUILDER_PUBLIC_PUBKEY_NOT_CANONICAL_EMPTY', 'expectedPrivacy="public" requires buyerEphemeralPubkey === CANONICAL_EMPTY_BYTES32 (32 zero bytes).', { expectedPrivacy: params.expectedPrivacy, buyerEphemeralPubkey: params.buyerEphemeralPubkey });
306
+ }
307
+ if (params.expectedPrivacy === 'encrypted' && pubkeyIsEmpty) {
308
+ throw new eip712_1.DeliveryEip712Error('BUILDER_ENCRYPTED_PUBKEY_IS_CANONICAL_EMPTY', 'expectedPrivacy="encrypted" requires a non-zero X25519 pubkey in buyerEphemeralPubkey (RFC 7748 §6.1).', { expectedPrivacy: params.expectedPrivacy });
309
+ }
310
+ // ----- Expiry window -----
311
+ const expiresInSec = params.expiresInSec ?? exports.DEFAULT_SETUP_EXPIRY_SEC;
312
+ if (!Number.isInteger(expiresInSec) || expiresInSec <= 0) {
313
+ throw new eip712_1.DeliveryEip712Error('BUILDER_INVALID_EXPIRES_IN', `expiresInSec must be a positive integer, got ${String(expiresInSec)}`, { expiresInSec });
314
+ }
315
+ // ----- Smart-wallet nonce (H4 fix) -----
316
+ //
317
+ // Default to 0 to preserve backward-compat with pre-H4 callers; the
318
+ // legacy hard-coded nonce-0 server derivation produces the same
319
+ // on-wire byte pattern, so existing tests continue to pass.
320
+ const smartWalletNonce = params.smartWalletNonce ?? 0;
321
+ if (!Number.isInteger(smartWalletNonce) || smartWalletNonce < 0) {
322
+ throw new eip712_1.DeliveryEip712Error('BUILDER_INVALID_SMART_WALLET_NONCE', `smartWalletNonce must be a non-negative integer, got ${String(smartWalletNonce)}`, { smartWalletNonce });
323
+ }
324
+ // ----- Timestamps -----
325
+ const createdAt = params.createdAt ?? secondsNow();
326
+ if (!Number.isInteger(createdAt) || createdAt <= 0) {
327
+ throw new eip712_1.DeliveryEip712Error('BUILDER_INVALID_CREATED_AT', `createdAt must be a positive integer, got ${String(createdAt)}`, { createdAt });
328
+ }
329
+ const expiresAt = createdAt + expiresInSec;
330
+ // ----- Signer-address binding -----
331
+ //
332
+ // We do NOT rely on the signer to produce the right `signerAddress`
333
+ // for us — we cross-check it explicitly so a wrong-EOA bug is
334
+ // caught at build time, not later at relay-side verification.
335
+ const actualSigner = await this.signer.getAddress();
336
+ if (actualSigner.toLowerCase() !== params.signerAddress.toLowerCase()) {
337
+ throw new eip712_1.DeliveryEip712Error('BUILDER_SIGNER_ADDRESS_MISMATCH', 'params.signerAddress does not match signer.getAddress()', {
338
+ expected: actualSigner.toLowerCase(),
339
+ got: params.signerAddress.toLowerCase(),
340
+ });
341
+ }
342
+ // ----- Nonce-manager hook (audit / future-compat) -----
343
+ //
344
+ // The signed v1 schema has no nonce field. The call here exists so
345
+ // a future v2 spec can plug a real counter in without churning the
346
+ // builder surface. `getNextNonce` is sync and returns a number; we
347
+ // intentionally discard the value (it's the manager's
348
+ // `getCurrentNonce` for the same key, +1, and we don't record).
349
+ if (this.nonceManager) {
350
+ // Defensive: a misbehaving manager could throw at the upper bound;
351
+ // we swallow nothing here, propagating as a builder error so the
352
+ // caller sees the actual failure.
353
+ this.nonceManager.getNextNonce(nonce_keys_1.DELIVERY_NONCE_KEY_SETUP);
354
+ }
355
+ // ----- Build signed projection -----
356
+ //
357
+ // Field order in the OBJECT does NOT matter — EIP-712 hashes by
358
+ // the type schema, not by JS key insertion order. We mirror the
359
+ // schema order in the source for readability and to make it
360
+ // easy to spot drift against `DELIVERY_SETUP_TYPES_V1`.
361
+ const acceptedChannels = params.acceptedChannels ?? [...exports.DEFAULT_ACCEPTED_CHANNELS];
362
+ const signed = {
363
+ version: 1,
364
+ txId: params.txId,
365
+ chainId: params.chainId,
366
+ kernelAddress: params.kernelAddress,
367
+ requesterAddress: params.requesterAddress,
368
+ signerAddress: params.signerAddress,
369
+ buyerEphemeralPubkey: params.buyerEphemeralPubkey,
370
+ acceptedChannels,
371
+ expectedPrivacy: params.expectedPrivacy,
372
+ createdAt,
373
+ expiresAt,
374
+ smartWalletNonce,
375
+ };
376
+ // ----- Sign -----
377
+ const domain = (0, eip712_1.buildDeliveryDomain)(params.chainId, params.kernelAddress);
378
+ const requesterSig = (await this.signer.signTypedData(domain, eip712_1.DELIVERY_SETUP_TYPES_V1, signed));
379
+ const wire = {
380
+ signed,
381
+ requesterSig,
382
+ };
383
+ return {
384
+ wire,
385
+ nonceManagerKey: nonce_keys_1.DELIVERY_NONCE_KEY_SETUP,
386
+ };
387
+ }
388
+ // --------------------------------------------------------------------------
389
+ // verify (static)
390
+ // --------------------------------------------------------------------------
391
+ /**
392
+ * Verify a {@link DeliverySetupWireV1} received from the relay.
393
+ *
394
+ * Check order (first failure short-circuits, with a stable code):
395
+ *
396
+ * 1. `validateSetupWire(wire)` — top-level shape + all field-level
397
+ * invariants (positive chainId, valid addresses, bytes32 shape on
398
+ * `buyerEphemeralPubkey`, non-empty acceptedChannels, valid
399
+ * `expectedPrivacy`, positive timestamps, `expiresAt > createdAt`,
400
+ * valid signature shape). On failure: code = `setup_signature_invalid`,
401
+ * error = the validator's identifier.
402
+ *
403
+ * 2. `signed.chainId === expectedChainId` — else `setup_chain_mismatch`.
404
+ *
405
+ * 3. `signed.kernelAddress` (lowercased) === `expectedKernelAddress`
406
+ * (lowercased) — else `setup_kernel_mismatch`. This is the
407
+ * allowlist anchor: callers MUST pass the kernel address they
408
+ * trust on the target chain; passing the payload's own kernel
409
+ * would defeat the allowlist (an attacker could sign under any
410
+ * kernel).
411
+ *
412
+ * 4. `recoverSetupSigner(signed, requesterSig, expectedKernelAddress)`
413
+ * (lowercased) === `signed.signerAddress` (lowercased). NOTE:
414
+ * recovery uses `expectedKernelAddress`, NOT `signed.kernelAddress`
415
+ * — at this point we've already enforced they match in step 3,
416
+ * but using the trusted value defends against future code
417
+ * refactors that might accidentally drop step 3. On failure:
418
+ * `setup_signature_invalid`.
419
+ *
420
+ * 5. Timestamp skew: `|now - createdAt| <= SETUP_TIMESTAMP_SKEW_SEC`
421
+ * — else `setup_timestamp_skew`. Symmetric to catch both
422
+ * past-replays and forward-dated forgeries.
423
+ *
424
+ * 6. Expiry: `expiresAt > now` — else `setup_expired`. Strict `>`
425
+ * (not `>=`) so a setup exactly at its expiry second is
426
+ * considered expired.
427
+ *
428
+ * Smart-wallet equality between `signerAddress` and `requesterAddress`
429
+ * is intentionally NOT performed here — that's the verifier's
430
+ * responsibility (server side, V2 receipts pattern, DEC-10).
431
+ *
432
+ * @param wire - The wire object received from the relay.
433
+ * @param opts.expectedKernelAddress - Trusted kernel address for the
434
+ * target chain (from the verifier's allowlist).
435
+ * @param opts.expectedChainId - Trusted chainId for the target chain.
436
+ * @param opts.now - Override for the verifier's wall clock (Unix
437
+ * seconds). Tests use this to drive timestamp-skew and expiry paths
438
+ * deterministically; production callers SHOULD omit it.
439
+ * @returns `{ ok: true, signed }` on success, `{ ok: false, code, error }`
440
+ * on failure.
441
+ */
442
+ static verify(wire, opts) {
443
+ // Step 1: structural / shape validation. Any failure here we report
444
+ // under `setup_signature_invalid` since downstream signature
445
+ // recovery would either crash or silently misbehave on malformed
446
+ // input — the structured-code surface treats both as "the buyer's
447
+ // setup is unusable" without leaking validator-internal labels.
448
+ const shapeResult = (0, validate_1.validateSetupWire)(wire);
449
+ if (!shapeResult.ok) {
450
+ return {
451
+ ok: false,
452
+ code: 'setup_signature_invalid',
453
+ error: shapeResult.error,
454
+ };
455
+ }
456
+ const signed = wire.signed;
457
+ // Step 2: chainId match (trusted vs payload).
458
+ if (signed.chainId !== opts.expectedChainId) {
459
+ return {
460
+ ok: false,
461
+ code: 'setup_chain_mismatch',
462
+ error: `expected chainId ${opts.expectedChainId}, got ${signed.chainId}`,
463
+ };
464
+ }
465
+ // Step 3: kernel-address match (allowlist anchor).
466
+ const expectedKernelLc = opts.expectedKernelAddress.toLowerCase();
467
+ const payloadKernelLc = signed.kernelAddress.toLowerCase();
468
+ if (payloadKernelLc !== expectedKernelLc) {
469
+ return {
470
+ ok: false,
471
+ code: 'setup_kernel_mismatch',
472
+ error: `expected kernel ${expectedKernelLc}, got ${payloadKernelLc}`,
473
+ };
474
+ }
475
+ // Step 4: signature recovery. We pass the TRUSTED kernel address
476
+ // (already proven to equal the payload's) so future refactors of
477
+ // this function cannot accidentally let an attacker control the
478
+ // recovery domain.
479
+ let recovered;
480
+ try {
481
+ recovered = (0, eip712_1.recoverSetupSigner)(signed, wire.requesterSig, opts.expectedKernelAddress);
482
+ }
483
+ catch (e) {
484
+ const msg = e instanceof Error ? e.message : String(e);
485
+ return {
486
+ ok: false,
487
+ code: 'setup_signature_invalid',
488
+ error: msg,
489
+ };
490
+ }
491
+ if (recovered.toLowerCase() !== signed.signerAddress.toLowerCase()) {
492
+ return {
493
+ ok: false,
494
+ code: 'setup_signature_invalid',
495
+ error: `recovered signer ${recovered.toLowerCase()} does not match signed.signerAddress ${signed.signerAddress.toLowerCase()}`,
496
+ };
497
+ }
498
+ // Step 5: timestamp skew. Symmetric — both past and future.
499
+ const now = opts.now ?? secondsNow();
500
+ if (Math.abs(now - signed.createdAt) > exports.SETUP_TIMESTAMP_SKEW_SEC) {
501
+ return {
502
+ ok: false,
503
+ code: 'setup_timestamp_skew',
504
+ error: `|now (${now}) - createdAt (${signed.createdAt})| > ${exports.SETUP_TIMESTAMP_SKEW_SEC}s`,
505
+ };
506
+ }
507
+ // Step 6: expiry. Strict greater-than — setup exactly at expiresAt
508
+ // is considered expired.
509
+ if (!(signed.expiresAt > now)) {
510
+ return {
511
+ ok: false,
512
+ code: 'setup_expired',
513
+ error: `expiresAt (${signed.expiresAt}) <= now (${now})`,
514
+ };
515
+ }
516
+ return { ok: true, signed };
517
+ }
518
+ // --------------------------------------------------------------------------
519
+ // computeHash (static)
520
+ // --------------------------------------------------------------------------
521
+ /**
522
+ * Compute a stable, cross-SDK identifier for a setup wire object.
523
+ *
524
+ * The hash is `keccak256(utf8Bytes(canonicalJsonStringify(wire.signed)))`:
525
+ *
526
+ * - canonical JSON (sorted keys, no whitespace) guarantees
527
+ * byte-for-byte identical input across SDK languages,
528
+ * - `keccak256` matches the on-chain hashing convention,
529
+ * - hashing the SIGNED projection (not the full wire) excludes the
530
+ * signature and any `serverMeta` so the hash is stable across
531
+ * relay-side decoration. The signature is recoverable from the
532
+ * signed bytes; including it in the hash would make the hash
533
+ * depend on signature malleability.
534
+ *
535
+ * This is not part of the EIP-712 signature path — it is purely a
536
+ * content-addressing helper for logs, dedup sets, and cross-SDK
537
+ * test fixtures. The EIP-712 hash (the one the wallet signs) is
538
+ * computed by ethers internally and is NOT exposed here.
539
+ *
540
+ * @param wire - The wire object to hash.
541
+ * @returns 32-byte hex-encoded keccak256 hash (`0x` + 64 hex chars).
542
+ */
543
+ static computeHash(wire) {
544
+ return (0, ethers_1.keccak256)((0, ethers_1.toUtf8Bytes)((0, canonicalJson_1.canonicalJsonStringify)(wire.signed)));
545
+ }
546
+ }
547
+ exports.DeliverySetupBuilder = DeliverySetupBuilder;
548
+ // Re-affirm ethers import is used (suppresses the rare unused-symbol
549
+ // lint when the file is built with very aggressive tree-shaking
550
+ // rules; ethers stays imported above for the `Signer` type and as the
551
+ // canonical entry point even if no runtime symbol is consumed).
552
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
553
+ const _ethersUsed = ethers_1.ethers;
554
+ //# sourceMappingURL=setupBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setupBuilder.js","sourceRoot":"","sources":["../../src/delivery/setupBuilder.ts"],"names":[],"mappings":"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"}