@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,722 @@
1
+ /**
2
+ * AIP-16 Delivery Surface — Type Definitions (Phase 2a Foundation)
3
+ * =================================================================
4
+ *
5
+ * Type-level contract for the AGIRAILS delivery layer (AIP-16 Rev 5).
6
+ *
7
+ * The delivery surface is the post-COMMITTED / pre-DELIVERED protocol
8
+ * step in which the provider hands the requester the *actual* deliverable
9
+ * (the bytes the requester paid for), with cryptographic guarantees of
10
+ * authenticity, integrity, and (optionally) confidentiality.
11
+ *
12
+ * Two privacy modes are supported in v1:
13
+ *
14
+ * - `public-v1` — body is plaintext UTF-8 JSON. Anyone observing
15
+ * the channel can read it. Useful for public
16
+ * deliverables (open data, public model outputs).
17
+ * - `x25519-aes256gcm-v1` — body is AES-256-GCM ciphertext, key derived
18
+ * via X25519 ECDH + HKDF-SHA256 between provider
19
+ * and requester ephemeral keys. End-to-end
20
+ * confidential.
21
+ *
22
+ * The delivery surface is composed of two signed objects:
23
+ *
24
+ * 1. **DeliverySetup** — signed by the *requester* (buyer). Posted to the
25
+ * channel after COMMITTED. Declares the buyer's ephemeral pubkey,
26
+ * accepted channels, and expected privacy mode.
27
+ *
28
+ * 2. **DeliveryEnvelope** — signed by the *provider* (seller). Carries
29
+ * the body bytes (plaintext or ciphertext), AEAD nonce + tag, and
30
+ * `payloadHash = keccak256(bodyBytes)` for on-chain anchoring.
31
+ *
32
+ * Both objects use a *signed projection* + *wire envelope* split:
33
+ * - The *signed* object is the canonical EIP-712 payload — exact byte
34
+ * ordering and field layout matter for cross-SDK interoperability.
35
+ * - The *wire* object wraps it with the signature and optional relay
36
+ * server metadata for transport.
37
+ *
38
+ * ## Critical conventions
39
+ *
40
+ * - **EIP-712 domain**: ALWAYS `{name: "AGIRAILS Delivery", version: "1",
41
+ * chainId, verifyingContract: kernelAddress}`. Domain reuse across
42
+ * AIP features (negotiation, receipts) would enable cross-feature
43
+ * signature replay.
44
+ *
45
+ * - **Canonical empty values**: For `scheme: "public-v1"`, the encryption
46
+ * fields (`providerEphemeralPubkey`, `nonce`, `tag`) MUST be canonical
47
+ * empty (zero-filled bytes of the correct length), NOT omitted. EIP-712
48
+ * has no concept of an "absent" field — the type schema is fixed and
49
+ * every field has a value.
50
+ *
51
+ * - **Smart wallet two-step auth**: `signerAddress` is the EOA that
52
+ * produced the signature; `requesterAddress` / `providerAddress` is the
53
+ * on-chain participant (which may be a Smart Wallet — a contract that
54
+ * does not itself sign). Verification recovers the EOA from the
55
+ * signature, then checks either equality with the participant OR that
56
+ * the participant is the Smart Wallet derived from the EOA.
57
+ *
58
+ * - **Address comparisons** are always case-insensitive (.toLowerCase()).
59
+ *
60
+ * - **Field order in EIP-712 types is IMMUTABLE.** Any reordering of
61
+ * fields in `DeliverySetupSignedV1` or `DeliveryEnvelopeSignedV1`
62
+ * constitutes a breaking SDK change because both client and server
63
+ * must encode byte-for-byte identical typed-data structures.
64
+ *
65
+ * @module delivery/types
66
+ * @see {@link https://eips.ethereum.org/EIPS/eip-712 EIP-712 Typed Structured Data}
67
+ * @see {@link https://www.rfc-editor.org/rfc/rfc5869 RFC 5869 — HKDF}
68
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc7748 RFC 7748 — X25519}
69
+ */
70
+ /**
71
+ * Cryptographic scheme used to protect (or not protect) the envelope body.
72
+ *
73
+ * - `"x25519-aes256gcm-v1"` — End-to-end encrypted. The provider derives
74
+ * a shared secret with the buyer's ephemeral X25519 pubkey, runs
75
+ * HKDF-SHA256 to produce a 32-byte symmetric key, then encrypts the
76
+ * plaintext body with AES-256-GCM using a 12-byte nonce. The 16-byte
77
+ * GCM authentication tag is carried separately in the signed
78
+ * projection so it is bound to the EIP-712 signature.
79
+ *
80
+ * - `"public-v1"` — No confidentiality. The envelope body is plaintext
81
+ * UTF-8 JSON. The encryption fields in the signed projection are set
82
+ * to canonical empty values (zero bytes of the appropriate length).
83
+ * Used for deliverables that are intentionally public or where the
84
+ * sensitivity does not warrant encryption overhead.
85
+ *
86
+ * Future versions of AIP-16 may add additional schemes (e.g. an XChaCha20
87
+ * variant) — those will be `*-v2` discriminants. The v1 spec is locked.
88
+ */
89
+ export type DeliveryScheme = 'x25519-aes256gcm-v1' | 'public-v1';
90
+ /**
91
+ * Transport / placement mode for the envelope.
92
+ *
93
+ * - `"channel"` — Envelope is posted to a delivery channel (e.g. the
94
+ * AGIRAILS relay) and pulled by the requester. The channel id is
95
+ * declared in `acceptedChannels` of the setup.
96
+ *
97
+ * - `"none"` — No envelope is delivered through this surface. Typically
98
+ * used for sentinel / smoke-test flows where settlement is the only
99
+ * outcome being exercised.
100
+ *
101
+ * NOTE: AIP-17 introduces a `"reference"` mode (envelope carries a CID
102
+ * pointer to externally-stored bytes); that mode is not part of the v1
103
+ * AIP-16 surface and is intentionally omitted here.
104
+ */
105
+ export type DeliveryMode = 'channel' | 'none';
106
+ /**
107
+ * High-level privacy posture the requester *expects* in the buyer setup.
108
+ *
109
+ * - `"encrypted"` — Requester expects an `x25519-aes256gcm-v1` envelope.
110
+ * If the provider sends `public-v1`, the requester SHOULD reject with
111
+ * `setup_signer_role_mismatch` / privacy-policy violation.
112
+ *
113
+ * - `"public"` — Requester accepts (or requires) a `public-v1` envelope.
114
+ *
115
+ * `expectedPrivacy` is an out-of-band hint the requester signs into the
116
+ * setup; the provider is responsible for honoring it when selecting a
117
+ * `DeliveryScheme`. The two enums are intentionally separate so that
118
+ * future scheme additions do not require reshaping the setup contract.
119
+ */
120
+ export type DeliveryPrivacy = 'encrypted' | 'public';
121
+ /**
122
+ * Role of a participant within a single delivery exchange.
123
+ *
124
+ * - `"provider"` — The agent producing and signing the envelope.
125
+ * - `"requester"` — The agent producing and signing the setup.
126
+ *
127
+ * Used in verification routines to disambiguate which signer-role check
128
+ * applies (the signer must be acting in the role declared in the
129
+ * surrounding payload).
130
+ */
131
+ export type ParticipantRole = 'provider' | 'requester';
132
+ /**
133
+ * Networks on which the delivery surface is exercised.
134
+ *
135
+ * - `"base-sepolia"` — Base L2 Sepolia testnet (chainId 84532).
136
+ * - `"base-mainnet"` — Base L2 mainnet (chainId 8453).
137
+ * - `"mock"` — In-process MockRuntime; no real on-chain anchoring.
138
+ *
139
+ * The network is used to look up the correct kernel address and chainId
140
+ * when constructing the EIP-712 domain. Builders MUST validate that
141
+ * `chainId` in the signed payload matches the expected chain for the
142
+ * network in use; mismatches produce `envelope_chain_mismatch` /
143
+ * `setup_chain_mismatch` errors.
144
+ */
145
+ export type DeliveryNetwork = 'base-sepolia' | 'base-mainnet' | 'mock';
146
+ /**
147
+ * Canonical EIP-712 payload signed by the *requester* (buyer) at the
148
+ * start of the delivery exchange.
149
+ *
150
+ * The setup is posted to the delivery channel (or otherwise made
151
+ * available to the provider) after the transaction reaches `COMMITTED`.
152
+ * It tells the provider:
153
+ *
154
+ * - Which kernel + chain the delivery is bound to (`chainId`,
155
+ * `kernelAddress`, `txId`).
156
+ * - Which on-chain identity is acting as the requester
157
+ * (`requesterAddress`) and which EOA will sign on its behalf
158
+ * (`signerAddress`).
159
+ * - The buyer's ephemeral X25519 pubkey (for encrypted schemes), or a
160
+ * canonical-empty value for `public-v1`.
161
+ * - Which channels the buyer accepts for envelope delivery.
162
+ * - The privacy posture the buyer expects.
163
+ * - A creation timestamp and an expiry timestamp for replay / staleness
164
+ * bounds.
165
+ *
166
+ * ## EIP-712 schema (signed)
167
+ *
168
+ * ```
169
+ * DeliverySetupV1 (
170
+ * uint8 version,
171
+ * bytes32 txId,
172
+ * uint256 chainId,
173
+ * address kernelAddress,
174
+ * address requesterAddress,
175
+ * address signerAddress,
176
+ * bytes32 buyerEphemeralPubkey,
177
+ * string[] acceptedChannels,
178
+ * string expectedPrivacy,
179
+ * uint64 createdAt,
180
+ * uint64 expiresAt
181
+ * )
182
+ * ```
183
+ *
184
+ * The field order shown above is IMMUTABLE — changing it is a breaking
185
+ * SDK and Platform change.
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * const signed: DeliverySetupSignedV1 = {
190
+ * version: 1,
191
+ * txId: '0xabc…',
192
+ * chainId: 84532,
193
+ * kernelAddress: '0x469C…',
194
+ * requesterAddress: '0xRequesterSmartWallet…',
195
+ * signerAddress: '0xRequesterEOA…',
196
+ * buyerEphemeralPubkey: '0x' + 'aa'.repeat(32),
197
+ * acceptedChannels: ['agirails-relay-v1'],
198
+ * expectedPrivacy: 'encrypted',
199
+ * createdAt: 1730000000,
200
+ * expiresAt: 1730000600,
201
+ * };
202
+ * ```
203
+ */
204
+ export interface DeliverySetupSignedV1 {
205
+ /** Protocol version literal. Always `1` for the v1 setup schema. */
206
+ version: 1;
207
+ /**
208
+ * On-chain transaction id this delivery setup is bound to.
209
+ * `bytes32` hex-encoded. Used as the HKDF salt when deriving the
210
+ * symmetric key for encrypted schemes (binds the key to a specific tx).
211
+ */
212
+ txId: `0x${string}`;
213
+ /**
214
+ * EVM chain id (e.g. 8453 for Base mainnet, 84532 for Base Sepolia).
215
+ * Encoded into the EIP-712 domain and ALSO into the signed payload —
216
+ * defense-in-depth against cross-chain replay if a wallet signs without
217
+ * properly enforcing domain chainId.
218
+ */
219
+ chainId: number;
220
+ /**
221
+ * Address of the ACTP kernel contract on `chainId`. Also the EIP-712
222
+ * `verifyingContract`. Relays validate this against an allowlist to
223
+ * reject setups bound to unknown kernels.
224
+ */
225
+ kernelAddress: `0x${string}`;
226
+ /**
227
+ * On-chain identity acting as the requester. When AutoWallet (AIP-12
228
+ * Tier 1) is active this is a Smart Wallet contract address — the
229
+ * contract itself cannot sign EIP-712 messages, so signature recovery
230
+ * yields the controlling EOA (`signerAddress`).
231
+ */
232
+ requesterAddress: `0x${string}`;
233
+ /**
234
+ * EOA that produced the signature on this payload. For non-smart-wallet
235
+ * flows this equals `requesterAddress`. For smart-wallet flows it is
236
+ * the controlling EOA; verification then checks that
237
+ * `computeSmartWalletFromSigner(signerAddress) === requesterAddress`.
238
+ */
239
+ signerAddress: `0x${string}`;
240
+ /**
241
+ * Buyer-side ephemeral X25519 public key, 32 bytes hex-encoded.
242
+ *
243
+ * For `expectedPrivacy: "encrypted"` this is a freshly generated
244
+ * X25519 pubkey whose corresponding private key is held only in
245
+ * memory by the requester. For `expectedPrivacy: "public"` (and
246
+ * therefore `scheme: "public-v1"`) this MUST be `CANONICAL_EMPTY_BYTES32`
247
+ * — NOT omitted. EIP-712 has no "absent field" concept.
248
+ */
249
+ buyerEphemeralPubkey: `0x${string}`;
250
+ /**
251
+ * Ordered list of delivery channels the buyer is willing to accept the
252
+ * envelope on. In v1 the only registered channel is `"agirails-relay-v1"`.
253
+ * Future channels (e.g. self-hosted relays, libp2p) will declare their
254
+ * own identifiers.
255
+ */
256
+ acceptedChannels: string[];
257
+ /**
258
+ * Privacy posture the buyer expects the provider to use. The provider
259
+ * MUST select a `DeliveryScheme` consistent with this value:
260
+ * - `"encrypted"` → `x25519-aes256gcm-v1`
261
+ * - `"public"` → `public-v1`
262
+ */
263
+ expectedPrivacy: DeliveryPrivacy;
264
+ /**
265
+ * Unix seconds at which the setup was created (NOT signed). Encoded
266
+ * into the EIP-712 payload so the provider can detect clock skew or
267
+ * stale setups.
268
+ */
269
+ createdAt: number;
270
+ /**
271
+ * Unix seconds after which this setup is no longer valid. The provider
272
+ * MUST reject setups where `now > expiresAt`. Typical values are
273
+ * `createdAt + 600` (10 min) to bound replay windows.
274
+ */
275
+ expiresAt: number;
276
+ /**
277
+ * CoinbaseSmartWallet factory nonce used to derive `requesterAddress`
278
+ * from `signerAddress`. Defaults to `0` (the first wallet per owner),
279
+ * matching the SDK's auto-wallet behavior.
280
+ *
281
+ * H4 fix (AIP-16 Phase 3 HIGH): users whose Smart Wallet was deployed
282
+ * at a non-zero factory nonce (e.g. they redeployed at nonce=1 after
283
+ * losing access to their nonce=0 keys) previously got permanently
284
+ * locked out with `signer_role_mismatch`. By signing the nonce into
285
+ * the payload, the server can derive the correct Smart Wallet address
286
+ * via `getAddress(owners, smartWalletNonce)` instead of always
287
+ * assuming `0`.
288
+ *
289
+ * Appended to the EIP-712 field list (NOT inserted) so existing
290
+ * positional encodings remain stable across SDK/Platform mirrors.
291
+ *
292
+ * Static field is OPTIONAL on the TypeScript interface for backwards
293
+ * compatibility with pre-H4 fixtures: when present the value MUST be
294
+ * a non-negative integer; when absent the verifier treats it as `0`
295
+ * and signs/recovers under `smartWalletNonce: 0`. Newly built
296
+ * payloads from `DeliverySetupBuilder.build()` always include the
297
+ * field explicitly (defaulting to `0` from `BuildSetupParams`).
298
+ */
299
+ smartWalletNonce?: number;
300
+ }
301
+ /**
302
+ * Wire envelope wrapping a {@link DeliverySetupSignedV1} for transport
303
+ * over the delivery channel.
304
+ *
305
+ * The wire form is what is POSTed to the channel; the relay may decorate
306
+ * it with `serverMeta` (received timestamp + relay id) when serving it
307
+ * back to the provider.
308
+ *
309
+ * The signed projection is preserved verbatim — clients MUST NOT
310
+ * re-serialize or normalize it after signing, since EIP-712 signatures
311
+ * are over the structured data, not its JSON encoding, but tampering
312
+ * with the projection invalidates the contract between signed bytes and
313
+ * the cleartext the relay/provider can read.
314
+ */
315
+ export interface DeliverySetupWireV1 {
316
+ /** Canonical signed projection. */
317
+ signed: DeliverySetupSignedV1;
318
+ /**
319
+ * Requester EIP-712 signature over `signed` using the
320
+ * `AGIRAILS Delivery` domain, type `DeliverySetupV1`.
321
+ *
322
+ * Recovers to `signed.signerAddress` (which is then matched against
323
+ * `signed.requesterAddress` via direct or smart-wallet equality).
324
+ */
325
+ requesterSig: `0x${string}`;
326
+ /**
327
+ * Optional server-added metadata (set by the relay on read, not by the
328
+ * signer). Never part of the signed payload — informational only.
329
+ */
330
+ serverMeta?: {
331
+ /** ISO 8601 timestamp at which the relay received the setup. */
332
+ receivedAt: string;
333
+ /** Identifier of the relay that received and is now serving the setup. */
334
+ relayId: string;
335
+ };
336
+ }
337
+ /**
338
+ * Canonical EIP-712 payload signed by the *provider* when delivering
339
+ * the actual bytes (or ciphertext) the requester paid for.
340
+ *
341
+ * The envelope is the load-bearing artifact of the entire delivery
342
+ * surface: it binds, in a single signed structure, the on-chain
343
+ * transaction id, the chosen cryptographic scheme, the AEAD parameters
344
+ * (when applicable), and a hash of the exact body bytes the requester
345
+ * will receive. Verification on the receiving side reconstructs
346
+ * `payloadHash = keccak256(bodyBytes)` from the wire body and compares.
347
+ *
348
+ * ## EIP-712 schema (signed)
349
+ *
350
+ * ```
351
+ * DeliveryEnvelopeV1 (
352
+ * uint8 version,
353
+ * bytes32 txId,
354
+ * uint256 chainId,
355
+ * address kernelAddress,
356
+ * address providerAddress,
357
+ * address signerAddress,
358
+ * string scheme,
359
+ * bytes32 providerEphemeralPubkey,
360
+ * bytes12 nonce,
361
+ * bytes32 payloadHash,
362
+ * bytes16 tag,
363
+ * uint64 createdAt
364
+ * )
365
+ * ```
366
+ *
367
+ * Field order is IMMUTABLE.
368
+ *
369
+ * ## Canonical-empty values
370
+ *
371
+ * For `scheme: "public-v1"` the following fields MUST be canonical empty:
372
+ * - `providerEphemeralPubkey` → {@link CANONICAL_EMPTY_BYTES32}
373
+ * - `nonce` → {@link CANONICAL_EMPTY_BYTES12}
374
+ * - `tag` → {@link CANONICAL_EMPTY_BYTES16}
375
+ *
376
+ * Verifiers MUST reject envelopes where the scheme/empty-value invariant
377
+ * is violated (e.g. `public-v1` with a non-zero `nonce`).
378
+ */
379
+ export interface DeliveryEnvelopeSignedV1 {
380
+ /** Protocol version literal. Always `1` for the v1 envelope schema. */
381
+ version: 1;
382
+ /**
383
+ * On-chain transaction id this envelope is bound to. Must equal the
384
+ * `txId` in the corresponding setup. `bytes32` hex-encoded.
385
+ */
386
+ txId: `0x${string}`;
387
+ /**
388
+ * EVM chain id. Must equal the chainId on which the kernel contract
389
+ * lives and match the EIP-712 domain.
390
+ */
391
+ chainId: number;
392
+ /** Address of the ACTP kernel contract; also EIP-712 `verifyingContract`. */
393
+ kernelAddress: `0x${string}`;
394
+ /**
395
+ * On-chain identity acting as the provider. When AutoWallet is active
396
+ * this is a Smart Wallet contract — see `signerAddress` below.
397
+ */
398
+ providerAddress: `0x${string}`;
399
+ /**
400
+ * EOA that produced the signature. For non-smart-wallet flows this
401
+ * equals `providerAddress`. For smart-wallet flows verification
402
+ * checks `computeSmartWalletFromSigner(signerAddress) === providerAddress`.
403
+ */
404
+ signerAddress: `0x${string}`;
405
+ /** Cryptographic scheme used for the body. See {@link DeliveryScheme}. */
406
+ scheme: DeliveryScheme;
407
+ /**
408
+ * Provider-side ephemeral X25519 public key, 32 bytes hex-encoded.
409
+ *
410
+ * For `scheme: "x25519-aes256gcm-v1"`: a freshly generated X25519
411
+ * pubkey; the receiver runs ECDH with their own ephemeral secret
412
+ * to derive the shared secret. Provider's ephemeral private key is
413
+ * discarded after sealing (forward secrecy w.r.t. provider long-term keys).
414
+ *
415
+ * For `scheme: "public-v1"`: MUST be {@link CANONICAL_EMPTY_BYTES32}.
416
+ */
417
+ providerEphemeralPubkey: `0x${string}`;
418
+ /**
419
+ * AES-GCM nonce (a.k.a. IV), 12 bytes hex-encoded.
420
+ *
421
+ * For `scheme: "x25519-aes256gcm-v1"`: 12 random bytes, unique per
422
+ * envelope (re-using a nonce under the same key destroys AES-GCM's
423
+ * security). The 12-byte length is the GCM standard.
424
+ *
425
+ * For `scheme: "public-v1"`: MUST be {@link CANONICAL_EMPTY_BYTES12}.
426
+ */
427
+ nonce: `0x${string}`;
428
+ /**
429
+ * `keccak256` hash of the exact bytes carried in the wire envelope's
430
+ * `body` field, 32 bytes hex-encoded.
431
+ *
432
+ * - For `public-v1`: hash of the UTF-8 plaintext bytes.
433
+ * - For `x25519-aes256gcm-v1`: hash of the raw ciphertext bytes
434
+ * (i.e. the bytes decoded from the base64 `body`).
435
+ *
436
+ * Verifiers MUST recompute and compare; mismatch → `envelope_payload_hash_mismatch`.
437
+ * This hash is also what is anchored on-chain (in AIP-3 receipts) so
438
+ * the entire chain of trust is body-hash → envelope sig → kernel.
439
+ */
440
+ payloadHash: `0x${string}`;
441
+ /**
442
+ * AES-GCM authentication tag, 16 bytes hex-encoded.
443
+ *
444
+ * For `scheme: "x25519-aes256gcm-v1"`: the GCM tag produced by the
445
+ * encryption. It is carried separately (rather than appended to the
446
+ * ciphertext) so that it is bound to the EIP-712 signature directly —
447
+ * tampering with the tag without also producing a fresh signature is
448
+ * detectable on signature recovery.
449
+ *
450
+ * For `scheme: "public-v1"`: MUST be {@link CANONICAL_EMPTY_BYTES16}.
451
+ */
452
+ tag: `0x${string}`;
453
+ /**
454
+ * Unix seconds at which the envelope was created. The receiver MAY
455
+ * enforce a max skew between this and their wall clock to bound
456
+ * replay windows; out-of-bounds → `envelope_timestamp_skew`.
457
+ */
458
+ createdAt: number;
459
+ /**
460
+ * CoinbaseSmartWallet factory nonce used to derive `providerAddress`
461
+ * from `signerAddress`. Defaults to `0` (the first wallet per owner).
462
+ *
463
+ * H4 fix (AIP-16 Phase 3 HIGH): symmetric to `DeliverySetupSignedV1.smartWalletNonce`
464
+ * — providers whose Smart Wallet was deployed at a non-zero factory
465
+ * nonce can declare it here so the server's smart-wallet derivation
466
+ * lands on the correct address.
467
+ *
468
+ * Appended to the EIP-712 field list (NOT inserted) so existing
469
+ * positional encodings remain stable across SDK/Platform mirrors.
470
+ *
471
+ * Optional on the TypeScript interface for backwards compatibility
472
+ * with pre-H4 fixtures; absent → treated as `0` by the verifier.
473
+ * Newly built envelopes always include the field explicitly.
474
+ */
475
+ smartWalletNonce?: number;
476
+ }
477
+ /**
478
+ * Wire envelope around a {@link DeliveryEnvelopeSignedV1} for transport.
479
+ *
480
+ * Contains:
481
+ * - the signed projection (verbatim),
482
+ * - the body (plaintext UTF-8 JSON for `public-v1`, 0x-prefixed
483
+ * lowercase hex of ciphertext for `x25519-aes256gcm-v1`),
484
+ * - the provider's EIP-712 signature,
485
+ * - optional relay server metadata.
486
+ *
487
+ * The body encoding is scheme-dependent (FIX-1, AIP-16 Phase 3.5):
488
+ *
489
+ * - `public-v1`: `body` is the plaintext UTF-8 JSON string itself —
490
+ * `JSON.stringify(payload)`, NOT hex. Hash to verify =
491
+ * `keccak256(utf8Bytes(body))`. The Platform verifier
492
+ * (`lib/delivery/auth.ts`) computes the same digest directly on
493
+ * the wire body. Hex-wrapping the plaintext would make the verifier
494
+ * hash the hex string as UTF-8 — a different digest — and every
495
+ * public envelope would be rejected with `payload_hash_mismatch`.
496
+ * - `x25519-aes256gcm-v1`: `body` is 0x-prefixed lowercase HEX of the
497
+ * raw ciphertext bytes (NOT base64 — AIP-16 standardizes on hex
498
+ * for binary byte-bearing fields). Hash to verify is
499
+ * `keccak256(hexDecode(body))`; decode hex → raw ciphertext bytes,
500
+ * then hash & decrypt.
501
+ *
502
+ * The receiver MUST:
503
+ * 1. Verify the EIP-712 signature recovers to `signed.signerAddress`.
504
+ * 2. Verify smart-wallet equality between `signerAddress` and
505
+ * `signed.providerAddress`.
506
+ * 3. Recompute `payloadHash` per the scheme rule above and compare
507
+ * to `signed.payloadHash`.
508
+ * 4. For encrypted schemes, derive the symmetric key via X25519+HKDF
509
+ * and decrypt; tag mismatch on GCM → `envelope_decrypt_failed`.
510
+ */
511
+ export interface DeliveryEnvelopeWireV1 {
512
+ /** Canonical signed projection. */
513
+ signed: DeliveryEnvelopeSignedV1;
514
+ /**
515
+ * Envelope body. Encoding depends on `signed.scheme`:
516
+ *
517
+ * - `public-v1`: plaintext UTF-8 JSON string. The body IS
518
+ * `JSON.stringify(payload)` verbatim — NOT hex-encoded. The
519
+ * Platform verifier computes `keccak256(utf8Bytes(body))` and
520
+ * the SDK signs over the same digest. Any encoding wrapper
521
+ * (hex, base64) here would force the verifier to hash a
522
+ * different byte sequence than the SDK signed over.
523
+ *
524
+ * - `x25519-aes256gcm-v1`: 0x-prefixed lowercase hex of the raw
525
+ * ciphertext bytes (NOT base64). `payloadHash =
526
+ * keccak256(hexDecode(body))`. The hex encoding is required
527
+ * because ciphertext is arbitrary binary (incl. 0x00, high-bit
528
+ * bytes) and cannot travel naked in a JSON string. The
529
+ * `bytesFromHex` decoder is the single shared hex-decoder used
530
+ * by every other byte-bearing field (nonce, tag, payloadHash,
531
+ * ephemeral pubkey).
532
+ *
533
+ * The exact bytes used to compute `signed.payloadHash` are
534
+ * `utf8Bytes(body)` for public-v1 and `hexDecode(body)` for the
535
+ * encrypted scheme — NOT the JSON-string or hex-string form
536
+ * uninterpreted.
537
+ */
538
+ body: string;
539
+ /**
540
+ * Provider EIP-712 signature over `signed` using the
541
+ * `AGIRAILS Delivery` domain, type `DeliveryEnvelopeV1`.
542
+ */
543
+ providerSig: `0x${string}`;
544
+ /**
545
+ * Optional server-added metadata (set by the relay on read).
546
+ * Never part of the signed payload — informational only.
547
+ */
548
+ serverMeta?: {
549
+ /** ISO 8601 timestamp at which the relay received the envelope. */
550
+ receivedAt: string;
551
+ /** Identifier of the relay that received and is now serving the envelope. */
552
+ relayId: string;
553
+ };
554
+ }
555
+ /**
556
+ * Result of building a delivery setup via the buyer setup builder.
557
+ *
558
+ * Carries the wire envelope (ready to POST to the relay) plus a
559
+ * nonce-manager key the caller uses to track this setup in a
560
+ * {@link NonceManager} instance, ensuring the same buyer cannot
561
+ * accidentally produce two setups bound to the same txId.
562
+ */
563
+ export interface BuildSetupResult {
564
+ /** Fully signed wire envelope, ready to post to a delivery channel. */
565
+ wire: DeliverySetupWireV1;
566
+ /**
567
+ * The NonceManager key under which this setup's anti-replay nonce was
568
+ * tracked. For delivery setups this key is namespaced under
569
+ * `agirails.delivery.setup.v1` and is *distinct* from the envelope
570
+ * nonce key (`agirails.delivery.envelope.v1`) and the older AIP-4
571
+ * delivery key (`agirails.delivery.v1`).
572
+ */
573
+ nonceManagerKey: string;
574
+ }
575
+ /**
576
+ * Result of building a delivery envelope via the provider envelope builder.
577
+ *
578
+ * Carries:
579
+ * - the wire envelope (ready to POST),
580
+ * - for encrypted schemes only, the symmetric `blobKey` that was used —
581
+ * returned so the provider can optionally persist it (e.g. for
582
+ * debugging or to seed an AIP-17 reference-mode flow). Receivers
583
+ * derive the key themselves from the ECDH exchange and do NOT use
584
+ * this field.
585
+ * - the exact body bytes the `payloadHash` was computed over (so
586
+ * callers can re-verify or anchor the hash without re-deriving the
587
+ * bytes themselves).
588
+ */
589
+ export interface BuildEnvelopeResult {
590
+ /** Fully signed wire envelope, ready to post to a delivery channel. */
591
+ wire: DeliveryEnvelopeWireV1;
592
+ /**
593
+ * Symmetric AES-256 key used to encrypt the body, 32 bytes.
594
+ * Present ONLY for `scheme: "x25519-aes256gcm-v1"`; `undefined` for
595
+ * `public-v1`. Receivers do not use this — it is returned solely
596
+ * for provider-side observability / future reference-mode flows.
597
+ */
598
+ blobKey?: Uint8Array;
599
+ /**
600
+ * Exact bytes over which `wire.signed.payloadHash` was computed.
601
+ *
602
+ * - For `public-v1`: UTF-8 encoded plaintext bytes.
603
+ * - For `x25519-aes256gcm-v1`: raw ciphertext bytes (NOT base64).
604
+ */
605
+ bodyBytes: Uint8Array;
606
+ }
607
+ /**
608
+ * Structured error codes for the delivery flow.
609
+ *
610
+ * Codes are grouped by stage:
611
+ *
612
+ * - `envelope_*` — Problems detected when verifying or processing
613
+ * an envelope received from the provider.
614
+ * - `setup_*` — Problems detected when verifying or processing a
615
+ * setup received from the requester.
616
+ * - `crypto_*` — Lower-level cryptographic primitive failures
617
+ * (keygen, ECDH, HKDF, AES-GCM).
618
+ * - `channel_*` — Transport-level failures (HTTP errors talking to
619
+ * the relay).
620
+ *
621
+ * Codes are stable identifiers — once shipped, semantics must not
622
+ * change. New failure modes should add a new code rather than overload
623
+ * an existing one. Codes are intended to be machine-actionable: SDK
624
+ * consumers and operators should be able to wire metrics and alerts
625
+ * directly to them.
626
+ */
627
+ export type DeliveryErrorCode = 'envelope_signature_invalid' | 'envelope_decrypt_failed' | 'envelope_payload_hash_mismatch' | 'envelope_participant_mismatch' | 'envelope_signer_role_mismatch' | 'envelope_chain_mismatch' | 'envelope_kernel_mismatch' | 'envelope_timestamp_skew' | 'envelope_no_envelope_at_relay' | 'setup_post_failed' | 'setup_signature_invalid' | 'setup_participant_mismatch' | 'setup_signer_role_mismatch' | 'setup_chain_mismatch' | 'setup_kernel_mismatch' | 'setup_timestamp_skew' | 'setup_expired' | 'crypto_keygen_failed' | 'crypto_shared_secret_failed' | 'crypto_hkdf_failed' | 'crypto_encrypt_failed' | 'crypto_decrypt_failed' | 'channel_post_failed' | 'channel_get_failed' | 'channel_unreachable' | 'envelope_missing' | 'envelope_late';
628
+ /**
629
+ * Structured error payload returned by delivery surface verification
630
+ * routines and builder failure paths.
631
+ *
632
+ * Carries the stable {@link DeliveryErrorCode}, a human-readable
633
+ * `message`, and optional structured `details` (e.g. expected vs actual
634
+ * values). Callers should branch on `code`, log `message`, and surface
635
+ * `details` for debugging.
636
+ *
637
+ * This is the *value* shape; the matching error *class* (extending
638
+ * `ACTPError`) is defined elsewhere in this module so consumers can
639
+ * `throw` and `catch` consistently with the rest of the SDK.
640
+ *
641
+ * @example
642
+ * ```typescript
643
+ * const err: DeliveryError = {
644
+ * code: 'envelope_payload_hash_mismatch',
645
+ * message: 'Recomputed hash does not match signed payloadHash',
646
+ * details: {
647
+ * expected: '0xabc…',
648
+ * actual: '0xdef…',
649
+ * },
650
+ * };
651
+ * ```
652
+ */
653
+ export interface DeliveryError {
654
+ /** Stable machine-actionable code from {@link DeliveryErrorCode}. */
655
+ code: DeliveryErrorCode;
656
+ /** Human-readable description of the failure. */
657
+ message: string;
658
+ /** Optional structured details (expected/actual values, txId, etc.). */
659
+ details?: Record<string, unknown>;
660
+ }
661
+ /**
662
+ * Canonical empty `bytes32` value: 32 zero bytes, hex-encoded.
663
+ *
664
+ * Used as the value of `buyerEphemeralPubkey` (in setups) and
665
+ * `providerEphemeralPubkey` / `payloadHash` slots whenever the field is
666
+ * scheme-irrelevant. EIP-712 has no concept of an absent field; every
667
+ * field in the typed schema has a value, so we use a canonical
668
+ * "no-data" sentinel that hashes to a known, predictable value.
669
+ *
670
+ * Specifically for `public-v1` envelopes:
671
+ * - `providerEphemeralPubkey` MUST equal this constant.
672
+ *
673
+ * For setups with `expectedPrivacy: "public"`:
674
+ * - `buyerEphemeralPubkey` MUST equal this constant.
675
+ *
676
+ * NOTE: `payloadHash` is NEVER canonical-empty in practice — even an
677
+ * empty body produces `keccak256("") = 0xc5d2…`. The constant is
678
+ * exported for type-level uniformity, not because `payloadHash` is
679
+ * ever zero.
680
+ *
681
+ * @example
682
+ * ```typescript
683
+ * // 0x0000000000000000000000000000000000000000000000000000000000000000
684
+ * console.log(CANONICAL_EMPTY_BYTES32);
685
+ * ```
686
+ */
687
+ export declare const CANONICAL_EMPTY_BYTES32: `0x${string}`;
688
+ /**
689
+ * Canonical empty `bytes12` value: 12 zero bytes, hex-encoded.
690
+ *
691
+ * Used for the AES-GCM `nonce` field when `scheme: "public-v1"` (the
692
+ * envelope is not encrypted, so there is no real nonce). Receivers
693
+ * MUST reject envelopes whose scheme is `public-v1` but whose `nonce`
694
+ * is NOT this constant.
695
+ *
696
+ * For `x25519-aes256gcm-v1`, `nonce` MUST be 12 random bytes — never
697
+ * this constant; a zero nonce under a real key catastrophically breaks
698
+ * AES-GCM (key recovery via tag forgery).
699
+ *
700
+ * @example
701
+ * ```typescript
702
+ * // 0x000000000000000000000000
703
+ * console.log(CANONICAL_EMPTY_BYTES12);
704
+ * ```
705
+ */
706
+ export declare const CANONICAL_EMPTY_BYTES12: `0x${string}`;
707
+ /**
708
+ * Canonical empty `bytes16` value: 16 zero bytes, hex-encoded.
709
+ *
710
+ * Used for the AES-GCM authentication `tag` field when
711
+ * `scheme: "public-v1"` (no encryption, no tag). Receivers MUST
712
+ * reject envelopes whose scheme is `public-v1` but whose `tag` is
713
+ * NOT this constant.
714
+ *
715
+ * @example
716
+ * ```typescript
717
+ * // 0x00000000000000000000000000000000
718
+ * console.log(CANONICAL_EMPTY_BYTES16);
719
+ * ```
720
+ */
721
+ export declare const CANONICAL_EMPTY_BYTES16: `0x${string}`;
722
+ //# sourceMappingURL=types.d.ts.map