@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.
- package/dist/builders/DeliveryProofBuilder.d.ts +224 -13
- package/dist/builders/DeliveryProofBuilder.d.ts.map +1 -1
- package/dist/builders/DeliveryProofBuilder.js +247 -13
- package/dist/builders/DeliveryProofBuilder.js.map +1 -1
- package/dist/cli/agirails.d.ts +85 -1
- package/dist/cli/agirails.d.ts.map +1 -1
- package/dist/cli/agirails.js +429 -154
- package/dist/cli/agirails.js.map +1 -1
- package/dist/cli/commands/init.d.ts +95 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +338 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/publish.d.ts +19 -0
- package/dist/cli/commands/publish.d.ts.map +1 -1
- package/dist/cli/commands/publish.js +14 -1
- package/dist/cli/commands/publish.js.map +1 -1
- package/dist/cli/commands/receipt.d.ts +70 -2
- package/dist/cli/commands/receipt.d.ts.map +1 -1
- package/dist/cli/commands/receipt.js +218 -3
- package/dist/cli/commands/receipt.js.map +1 -1
- package/dist/cli/commands/test.d.ts +77 -1
- package/dist/cli/commands/test.d.ts.map +1 -1
- package/dist/cli/commands/test.js +264 -2
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/lib/runRequest.d.ts +90 -0
- package/dist/cli/lib/runRequest.d.ts.map +1 -1
- package/dist/cli/lib/runRequest.js +300 -9
- package/dist/cli/lib/runRequest.js.map +1 -1
- package/dist/cli/lib/sentinelReflections.d.ts +111 -0
- package/dist/cli/lib/sentinelReflections.d.ts.map +1 -0
- package/dist/cli/lib/sentinelReflections.js +193 -0
- package/dist/cli/lib/sentinelReflections.js.map +1 -0
- package/dist/delivery/MockDeliveryChannel.d.ts +208 -0
- package/dist/delivery/MockDeliveryChannel.d.ts.map +1 -0
- package/dist/delivery/MockDeliveryChannel.js +445 -0
- package/dist/delivery/MockDeliveryChannel.js.map +1 -0
- package/dist/delivery/RelayDeliveryChannel.d.ts +176 -0
- package/dist/delivery/RelayDeliveryChannel.d.ts.map +1 -0
- package/dist/delivery/RelayDeliveryChannel.js +377 -0
- package/dist/delivery/RelayDeliveryChannel.js.map +1 -0
- package/dist/delivery/channel.d.ts +282 -0
- package/dist/delivery/channel.d.ts.map +1 -0
- package/dist/delivery/channel.js +76 -0
- package/dist/delivery/channel.js.map +1 -0
- package/dist/delivery/channelLog.d.ts +115 -0
- package/dist/delivery/channelLog.d.ts.map +1 -0
- package/dist/delivery/channelLog.js +94 -0
- package/dist/delivery/channelLog.js.map +1 -0
- package/dist/delivery/crypto.d.ts +312 -0
- package/dist/delivery/crypto.d.ts.map +1 -0
- package/dist/delivery/crypto.js +495 -0
- package/dist/delivery/crypto.js.map +1 -0
- package/dist/delivery/eip712.d.ts +248 -0
- package/dist/delivery/eip712.d.ts.map +1 -0
- package/dist/delivery/eip712.js +397 -0
- package/dist/delivery/eip712.js.map +1 -0
- package/dist/delivery/envelopeBuilder.d.ts +531 -0
- package/dist/delivery/envelopeBuilder.d.ts.map +1 -0
- package/dist/delivery/envelopeBuilder.js +832 -0
- package/dist/delivery/envelopeBuilder.js.map +1 -0
- package/dist/delivery/index.d.ts +53 -0
- package/dist/delivery/index.d.ts.map +1 -0
- package/dist/delivery/index.js +143 -0
- package/dist/delivery/index.js.map +1 -0
- package/dist/delivery/keys.d.ts +344 -0
- package/dist/delivery/keys.d.ts.map +1 -0
- package/dist/delivery/keys.js +513 -0
- package/dist/delivery/keys.js.map +1 -0
- package/dist/delivery/nonce-keys.d.ts +93 -0
- package/dist/delivery/nonce-keys.d.ts.map +1 -0
- package/dist/delivery/nonce-keys.js +88 -0
- package/dist/delivery/nonce-keys.js.map +1 -0
- package/dist/delivery/setupBuilder.d.ts +403 -0
- package/dist/delivery/setupBuilder.d.ts.map +1 -0
- package/dist/delivery/setupBuilder.js +554 -0
- package/dist/delivery/setupBuilder.js.map +1 -0
- package/dist/delivery/types.d.ts +722 -0
- package/dist/delivery/types.d.ts.map +1 -0
- package/dist/delivery/types.js +150 -0
- package/dist/delivery/types.js.map +1 -0
- package/dist/delivery/validate.d.ts +288 -0
- package/dist/delivery/validate.d.ts.map +1 -0
- package/dist/delivery/validate.js +648 -0
- package/dist/delivery/validate.js.map +1 -0
- package/dist/level1/Agent.d.ts +130 -0
- package/dist/level1/Agent.d.ts.map +1 -1
- package/dist/level1/Agent.js +248 -0
- package/dist/level1/Agent.js.map +1 -1
- package/dist/level1/types/Options.d.ts +62 -0
- package/dist/level1/types/Options.d.ts.map +1 -1
- package/dist/level1/types/Options.js +22 -0
- package/dist/level1/types/Options.js.map +1 -1
- package/dist/runtime/MockRuntime.d.ts +32 -0
- package/dist/runtime/MockRuntime.d.ts.map +1 -1
- package/dist/runtime/MockRuntime.js +44 -0
- package/dist/runtime/MockRuntime.js.map +1 -1
- 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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"}
|