@agirails/sdk 4.4.9 → 4.6.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.
Files changed (97) 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 +95 -0
  10. package/dist/cli/commands/init.d.ts.map +1 -1
  11. package/dist/cli/commands/init.js +338 -1
  12. package/dist/cli/commands/init.js.map +1 -1
  13. package/dist/cli/commands/publish.d.ts +19 -0
  14. package/dist/cli/commands/publish.d.ts.map +1 -1
  15. package/dist/cli/commands/publish.js +14 -1
  16. package/dist/cli/commands/publish.js.map +1 -1
  17. package/dist/cli/commands/receipt.d.ts +70 -2
  18. package/dist/cli/commands/receipt.d.ts.map +1 -1
  19. package/dist/cli/commands/receipt.js +218 -3
  20. package/dist/cli/commands/receipt.js.map +1 -1
  21. package/dist/cli/commands/test.d.ts +77 -1
  22. package/dist/cli/commands/test.d.ts.map +1 -1
  23. package/dist/cli/commands/test.js +264 -2
  24. package/dist/cli/commands/test.js.map +1 -1
  25. package/dist/cli/lib/runRequest.d.ts +90 -0
  26. package/dist/cli/lib/runRequest.d.ts.map +1 -1
  27. package/dist/cli/lib/runRequest.js +300 -9
  28. package/dist/cli/lib/runRequest.js.map +1 -1
  29. package/dist/cli/lib/sentinelReflections.d.ts +111 -0
  30. package/dist/cli/lib/sentinelReflections.d.ts.map +1 -0
  31. package/dist/cli/lib/sentinelReflections.js +193 -0
  32. package/dist/cli/lib/sentinelReflections.js.map +1 -0
  33. package/dist/delivery/MockDeliveryChannel.d.ts +208 -0
  34. package/dist/delivery/MockDeliveryChannel.d.ts.map +1 -0
  35. package/dist/delivery/MockDeliveryChannel.js +445 -0
  36. package/dist/delivery/MockDeliveryChannel.js.map +1 -0
  37. package/dist/delivery/RelayDeliveryChannel.d.ts +176 -0
  38. package/dist/delivery/RelayDeliveryChannel.d.ts.map +1 -0
  39. package/dist/delivery/RelayDeliveryChannel.js +377 -0
  40. package/dist/delivery/RelayDeliveryChannel.js.map +1 -0
  41. package/dist/delivery/channel.d.ts +282 -0
  42. package/dist/delivery/channel.d.ts.map +1 -0
  43. package/dist/delivery/channel.js +76 -0
  44. package/dist/delivery/channel.js.map +1 -0
  45. package/dist/delivery/channelLog.d.ts +115 -0
  46. package/dist/delivery/channelLog.d.ts.map +1 -0
  47. package/dist/delivery/channelLog.js +94 -0
  48. package/dist/delivery/channelLog.js.map +1 -0
  49. package/dist/delivery/crypto.d.ts +312 -0
  50. package/dist/delivery/crypto.d.ts.map +1 -0
  51. package/dist/delivery/crypto.js +495 -0
  52. package/dist/delivery/crypto.js.map +1 -0
  53. package/dist/delivery/eip712.d.ts +248 -0
  54. package/dist/delivery/eip712.d.ts.map +1 -0
  55. package/dist/delivery/eip712.js +397 -0
  56. package/dist/delivery/eip712.js.map +1 -0
  57. package/dist/delivery/envelopeBuilder.d.ts +531 -0
  58. package/dist/delivery/envelopeBuilder.d.ts.map +1 -0
  59. package/dist/delivery/envelopeBuilder.js +832 -0
  60. package/dist/delivery/envelopeBuilder.js.map +1 -0
  61. package/dist/delivery/index.d.ts +53 -0
  62. package/dist/delivery/index.d.ts.map +1 -0
  63. package/dist/delivery/index.js +143 -0
  64. package/dist/delivery/index.js.map +1 -0
  65. package/dist/delivery/keys.d.ts +344 -0
  66. package/dist/delivery/keys.d.ts.map +1 -0
  67. package/dist/delivery/keys.js +513 -0
  68. package/dist/delivery/keys.js.map +1 -0
  69. package/dist/delivery/nonce-keys.d.ts +93 -0
  70. package/dist/delivery/nonce-keys.d.ts.map +1 -0
  71. package/dist/delivery/nonce-keys.js +88 -0
  72. package/dist/delivery/nonce-keys.js.map +1 -0
  73. package/dist/delivery/setupBuilder.d.ts +403 -0
  74. package/dist/delivery/setupBuilder.d.ts.map +1 -0
  75. package/dist/delivery/setupBuilder.js +554 -0
  76. package/dist/delivery/setupBuilder.js.map +1 -0
  77. package/dist/delivery/types.d.ts +722 -0
  78. package/dist/delivery/types.d.ts.map +1 -0
  79. package/dist/delivery/types.js +150 -0
  80. package/dist/delivery/types.js.map +1 -0
  81. package/dist/delivery/validate.d.ts +288 -0
  82. package/dist/delivery/validate.d.ts.map +1 -0
  83. package/dist/delivery/validate.js +648 -0
  84. package/dist/delivery/validate.js.map +1 -0
  85. package/dist/level1/Agent.d.ts +130 -0
  86. package/dist/level1/Agent.d.ts.map +1 -1
  87. package/dist/level1/Agent.js +248 -0
  88. package/dist/level1/Agent.js.map +1 -1
  89. package/dist/level1/types/Options.d.ts +62 -0
  90. package/dist/level1/types/Options.d.ts.map +1 -1
  91. package/dist/level1/types/Options.js +22 -0
  92. package/dist/level1/types/Options.js.map +1 -1
  93. package/dist/runtime/MockRuntime.d.ts +32 -0
  94. package/dist/runtime/MockRuntime.d.ts.map +1 -1
  95. package/dist/runtime/MockRuntime.js +44 -0
  96. package/dist/runtime/MockRuntime.js.map +1 -1
  97. package/package.json +6 -1
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ /**
3
+ * AIP-16 Delivery — Per-Builder Nonce Key Constants
4
+ * ===================================================
5
+ *
6
+ * The AGIRAILS delivery surface (AIP-16 Rev 5) uses two SEPARATE nonce
7
+ * spaces, one for the buyer-signed *setup* message and one for the
8
+ * provider-signed *envelope* message. These are deliberately distinct
9
+ * from the AIP-4 delivery-proof nonce key (`agirails.delivery.v1`) and
10
+ * from each other, so that:
11
+ *
12
+ * 1. A nonce burned for a setup message cannot be replayed as an
13
+ * envelope message (per-builder replay separation).
14
+ * 2. A nonce burned for an AIP-4 delivery proof cannot collide with
15
+ * the AIP-16 setup/envelope nonce spaces (cross-feature isolation).
16
+ * 3. The on-disk persistence file (`.actp/nonces.json`) keeps a
17
+ * clean, auditable per-key monotonic counter.
18
+ *
19
+ * Why per-builder separation matters (audit context):
20
+ * ----------------------------------------------------
21
+ * The existing `NonceManager` (`src/utils/NonceManager.ts`) keys nonces
22
+ * by *message-type string*. There is no central registry of known keys
23
+ * — any string is accepted. This file therefore acts as the canonical,
24
+ * type-safe constant source for AIP-16's two delivery nonce keys, so
25
+ * call sites (setup builder, envelope builder, future replay-cache
26
+ * server) all reach for the SAME literal and the TypeScript `as const`
27
+ * narrowing prevents silent drift.
28
+ *
29
+ * Reuse, NOT replace:
30
+ * -------------------
31
+ * These constants are intended to be passed straight into the existing
32
+ * `NonceManager` API (`getNextNonce`, `getAndIncrementNonce`,
33
+ * `recordNonce`, etc.) — they introduce no new manager, no new storage
34
+ * layer, and no behavioural change. They simply give the delivery layer
35
+ * a single authoritative spelling of its two nonce-key strings.
36
+ *
37
+ * @example Use with the existing nonce manager
38
+ * ```typescript
39
+ * import { createNonceManager } from '../utils/NonceManager';
40
+ * import {
41
+ * DELIVERY_NONCE_KEY_SETUP,
42
+ * DELIVERY_NONCE_KEY_ENVELOPE,
43
+ * } from './nonce-keys';
44
+ *
45
+ * const nonces = createNonceManager({ stateDirectory: process.cwd() });
46
+ *
47
+ * // Buyer setup signing path:
48
+ * const setupNonce = await (nonces as any).getAndIncrementNonce(
49
+ * DELIVERY_NONCE_KEY_SETUP,
50
+ * );
51
+ *
52
+ * // Provider envelope signing path (independent counter):
53
+ * const envelopeNonce = await (nonces as any).getAndIncrementNonce(
54
+ * DELIVERY_NONCE_KEY_ENVELOPE,
55
+ * );
56
+ * ```
57
+ *
58
+ * Reference: AIP-16 Rev 5 §replay-protection, §nonce-spaces
59
+ *
60
+ * @module delivery/nonce-keys
61
+ */
62
+ Object.defineProperty(exports, "__esModule", { value: true });
63
+ exports.DELIVERY_NONCE_KEY_ENVELOPE = exports.DELIVERY_NONCE_KEY_SETUP = void 0;
64
+ /**
65
+ * Nonce key for buyer-signed AIP-16 delivery *setup* messages.
66
+ *
67
+ * Distinct from {@link DELIVERY_NONCE_KEY_ENVELOPE} (per-builder
68
+ * separation) and from the AIP-4 delivery-proof key
69
+ * `agirails.delivery.v1` (cross-feature separation).
70
+ *
71
+ * The `.v1` suffix matches the EIP-712 domain version for the v1
72
+ * delivery surface; a future v2 would introduce a new key string
73
+ * rather than incrementing in place.
74
+ */
75
+ exports.DELIVERY_NONCE_KEY_SETUP = 'agirails.delivery.setup.v1';
76
+ /**
77
+ * Nonce key for provider-signed AIP-16 delivery *envelope* messages.
78
+ *
79
+ * Distinct from {@link DELIVERY_NONCE_KEY_SETUP} (per-builder
80
+ * separation) and from the AIP-4 delivery-proof key
81
+ * `agirails.delivery.v1` (cross-feature separation).
82
+ *
83
+ * The `.v1` suffix matches the EIP-712 domain version for the v1
84
+ * delivery surface; a future v2 would introduce a new key string
85
+ * rather than incrementing in place.
86
+ */
87
+ exports.DELIVERY_NONCE_KEY_ENVELOPE = 'agirails.delivery.envelope.v1';
88
+ //# sourceMappingURL=nonce-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nonce-keys.js","sourceRoot":"","sources":["../../src/delivery/nonce-keys.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;;;AAEH;;;;;;;;;;GAUG;AACU,QAAA,wBAAwB,GAAG,4BAAqC,CAAC;AAE9E;;;;;;;;;;GAUG;AACU,QAAA,2BAA2B,GAAG,+BAAwC,CAAC"}
@@ -0,0 +1,403 @@
1
+ /**
2
+ * AIP-16 Delivery Surface — Buyer Setup Builder + Verifier (Phase 2b)
3
+ * =====================================================================
4
+ *
5
+ * Constructs and verifies the buyer-signed `DeliverySetupV1` payload —
6
+ * the first artifact of the AIP-16 Rev 5 delivery surface. The buyer
7
+ * (requester) posts this signed object to the delivery channel after
8
+ * the on-chain transaction reaches `COMMITTED`, declaring:
9
+ *
10
+ * - which kernel + chain the delivery is bound to,
11
+ * - which on-chain identity is acting as the requester,
12
+ * - which EOA produced the signature (smart-wallet two-step auth),
13
+ * - the buyer's ephemeral X25519 pubkey (or canonical-empty for `public`),
14
+ * - which channels the buyer accepts the envelope on,
15
+ * - the privacy posture the buyer expects,
16
+ * - and a creation timestamp + expiry for replay / staleness bounds.
17
+ *
18
+ * ## Builder shape
19
+ *
20
+ * Per the AIP-16 builder convention (and consistent with `QuoteBuilder`,
21
+ * `CounterOfferBuilder`, etc.):
22
+ *
23
+ * - `constructor(signer?, nonceManager?)` — both optional. A signer is
24
+ * REQUIRED for `build()`; `verify()` and `computeHash()` need
25
+ * neither, so verifying SDKs (relays, peer endpoints, dispute
26
+ * workers) can instantiate a no-arg builder.
27
+ *
28
+ * - `build()` is `async` because EIP-712 signing is async on real
29
+ * wallets (`Wallet.signTypedData` returns a `Promise`).
30
+ *
31
+ * - `verify()` and `computeHash()` are `static` — they take a wire
32
+ * object and need no builder state. This mirrors the existing
33
+ * `DeliveryProofBuilder` static-verify pattern.
34
+ *
35
+ * ## Smart-wallet two-step auth (DEC-10 / V2 receipts pattern)
36
+ *
37
+ * `requesterAddress` (the on-chain participant) and `signerAddress`
38
+ * (the EOA that produced the signature) are accepted SEPARATELY and
39
+ * are NOT derived from each other in this layer. When AutoWallet
40
+ * (AIP-12 Tier 1) is active, `requesterAddress` is the Smart Wallet
41
+ * contract and `signerAddress` is the controlling EOA; the SMART-WALLET
42
+ * DERIVATION (`computeSmartWalletFromSigner(signerAddress) ===
43
+ * requesterAddress`) is the SERVER'S responsibility, not the SDK's.
44
+ * Doing it here would silently couple the SDK to the Coinbase Smart
45
+ * Wallet factory ABI and break in cross-vendor flows.
46
+ *
47
+ * What the SDK DOES enforce in `build()` is the cheaper invariant:
48
+ * `signerAddress` MUST equal the address of the supplied `signer`.
49
+ * That catches the most common bug (caller passes the wrong
50
+ * `signerAddress`) without making assumptions about the participant.
51
+ *
52
+ * ## Nonce manager use
53
+ *
54
+ * The signed `DeliverySetupV1` schema has NO `nonce` field — replay
55
+ * binding is provided by `txId` (one tx per setup) and timestamps
56
+ * (`createdAt` / `expiresAt`). The `NonceManager` is still touched
57
+ * here so we have one place to hook future per-builder counters if
58
+ * the spec evolves; we use {@link DELIVERY_NONCE_KEY_SETUP} (distinct
59
+ * from the envelope key and the AIP-4 delivery-proof key) and the
60
+ * returned counter is reported back to the caller via
61
+ * {@link BuildSetupResult.nonceManagerKey} so the caller can audit
62
+ * the path was reached. Because the value is not signed, we tolerate
63
+ * a missing `NonceManager` gracefully — `build()` does NOT throw on
64
+ * undefined `nonceManager`, it simply skips the counter bump.
65
+ *
66
+ * ## Verification order
67
+ *
68
+ * `verify()` is `static` and runs checks in a fixed coarse → fine
69
+ * order, short-circuiting at the first failure with a stable
70
+ * structured code. The order is chosen so that cheap, unambiguous
71
+ * defects are reported BEFORE the more expensive signature recovery,
72
+ * but also so that signature failures are reported before policy
73
+ * failures (timestamp skew, expiry) — a forged signature is a more
74
+ * severe class of error and we want the caller to see it first.
75
+ *
76
+ * @module delivery/setupBuilder
77
+ * @see ./types — signed/wire interfaces and `BuildSetupResult`.
78
+ * @see ./eip712 — domain, types, and `recoverSetupSigner`.
79
+ * @see ./validate — `validateSetupWire` (structural validation).
80
+ * @see ./nonce-keys — `DELIVERY_NONCE_KEY_SETUP`.
81
+ */
82
+ import { type Signer } from 'ethers';
83
+ import type { NonceManager } from '../utils/NonceManager';
84
+ import { type BuildSetupResult, type DeliveryPrivacy, type DeliverySetupSignedV1, type DeliverySetupWireV1 } from './types';
85
+ /**
86
+ * Default expiry, in seconds, applied when callers omit `expiresInSec`.
87
+ *
88
+ * 3600 (1 hour) matches the negotiation-layer default and is bounded
89
+ * by the relay's accepted-setup TTL. Callers facing high-latency
90
+ * counterparties may pass an explicit larger value, but the relay
91
+ * SHOULD cap at its own policy ceiling.
92
+ */
93
+ export declare const DEFAULT_SETUP_EXPIRY_SEC = 3600;
94
+ /**
95
+ * Maximum tolerated clock-skew, in seconds, between the signed
96
+ * `createdAt` and the verifier's wall clock. Symmetric (past + future).
97
+ *
98
+ * 900s (15 min) matches the receipts-V2 freshness window and the
99
+ * AIP-3 anchor-receipt skew bound. Tighter would penalize NTP-skewed
100
+ * client machines; looser would meaningfully extend the replay
101
+ * window an attacker has to work with a leaked setup.
102
+ */
103
+ export declare const SETUP_TIMESTAMP_SKEW_SEC = 900;
104
+ /**
105
+ * Default v1 channel list applied when callers omit `acceptedChannels`.
106
+ *
107
+ * The v1 channel registry has exactly one entry; future channels MUST
108
+ * be added by callers explicitly so that channel-selection is always
109
+ * an intentional choice, not a hidden default.
110
+ */
111
+ export declare const DEFAULT_ACCEPTED_CHANNELS: readonly string[];
112
+ /**
113
+ * Replace the wall-clock implementation used inside this module.
114
+ *
115
+ * **TEST-ONLY.** Production code MUST NOT call this. The function is
116
+ * exported because Jest spies cannot intercept top-level `let`
117
+ * assignments cleanly across ESM/CJS boundaries; an explicit setter
118
+ * keeps the seam visible and grep-able.
119
+ *
120
+ * Pass `null` (or call {@link resetSecondsNowForTests}) to restore
121
+ * the real wall-clock implementation.
122
+ *
123
+ * @param impl - Replacement function returning Unix seconds, or `null`
124
+ * to restore the default real-clock implementation.
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * setSecondsNowForTests(() => 1_750_000_000);
129
+ * try {
130
+ * const { wire } = await new DeliverySetupBuilder(wallet).build(params);
131
+ * expect(wire.signed.createdAt).toBe(1_750_000_000);
132
+ * } finally {
133
+ * resetSecondsNowForTests();
134
+ * }
135
+ * ```
136
+ */
137
+ export declare function setSecondsNowForTests(impl: (() => number) | null): void;
138
+ /**
139
+ * Restore {@link secondsNow} to its default real-clock implementation.
140
+ *
141
+ * **TEST-ONLY.** Called from `afterEach` blocks; safe to call when no
142
+ * override is active.
143
+ */
144
+ export declare function resetSecondsNowForTests(): void;
145
+ /**
146
+ * Parameters accepted by {@link DeliverySetupBuilder.build}.
147
+ *
148
+ * Every field is explicit — no implicit derivation of one address
149
+ * from another. In particular, `requesterAddress` and `signerAddress`
150
+ * are passed SEPARATELY so the SDK is agnostic to which Smart Wallet
151
+ * factory the caller is using (see DEC-10 / V2 receipts pattern).
152
+ */
153
+ export interface BuildSetupParams {
154
+ /**
155
+ * On-chain transaction id this setup is bound to.
156
+ * 32-byte hex-encoded value (`0x` + 64 hex chars).
157
+ */
158
+ txId: `0x${string}`;
159
+ /**
160
+ * EVM chain id (e.g. `8453` for Base mainnet, `84532` for Base Sepolia).
161
+ * Encoded into BOTH the EIP-712 domain and the signed payload.
162
+ */
163
+ chainId: number;
164
+ /**
165
+ * Address of the ACTP kernel contract on `chainId`. Becomes the
166
+ * EIP-712 `verifyingContract`.
167
+ */
168
+ kernelAddress: `0x${string}`;
169
+ /**
170
+ * On-chain identity acting as the requester. Smart-wallet flows pass
171
+ * the Smart Wallet address here; non-smart-wallet flows pass the EOA.
172
+ * The SDK does NOT derive this from `signer` — callers must supply it.
173
+ */
174
+ requesterAddress: `0x${string}`;
175
+ /**
176
+ * EOA address that will produce the signature. MUST equal
177
+ * `await signer.getAddress()` — `build()` enforces this and throws
178
+ * a {@link DeliveryEip712Error} on mismatch.
179
+ */
180
+ signerAddress: `0x${string}`;
181
+ /**
182
+ * Buyer-side ephemeral X25519 public key as 32-byte hex.
183
+ *
184
+ * For `expectedPrivacy: "encrypted"`: a freshly generated X25519
185
+ * pubkey whose private key is held in memory by the requester
186
+ * (forward secrecy w.r.t. requester long-term keys).
187
+ *
188
+ * For `expectedPrivacy: "public"`: MUST be {@link CANONICAL_EMPTY_BYTES32}.
189
+ * `build()` enforces the canonical-empty rule on this field.
190
+ */
191
+ buyerEphemeralPubkey: `0x${string}`;
192
+ /**
193
+ * Ordered list of delivery channels the buyer is willing to accept
194
+ * the envelope on. Defaults to {@link DEFAULT_ACCEPTED_CHANNELS}
195
+ * (`["agirails-relay-v1"]`) when omitted.
196
+ */
197
+ acceptedChannels?: string[];
198
+ /**
199
+ * Privacy posture the buyer expects. The provider MUST select a
200
+ * `DeliveryScheme` consistent with this value.
201
+ */
202
+ expectedPrivacy: DeliveryPrivacy;
203
+ /**
204
+ * Validity window for this setup, in seconds. Default
205
+ * {@link DEFAULT_SETUP_EXPIRY_SEC} (3600 = 1 hour).
206
+ * `expiresAt` is computed as `createdAt + expiresInSec`.
207
+ */
208
+ expiresInSec?: number;
209
+ /**
210
+ * Override the `createdAt` timestamp. Defaults to {@link secondsNow}.
211
+ * Tests SHOULD pass an explicit value here for determinism rather
212
+ * than relying on {@link setSecondsNowForTests}; the test-clock
213
+ * setter is for callers that cannot reach into the params object
214
+ * (e.g. higher-level helpers that wrap the builder).
215
+ */
216
+ createdAt?: number;
217
+ /**
218
+ * CoinbaseSmartWallet factory nonce used to derive `requesterAddress`
219
+ * from `signerAddress`. Defaults to `0` (the first wallet per owner).
220
+ *
221
+ * H4 fix (AIP-16 Phase 3 HIGH): callers whose Smart Wallet was
222
+ * deployed at a non-zero factory nonce MUST pass that nonce here so
223
+ * the server's smart-wallet derivation lands on the correct address.
224
+ * Omitting it (or passing `0`) reproduces the legacy behavior, which
225
+ * is correct for the vast majority of callers (auto-wallet always
226
+ * deploys at nonce=0).
227
+ *
228
+ * Must be a non-negative integer in the `uint256` range; `build()`
229
+ * rejects negative or non-integer values with `BUILDER_INVALID_SMART_WALLET_NONCE`.
230
+ */
231
+ smartWalletNonce?: number;
232
+ }
233
+ /**
234
+ * Builder + verifier for AIP-16 delivery setup messages.
235
+ *
236
+ * Instances are cheap to construct and have no I/O side effects.
237
+ * `verify()` and `computeHash()` are static — call them without
238
+ * constructing an instance.
239
+ *
240
+ * @example Buyer signing flow
241
+ * ```typescript
242
+ * const builder = new DeliverySetupBuilder(wallet, nonceManager);
243
+ * const { wire } = await builder.build({
244
+ * txId,
245
+ * chainId: 84532,
246
+ * kernelAddress: KERNEL,
247
+ * requesterAddress: SMART_WALLET,
248
+ * signerAddress: EOA,
249
+ * buyerEphemeralPubkey: '0x' + 'aa'.repeat(32),
250
+ * expectedPrivacy: 'encrypted',
251
+ * });
252
+ * await postToRelay(wire);
253
+ * ```
254
+ *
255
+ * @example Provider verification flow
256
+ * ```typescript
257
+ * const result = DeliverySetupBuilder.verify(wire, {
258
+ * expectedKernelAddress: KERNEL,
259
+ * expectedChainId: 84532,
260
+ * });
261
+ * if (!result.ok) {
262
+ * throw new Error(`Setup verification failed: ${result.code}`);
263
+ * }
264
+ * const setup = result.signed;
265
+ * ```
266
+ */
267
+ export declare class DeliverySetupBuilder {
268
+ private readonly signer?;
269
+ private readonly nonceManager?;
270
+ /**
271
+ * Construct a new builder.
272
+ *
273
+ * @param signer - EOA signer required for {@link build}. Pass `undefined`
274
+ * to construct a verify-only instance; `verify()` and `computeHash()`
275
+ * are static and do not need a builder instance at all, but a
276
+ * no-arg constructor is supported for symmetry with peer builders.
277
+ * @param nonceManager - Optional nonce manager. The v1 setup schema
278
+ * has no `nonce` field, so this is purely an audit hook today;
279
+ * when supplied, `build()` calls `getNextNonce(DELIVERY_NONCE_KEY_SETUP)`
280
+ * to advance the counter. Missing manager is tolerated.
281
+ */
282
+ constructor(signer?: Signer, nonceManager?: NonceManager);
283
+ /**
284
+ * Construct, sign, and return a {@link DeliverySetupWireV1}.
285
+ *
286
+ * Pre-checks:
287
+ * - signer MUST be present (throws `BUILDER_NO_SIGNER` otherwise).
288
+ * - `signerAddress` MUST equal `await signer.getAddress()`
289
+ * (throws `BUILDER_SIGNER_ADDRESS_MISMATCH` otherwise).
290
+ * - For `expectedPrivacy: "public"`, `buyerEphemeralPubkey` MUST equal
291
+ * {@link CANONICAL_EMPTY_BYTES32}.
292
+ * - For `expectedPrivacy: "encrypted"`, `buyerEphemeralPubkey` MUST NOT
293
+ * be {@link CANONICAL_EMPTY_BYTES32} (a zero X25519 public key is
294
+ * rejected by RFC 7748 §6.1 anyway, but we surface a clearer error).
295
+ * - `expiresInSec` (when supplied) must be a positive integer.
296
+ *
297
+ * Signing:
298
+ * - Uses `signer.signTypedData(domain, types, signed)` with the
299
+ * canonical delivery EIP-712 domain anchored to `kernelAddress`.
300
+ *
301
+ * Nonce manager:
302
+ * - When supplied, `getNextNonce(DELIVERY_NONCE_KEY_SETUP)` is called
303
+ * purely for audit / future-compat. The returned counter is NOT
304
+ * encoded into the signed payload (the v1 schema has no nonce
305
+ * field) and the caller MAY ignore `nonceManagerKey` in the result.
306
+ *
307
+ * @param params - {@link BuildSetupParams}.
308
+ * @returns A {@link BuildSetupResult} carrying the signed wire object
309
+ * and the nonce-manager key that was touched (always
310
+ * {@link DELIVERY_NONCE_KEY_SETUP} for v1).
311
+ * @throws {DeliveryEip712Error} on signer absence, signer/address
312
+ * mismatch, or canonical-empty rule violation.
313
+ */
314
+ build(params: BuildSetupParams): Promise<BuildSetupResult>;
315
+ /**
316
+ * Verify a {@link DeliverySetupWireV1} received from the relay.
317
+ *
318
+ * Check order (first failure short-circuits, with a stable code):
319
+ *
320
+ * 1. `validateSetupWire(wire)` — top-level shape + all field-level
321
+ * invariants (positive chainId, valid addresses, bytes32 shape on
322
+ * `buyerEphemeralPubkey`, non-empty acceptedChannels, valid
323
+ * `expectedPrivacy`, positive timestamps, `expiresAt > createdAt`,
324
+ * valid signature shape). On failure: code = `setup_signature_invalid`,
325
+ * error = the validator's identifier.
326
+ *
327
+ * 2. `signed.chainId === expectedChainId` — else `setup_chain_mismatch`.
328
+ *
329
+ * 3. `signed.kernelAddress` (lowercased) === `expectedKernelAddress`
330
+ * (lowercased) — else `setup_kernel_mismatch`. This is the
331
+ * allowlist anchor: callers MUST pass the kernel address they
332
+ * trust on the target chain; passing the payload's own kernel
333
+ * would defeat the allowlist (an attacker could sign under any
334
+ * kernel).
335
+ *
336
+ * 4. `recoverSetupSigner(signed, requesterSig, expectedKernelAddress)`
337
+ * (lowercased) === `signed.signerAddress` (lowercased). NOTE:
338
+ * recovery uses `expectedKernelAddress`, NOT `signed.kernelAddress`
339
+ * — at this point we've already enforced they match in step 3,
340
+ * but using the trusted value defends against future code
341
+ * refactors that might accidentally drop step 3. On failure:
342
+ * `setup_signature_invalid`.
343
+ *
344
+ * 5. Timestamp skew: `|now - createdAt| <= SETUP_TIMESTAMP_SKEW_SEC`
345
+ * — else `setup_timestamp_skew`. Symmetric to catch both
346
+ * past-replays and forward-dated forgeries.
347
+ *
348
+ * 6. Expiry: `expiresAt > now` — else `setup_expired`. Strict `>`
349
+ * (not `>=`) so a setup exactly at its expiry second is
350
+ * considered expired.
351
+ *
352
+ * Smart-wallet equality between `signerAddress` and `requesterAddress`
353
+ * is intentionally NOT performed here — that's the verifier's
354
+ * responsibility (server side, V2 receipts pattern, DEC-10).
355
+ *
356
+ * @param wire - The wire object received from the relay.
357
+ * @param opts.expectedKernelAddress - Trusted kernel address for the
358
+ * target chain (from the verifier's allowlist).
359
+ * @param opts.expectedChainId - Trusted chainId for the target chain.
360
+ * @param opts.now - Override for the verifier's wall clock (Unix
361
+ * seconds). Tests use this to drive timestamp-skew and expiry paths
362
+ * deterministically; production callers SHOULD omit it.
363
+ * @returns `{ ok: true, signed }` on success, `{ ok: false, code, error }`
364
+ * on failure.
365
+ */
366
+ static verify(wire: DeliverySetupWireV1, opts: {
367
+ expectedKernelAddress: string;
368
+ expectedChainId: number;
369
+ now?: number;
370
+ }): {
371
+ ok: true;
372
+ signed: DeliverySetupSignedV1;
373
+ } | {
374
+ ok: false;
375
+ code: string;
376
+ error: string;
377
+ };
378
+ /**
379
+ * Compute a stable, cross-SDK identifier for a setup wire object.
380
+ *
381
+ * The hash is `keccak256(utf8Bytes(canonicalJsonStringify(wire.signed)))`:
382
+ *
383
+ * - canonical JSON (sorted keys, no whitespace) guarantees
384
+ * byte-for-byte identical input across SDK languages,
385
+ * - `keccak256` matches the on-chain hashing convention,
386
+ * - hashing the SIGNED projection (not the full wire) excludes the
387
+ * signature and any `serverMeta` so the hash is stable across
388
+ * relay-side decoration. The signature is recoverable from the
389
+ * signed bytes; including it in the hash would make the hash
390
+ * depend on signature malleability.
391
+ *
392
+ * This is not part of the EIP-712 signature path — it is purely a
393
+ * content-addressing helper for logs, dedup sets, and cross-SDK
394
+ * test fixtures. The EIP-712 hash (the one the wallet signs) is
395
+ * computed by ethers internally and is NOT exposed here.
396
+ *
397
+ * @param wire - The wire object to hash.
398
+ * @returns 32-byte hex-encoded keccak256 hash (`0x` + 64 hex chars).
399
+ */
400
+ static computeHash(wire: DeliverySetupWireV1): string;
401
+ }
402
+ export type { BuildSetupResult } from './types';
403
+ //# sourceMappingURL=setupBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setupBuilder.d.ts","sourceRoot":"","sources":["../../src/delivery/setupBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AAEH,OAAO,EAIL,KAAK,MAAM,EACZ,MAAM,QAAQ,CAAC;AAGhB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAS1D,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACzB,MAAM,SAAS,CAAC;AAOjB;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAE5C;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAE7C,CAAC;AA2CX;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,IAAI,GAAG,IAAI,CAMvE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAMD;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IAEpB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,aAAa,EAAE,KAAK,MAAM,EAAE,CAAC;IAE7B;;;;OAIG;IACH,gBAAgB,EAAE,KAAK,MAAM,EAAE,CAAC;IAEhC;;;;OAIG;IACH,aAAa,EAAE,KAAK,MAAM,EAAE,CAAC;IAE7B;;;;;;;;;OASG;IACH,oBAAoB,EAAE,KAAK,MAAM,EAAE,CAAC;IAEpC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B;;;OAGG;IACH,eAAe,EAAE,eAAe,CAAC;IAEjC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;;;;;;OAaG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAe;IAE7C;;;;;;;;;;;OAWG;gBACS,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY;IASxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACG,KAAK,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAkJhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkDG;IACH,MAAM,CAAC,MAAM,CACX,IAAI,EAAE,mBAAmB,EACzB,IAAI,EAAE;QACJ,qBAAqB,EAAE,MAAM,CAAC;QAC9B,eAAe,EAAE,MAAM,CAAC;QACxB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,GAEC;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,qBAAqB,CAAA;KAAE,GAC3C;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IA4F9C;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM;CAGtD;AAWD,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC"}