@agirails/sdk 4.4.9 → 4.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/builders/DeliveryProofBuilder.d.ts +224 -13
  2. package/dist/builders/DeliveryProofBuilder.d.ts.map +1 -1
  3. package/dist/builders/DeliveryProofBuilder.js +247 -13
  4. package/dist/builders/DeliveryProofBuilder.js.map +1 -1
  5. package/dist/cli/agirails.d.ts +85 -1
  6. package/dist/cli/agirails.d.ts.map +1 -1
  7. package/dist/cli/agirails.js +429 -154
  8. package/dist/cli/agirails.js.map +1 -1
  9. package/dist/cli/commands/init.d.ts +54 -0
  10. package/dist/cli/commands/init.d.ts.map +1 -1
  11. package/dist/cli/commands/init.js +193 -1
  12. package/dist/cli/commands/init.js.map +1 -1
  13. package/dist/cli/commands/receipt.d.ts +70 -2
  14. package/dist/cli/commands/receipt.d.ts.map +1 -1
  15. package/dist/cli/commands/receipt.js +218 -3
  16. package/dist/cli/commands/receipt.js.map +1 -1
  17. package/dist/cli/commands/test.d.ts +77 -1
  18. package/dist/cli/commands/test.d.ts.map +1 -1
  19. package/dist/cli/commands/test.js +264 -2
  20. package/dist/cli/commands/test.js.map +1 -1
  21. package/dist/cli/lib/runRequest.d.ts +90 -0
  22. package/dist/cli/lib/runRequest.d.ts.map +1 -1
  23. package/dist/cli/lib/runRequest.js +300 -9
  24. package/dist/cli/lib/runRequest.js.map +1 -1
  25. package/dist/cli/lib/sentinelReflections.d.ts +111 -0
  26. package/dist/cli/lib/sentinelReflections.d.ts.map +1 -0
  27. package/dist/cli/lib/sentinelReflections.js +193 -0
  28. package/dist/cli/lib/sentinelReflections.js.map +1 -0
  29. package/dist/delivery/MockDeliveryChannel.d.ts +208 -0
  30. package/dist/delivery/MockDeliveryChannel.d.ts.map +1 -0
  31. package/dist/delivery/MockDeliveryChannel.js +445 -0
  32. package/dist/delivery/MockDeliveryChannel.js.map +1 -0
  33. package/dist/delivery/RelayDeliveryChannel.d.ts +176 -0
  34. package/dist/delivery/RelayDeliveryChannel.d.ts.map +1 -0
  35. package/dist/delivery/RelayDeliveryChannel.js +377 -0
  36. package/dist/delivery/RelayDeliveryChannel.js.map +1 -0
  37. package/dist/delivery/channel.d.ts +282 -0
  38. package/dist/delivery/channel.d.ts.map +1 -0
  39. package/dist/delivery/channel.js +76 -0
  40. package/dist/delivery/channel.js.map +1 -0
  41. package/dist/delivery/channelLog.d.ts +115 -0
  42. package/dist/delivery/channelLog.d.ts.map +1 -0
  43. package/dist/delivery/channelLog.js +94 -0
  44. package/dist/delivery/channelLog.js.map +1 -0
  45. package/dist/delivery/crypto.d.ts +312 -0
  46. package/dist/delivery/crypto.d.ts.map +1 -0
  47. package/dist/delivery/crypto.js +495 -0
  48. package/dist/delivery/crypto.js.map +1 -0
  49. package/dist/delivery/eip712.d.ts +248 -0
  50. package/dist/delivery/eip712.d.ts.map +1 -0
  51. package/dist/delivery/eip712.js +397 -0
  52. package/dist/delivery/eip712.js.map +1 -0
  53. package/dist/delivery/envelopeBuilder.d.ts +531 -0
  54. package/dist/delivery/envelopeBuilder.d.ts.map +1 -0
  55. package/dist/delivery/envelopeBuilder.js +832 -0
  56. package/dist/delivery/envelopeBuilder.js.map +1 -0
  57. package/dist/delivery/index.d.ts +53 -0
  58. package/dist/delivery/index.d.ts.map +1 -0
  59. package/dist/delivery/index.js +143 -0
  60. package/dist/delivery/index.js.map +1 -0
  61. package/dist/delivery/keys.d.ts +344 -0
  62. package/dist/delivery/keys.d.ts.map +1 -0
  63. package/dist/delivery/keys.js +513 -0
  64. package/dist/delivery/keys.js.map +1 -0
  65. package/dist/delivery/nonce-keys.d.ts +93 -0
  66. package/dist/delivery/nonce-keys.d.ts.map +1 -0
  67. package/dist/delivery/nonce-keys.js +88 -0
  68. package/dist/delivery/nonce-keys.js.map +1 -0
  69. package/dist/delivery/setupBuilder.d.ts +403 -0
  70. package/dist/delivery/setupBuilder.d.ts.map +1 -0
  71. package/dist/delivery/setupBuilder.js +554 -0
  72. package/dist/delivery/setupBuilder.js.map +1 -0
  73. package/dist/delivery/types.d.ts +722 -0
  74. package/dist/delivery/types.d.ts.map +1 -0
  75. package/dist/delivery/types.js +150 -0
  76. package/dist/delivery/types.js.map +1 -0
  77. package/dist/delivery/validate.d.ts +288 -0
  78. package/dist/delivery/validate.d.ts.map +1 -0
  79. package/dist/delivery/validate.js +648 -0
  80. package/dist/delivery/validate.js.map +1 -0
  81. package/dist/level1/Agent.d.ts +130 -0
  82. package/dist/level1/Agent.d.ts.map +1 -1
  83. package/dist/level1/Agent.js +248 -0
  84. package/dist/level1/Agent.js.map +1 -1
  85. package/dist/level1/types/Options.d.ts +62 -0
  86. package/dist/level1/types/Options.d.ts.map +1 -1
  87. package/dist/level1/types/Options.js +22 -0
  88. package/dist/level1/types/Options.js.map +1 -1
  89. package/dist/runtime/MockRuntime.d.ts +32 -0
  90. package/dist/runtime/MockRuntime.d.ts.map +1 -1
  91. package/dist/runtime/MockRuntime.js +44 -0
  92. package/dist/runtime/MockRuntime.js.map +1 -1
  93. package/package.json +6 -1
@@ -0,0 +1,495 @@
1
+ "use strict";
2
+ /**
3
+ * AIP-16 Delivery Surface — AES-256-GCM AEAD + Body Hashing (Phase 2a Foundation)
4
+ * ==============================================================================
5
+ *
6
+ * Authenticated encryption primitives for the `x25519-aes256gcm-v1`
7
+ * delivery scheme of AIP-16 Rev 5.
8
+ *
9
+ * This module sits one layer above `./keys.ts` (which produces the
10
+ * 32-byte session key via X25519 ECDH + HKDF-SHA256) and one layer
11
+ * below the envelope builders (`./envelopeBuilder.ts`, later phase),
12
+ * which assemble the ciphertext + nonce + tag + signature into the
13
+ * wire envelope.
14
+ *
15
+ * ## Scope of this file
16
+ *
17
+ * - {@link encryptBody}: seal a UTF-8 string or raw byte body with
18
+ * AES-256-GCM, returning ciphertext + 12-byte nonce + 16-byte tag.
19
+ * - {@link decryptBody}: inverse — verify the GCM tag and return the
20
+ * plaintext.
21
+ * - {@link bodyHash}: keccak256 of the UTF-8 / raw bytes, in the exact
22
+ * form used for the `payloadHash` field of the signed EIP-712
23
+ * projection.
24
+ * - Hex format helpers ({@link bytesToHex}, {@link bytesFromHex}) for
25
+ * ciphertext / nonce / tag serialization at the wire boundary.
26
+ *
27
+ * ## Library choice: `node:crypto`
28
+ *
29
+ * We use Node's built-in AES-GCM (`createCipheriv('aes-256-gcm', …)`)
30
+ * rather than `@noble/ciphers`. Reasons:
31
+ *
32
+ * 1. AES-256-GCM is a *standard* AEAD; the implementation surface is
33
+ * small and audited as part of OpenSSL (the engine behind
34
+ * `node:crypto`).
35
+ * 2. Zero new dependencies — matches the design constraint in the
36
+ * Phase 2a task brief.
37
+ * 3. The `setAuthTag` / `getAuthTag` pattern is mechanical and easy
38
+ * to audit for "did we actually verify the tag before returning
39
+ * plaintext?" (`decipher.final()` throws on tag mismatch).
40
+ *
41
+ * ## AAD (Additional Authenticated Data) — H5 defense-in-depth
42
+ *
43
+ * Both {@link encryptBody} and {@link decryptBody} accept an OPTIONAL
44
+ * `aad` byte buffer. When supplied, the bytes are fed into GCM via
45
+ * `cipher.setAAD(aad)` / `decipher.setAAD(aad)` — they are *not*
46
+ * encrypted, but the GCM authentication tag commits to them, so a
47
+ * decryption with the wrong AAD fails closed with a tag mismatch.
48
+ *
49
+ * For the `x25519-aes256gcm-v1` scheme the envelope builder constructs
50
+ *
51
+ * aad = txId_bytes (32) || signerAddress_bytes (20) // 52 bytes
52
+ *
53
+ * and passes it to both encrypt and decrypt. This binds the GCM
54
+ * authentication to the on-chain transaction id and the EOA that
55
+ * signed the envelope, so a misrouted envelope (correct ciphertext +
56
+ * nonce + tag + sessionKey, but delivered to a different `txId` or
57
+ * `signerAddress`) cannot be opened — defense-in-depth on top of the
58
+ * EIP-712 signature over `txId` and `payloadHash`.
59
+ *
60
+ * Because the channel is gated behind the Phase 2f feature flag and
61
+ * no in-flight `x25519-aes256gcm-v1` envelopes exist in production, we
62
+ * change the AAD inline within the existing scheme tag rather than
63
+ * minting a `-v2` suffix; the scheme name stays `x25519-aes256gcm-v1`.
64
+ *
65
+ * AAD is OPTIONAL at the primitive level. Callers that omit it get
66
+ * the legacy "AAD = empty" behavior (still interoperable with prior
67
+ * versions of the function). The envelope builder always supplies AAD.
68
+ *
69
+ * ## Memory hygiene
70
+ *
71
+ * `sessionKey` and plaintext are held in plain `Uint8Array`s. Like
72
+ * `./keys.ts`, this module does not attempt to zero memory — V8 makes
73
+ * no such guarantees, and the SDK target environments (Node + Bun)
74
+ * inherit that limitation. Callers SHOULD let secrets go out of scope
75
+ * promptly after use.
76
+ *
77
+ * @module delivery/crypto
78
+ * @see ./keys — produces the 32-byte session key consumed here
79
+ * @see ./eip712 — signs the `payloadHash` produced by {@link bodyHash}
80
+ * @see {@link https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf NIST SP 800-38D — GCM mode}
81
+ * @see {@link https://www.rfc-editor.org/rfc/rfc5116 RFC 5116 — AEAD interface}
82
+ */
83
+ Object.defineProperty(exports, "__esModule", { value: true });
84
+ exports.bytesFromHex = exports.bytesToHex = exports.bodyHash = exports.decryptBody = exports.encryptBody = exports.AES_KEY_LENGTH = exports.AES_GCM_TAG_LENGTH = exports.AES_GCM_NONCE_LENGTH = void 0;
85
+ const node_crypto_1 = require("node:crypto");
86
+ const ethers_1 = require("ethers");
87
+ const keys_1 = require("./keys");
88
+ // ============================================================================
89
+ // Constants
90
+ // ============================================================================
91
+ /**
92
+ * Length (in bytes) of the AES-256-GCM nonce / IV.
93
+ *
94
+ * Twelve bytes is the GCM-standard length (NIST SP 800-38D §5.2.1.1).
95
+ * Any other length is technically permitted by the spec but triggers
96
+ * an additional GHASH step and is interoperable only by convention;
97
+ * AIP-16 v1 mandates 12 bytes to keep the wire format unambiguous.
98
+ *
99
+ * We sample the nonce from `randomBytes(12)` per-encryption. The
100
+ * 2^96 nonce space is more than adequate for the AIP-16 use case
101
+ * (one nonce per delivery envelope per session key, with session keys
102
+ * themselves bound to a single transaction via HKDF).
103
+ */
104
+ exports.AES_GCM_NONCE_LENGTH = 12;
105
+ /**
106
+ * Length (in bytes) of the AES-256-GCM authentication tag.
107
+ *
108
+ * Sixteen bytes is the maximum (full-strength) tag length permitted
109
+ * by GCM; NIST SP 800-38D recommends this size when the application
110
+ * cannot tolerate any forgery probability. The wire format reserves
111
+ * a fixed 16-byte slot for the tag.
112
+ */
113
+ exports.AES_GCM_TAG_LENGTH = 16;
114
+ /**
115
+ * Length (in bytes) of an AES-256 key. Equal to
116
+ * {@link DELIVERY_SESSION_KEY_LENGTH} (re-exported from `./keys`) so
117
+ * callers do not have to import both files just for the length check.
118
+ */
119
+ exports.AES_KEY_LENGTH = keys_1.DELIVERY_SESSION_KEY_LENGTH;
120
+ // ============================================================================
121
+ // Internal helpers
122
+ // ============================================================================
123
+ /**
124
+ * Convert a `string | Uint8Array` plaintext to bytes. UTF-8 is the
125
+ * canonical text encoding for AIP-16 envelope bodies; any other
126
+ * encoding (UTF-16, Latin-1, …) MUST be transcoded to UTF-8 by the
127
+ * caller before calling {@link encryptBody}.
128
+ *
129
+ * @internal
130
+ */
131
+ function toBytes(value, field) {
132
+ if (typeof value === 'string') {
133
+ return new Uint8Array(Buffer.from(value, 'utf8'));
134
+ }
135
+ if (value instanceof Uint8Array) {
136
+ return value;
137
+ }
138
+ throw new keys_1.DeliveryCryptoError('crypto_encrypt_failed', `${field} must be a string or Uint8Array, got ${typeof value}`, { field, type: typeof value });
139
+ }
140
+ /**
141
+ * Hex alphabet for the lowercase no-Buffer hex encoder. Kept in lock-
142
+ * step with `./keys.ts` so both files produce byte-identical output.
143
+ *
144
+ * @internal
145
+ */
146
+ const HEX_CHARS = '0123456789abcdef';
147
+ // ============================================================================
148
+ // Public API: AES-256-GCM
149
+ // ============================================================================
150
+ /**
151
+ * Encrypt a delivery envelope body with AES-256-GCM using the supplied
152
+ * session key.
153
+ *
154
+ * The session key MUST have been produced by
155
+ * {@link import('./keys').deriveSessionKey} (32 bytes, HKDF-SHA256
156
+ * output bound to the on-chain `txId`).
157
+ *
158
+ * A fresh 12-byte nonce is sampled from `randomBytes` per call.
159
+ * Re-using a (key, nonce) pair is *catastrophic* for GCM — it leaks
160
+ * the GHASH key, allowing both decryption of past messages and
161
+ * forgery of future ones. With session keys scoped to one transaction
162
+ * and nonces randomized per envelope, the probability of collision
163
+ * over realistic envelope counts is negligible.
164
+ *
165
+ * AAD is OPTIONAL. When supplied, the bytes are committed by the GCM
166
+ * tag (defense-in-depth — see the H5 section of the module-level docs).
167
+ * Decryption with a different AAD (or with no AAD at all when the
168
+ * encrypt side used one) will fail with `crypto_decrypt_failed`.
169
+ *
170
+ * @param plaintext - Body bytes to encrypt. A `string` is interpreted
171
+ * as UTF-8; pre-encoded `Uint8Array` is passed through verbatim.
172
+ * @param sessionKey - 32-byte AES-256-GCM key from `deriveSessionKey`.
173
+ * @param aad - Optional Additional Authenticated Data. When omitted,
174
+ * no AAD is fed into GCM (legacy behavior). When supplied, MUST be a
175
+ * `Uint8Array`; mismatched AAD at decrypt time fails tag verification.
176
+ * @returns {@link EncryptResult} carrying ciphertext, nonce, and tag.
177
+ * @throws {DeliveryCryptoError} `crypto_encrypt_failed` if
178
+ * `sessionKey` is malformed (not a `Uint8Array` of length 32), if
179
+ * `plaintext` is the wrong type, if `aad` is supplied as a non-bytes
180
+ * value, or if `node:crypto` raises.
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * const key = deriveSessionKey(shared, txId);
185
+ * // AAD = txId_bytes || signerAddress_bytes (H5 binding)
186
+ * const aad = new Uint8Array(52);
187
+ * aad.set(bytesFromHex(txId), 0);
188
+ * aad.set(bytesFromHex(signerAddress), 32);
189
+ * const { ciphertext, nonce, tag } = encryptBody('{"result":"ok"}', key, aad);
190
+ * ```
191
+ */
192
+ function encryptBody(plaintext, sessionKey, aad) {
193
+ // ── Validate session key shape ──────────────────────────────────
194
+ if (!(sessionKey instanceof Uint8Array)) {
195
+ throw new keys_1.DeliveryCryptoError('crypto_encrypt_failed', `sessionKey must be a Uint8Array, got ${typeof sessionKey}`, { field: 'sessionKey', type: typeof sessionKey });
196
+ }
197
+ if (sessionKey.length !== exports.AES_KEY_LENGTH) {
198
+ throw new keys_1.DeliveryCryptoError('crypto_encrypt_failed', `sessionKey must be exactly ${exports.AES_KEY_LENGTH} bytes (got ${sessionKey.length})`, {
199
+ field: 'sessionKey',
200
+ expectedLength: exports.AES_KEY_LENGTH,
201
+ actualLength: sessionKey.length,
202
+ });
203
+ }
204
+ // ── Validate AAD shape (if provided) ────────────────────────────
205
+ //
206
+ // We accept either `undefined` (no-AAD legacy behavior) or a
207
+ // `Uint8Array` (any length, including zero). Anything else is a
208
+ // caller bug and surfaces as `crypto_encrypt_failed` so it fails
209
+ // closed at the encrypt boundary rather than producing an envelope
210
+ // the buyer cannot open.
211
+ if (aad !== undefined && !(aad instanceof Uint8Array)) {
212
+ throw new keys_1.DeliveryCryptoError('crypto_encrypt_failed', `aad must be a Uint8Array when supplied, got ${typeof aad}`, { field: 'aad', type: typeof aad });
213
+ }
214
+ // ── Coerce plaintext to bytes ───────────────────────────────────
215
+ const ptBytes = toBytes(plaintext, 'plaintext');
216
+ // ── Sample a fresh 12-byte nonce ────────────────────────────────
217
+ let nonce;
218
+ try {
219
+ nonce = new Uint8Array((0, node_crypto_1.randomBytes)(exports.AES_GCM_NONCE_LENGTH));
220
+ }
221
+ catch (err) {
222
+ throw new keys_1.DeliveryCryptoError('crypto_encrypt_failed', `randomBytes(${exports.AES_GCM_NONCE_LENGTH}) failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err instanceof Error ? err.message : String(err) });
223
+ }
224
+ // ── Encrypt ─────────────────────────────────────────────────────
225
+ let ciphertext;
226
+ let tag;
227
+ try {
228
+ const cipher = (0, node_crypto_1.createCipheriv)('aes-256-gcm', sessionKey, nonce, {
229
+ authTagLength: exports.AES_GCM_TAG_LENGTH,
230
+ });
231
+ // H5 binding: when AAD is supplied, feed it into GCM BEFORE any
232
+ // ciphertext bytes are produced. AAD is authenticated but not
233
+ // encrypted — the tag will only verify on decrypt if the same AAD
234
+ // is presented. `setAAD` MUST be called before `update` per the
235
+ // node:crypto contract (the underlying OpenSSL state machine
236
+ // forbids AAD after ciphertext input).
237
+ if (aad !== undefined) {
238
+ cipher.setAAD(aad);
239
+ }
240
+ const part1 = cipher.update(ptBytes);
241
+ const part2 = cipher.final();
242
+ // Concatenate as a single Uint8Array. `Buffer.concat` returns a
243
+ // Buffer (subclass of Uint8Array); we wrap to a plain Uint8Array
244
+ // view to avoid leaking the Buffer subclass to consumers, which
245
+ // matters for downstream `instanceof Uint8Array` checks across
246
+ // realms / workers.
247
+ const combined = Buffer.concat([part1, part2]);
248
+ ciphertext = new Uint8Array(combined.buffer, combined.byteOffset, combined.byteLength);
249
+ const rawTag = cipher.getAuthTag();
250
+ tag = new Uint8Array(rawTag.buffer, rawTag.byteOffset, rawTag.byteLength);
251
+ }
252
+ catch (err) {
253
+ throw new keys_1.DeliveryCryptoError('crypto_encrypt_failed', `AES-256-GCM encryption failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err instanceof Error ? err.message : String(err) });
254
+ }
255
+ // ── Defensive length checks (paranoia) ──────────────────────────
256
+ if (tag.length !== exports.AES_GCM_TAG_LENGTH) {
257
+ throw new keys_1.DeliveryCryptoError('crypto_encrypt_failed', `GCM authentication tag has unexpected length: ${tag.length}`, { expectedLength: exports.AES_GCM_TAG_LENGTH, actualLength: tag.length });
258
+ }
259
+ if (nonce.length !== exports.AES_GCM_NONCE_LENGTH) {
260
+ throw new keys_1.DeliveryCryptoError('crypto_encrypt_failed', `GCM nonce has unexpected length: ${nonce.length}`, { expectedLength: exports.AES_GCM_NONCE_LENGTH, actualLength: nonce.length });
261
+ }
262
+ return { ciphertext, nonce, tag };
263
+ }
264
+ exports.encryptBody = encryptBody;
265
+ /**
266
+ * Decrypt and authenticate an AES-256-GCM ciphertext produced by
267
+ * {@link encryptBody} (or an interoperable peer).
268
+ *
269
+ * The GCM authentication tag is verified inside `decipher.final()` —
270
+ * if the tag does not match, `node:crypto` throws and we re-raise as
271
+ * `DeliveryCryptoError('crypto_decrypt_failed')`. This is the *only*
272
+ * integrity check on the envelope body bytes; pair it with EIP-712
273
+ * signature verification one layer up to also bind the body to a
274
+ * specific signer.
275
+ *
276
+ * AAD is OPTIONAL but MUST match what the encrypt side used. The GCM
277
+ * tag commits to the AAD bytes; supplying the wrong AAD (or omitting
278
+ * AAD when the encrypt side supplied one, or vice versa) produces a
279
+ * tag-mismatch error, surfaced here as `crypto_decrypt_failed`. This
280
+ * is the H5 misrouting defense — see the module-level AAD section.
281
+ *
282
+ * @param ciphertext - GCM ciphertext as raw bytes.
283
+ * @param sessionKey - 32-byte AES-256-GCM key (same as encrypt side).
284
+ * @param nonce - 12-byte nonce that was used at encrypt time.
285
+ * @param tag - 16-byte GCM authentication tag.
286
+ * @param aad - Optional Additional Authenticated Data. MUST exactly
287
+ * match the AAD passed to {@link encryptBody}; mismatch (including
288
+ * AAD/no-AAD asymmetry) fails the tag check and throws
289
+ * `crypto_decrypt_failed`.
290
+ * @returns The decrypted plaintext as raw bytes. If the original
291
+ * plaintext was a UTF-8 string, the caller can recover it via
292
+ * `Buffer.from(plaintext).toString('utf8')`.
293
+ * @throws {DeliveryCryptoError} `crypto_decrypt_failed` on any of:
294
+ * malformed lengths, wrong session key, tampered ciphertext / tag /
295
+ * nonce, AAD mismatch, malformed AAD type, or underlying
296
+ * `node:crypto` failure.
297
+ *
298
+ * @example
299
+ * ```typescript
300
+ * const aad = new Uint8Array(52);
301
+ * aad.set(bytesFromHex(txId), 0);
302
+ * aad.set(bytesFromHex(signerAddress), 32);
303
+ * const plaintextBytes = decryptBody(ciphertext, key, nonce, tag, aad);
304
+ * const json = Buffer.from(plaintextBytes).toString('utf8');
305
+ * ```
306
+ */
307
+ function decryptBody(ciphertext, sessionKey, nonce, tag, aad) {
308
+ // ── Validate all four inputs up-front ───────────────────────────
309
+ if (!(ciphertext instanceof Uint8Array)) {
310
+ throw new keys_1.DeliveryCryptoError('crypto_decrypt_failed', `ciphertext must be a Uint8Array, got ${typeof ciphertext}`, { field: 'ciphertext', type: typeof ciphertext });
311
+ }
312
+ if (!(sessionKey instanceof Uint8Array) || sessionKey.length !== exports.AES_KEY_LENGTH) {
313
+ throw new keys_1.DeliveryCryptoError('crypto_decrypt_failed', `sessionKey must be a Uint8Array of exactly ${exports.AES_KEY_LENGTH} bytes (got ${sessionKey instanceof Uint8Array ? sessionKey.length : typeof sessionKey})`, {
314
+ field: 'sessionKey',
315
+ expectedLength: exports.AES_KEY_LENGTH,
316
+ actualLength: sessionKey instanceof Uint8Array ? sessionKey.length : null,
317
+ });
318
+ }
319
+ if (!(nonce instanceof Uint8Array) || nonce.length !== exports.AES_GCM_NONCE_LENGTH) {
320
+ throw new keys_1.DeliveryCryptoError('crypto_decrypt_failed', `nonce must be a Uint8Array of exactly ${exports.AES_GCM_NONCE_LENGTH} bytes (got ${nonce instanceof Uint8Array ? nonce.length : typeof nonce})`, {
321
+ field: 'nonce',
322
+ expectedLength: exports.AES_GCM_NONCE_LENGTH,
323
+ actualLength: nonce instanceof Uint8Array ? nonce.length : null,
324
+ });
325
+ }
326
+ if (!(tag instanceof Uint8Array) || tag.length !== exports.AES_GCM_TAG_LENGTH) {
327
+ throw new keys_1.DeliveryCryptoError('crypto_decrypt_failed', `tag must be a Uint8Array of exactly ${exports.AES_GCM_TAG_LENGTH} bytes (got ${tag instanceof Uint8Array ? tag.length : typeof tag})`, {
328
+ field: 'tag',
329
+ expectedLength: exports.AES_GCM_TAG_LENGTH,
330
+ actualLength: tag instanceof Uint8Array ? tag.length : null,
331
+ });
332
+ }
333
+ if (aad !== undefined && !(aad instanceof Uint8Array)) {
334
+ throw new keys_1.DeliveryCryptoError('crypto_decrypt_failed', `aad must be a Uint8Array when supplied, got ${typeof aad}`, { field: 'aad', type: typeof aad });
335
+ }
336
+ // ── Decrypt ─────────────────────────────────────────────────────
337
+ try {
338
+ const decipher = (0, node_crypto_1.createDecipheriv)('aes-256-gcm', sessionKey, nonce, {
339
+ authTagLength: exports.AES_GCM_TAG_LENGTH,
340
+ });
341
+ decipher.setAuthTag(tag);
342
+ // H5 binding: AAD MUST be supplied to setAAD before any ciphertext
343
+ // is fed in (node:crypto / OpenSSL contract). If the encrypt side
344
+ // used AAD and we omit it here, the tag will fail to verify in
345
+ // `final()`. If the encrypt side used no AAD and we supply one
346
+ // here, same outcome — symmetric failure, fail-closed.
347
+ if (aad !== undefined) {
348
+ decipher.setAAD(aad);
349
+ }
350
+ const part1 = decipher.update(ciphertext);
351
+ // `final()` throws if the GCM tag doesn't authenticate. This is
352
+ // the integrity check; anything that reaches the assignment
353
+ // below has been authenticated under (sessionKey, nonce, tag).
354
+ const part2 = decipher.final();
355
+ const combined = Buffer.concat([part1, part2]);
356
+ return new Uint8Array(combined.buffer, combined.byteOffset, combined.byteLength);
357
+ }
358
+ catch (err) {
359
+ throw new keys_1.DeliveryCryptoError('crypto_decrypt_failed', `AES-256-GCM decryption / authentication failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err instanceof Error ? err.message : String(err) });
360
+ }
361
+ }
362
+ exports.decryptBody = decryptBody;
363
+ // ============================================================================
364
+ // Public API: keccak256 body hash
365
+ // ============================================================================
366
+ /**
367
+ * Compute the keccak256 hash of an envelope body, in the exact form
368
+ * embedded into the `payloadHash` field of the signed EIP-712
369
+ * projection.
370
+ *
371
+ * Per AIP-16 Rev 5 §6.2, `payloadHash = keccak256(bodyBytes)` where
372
+ * `bodyBytes` is:
373
+ * - For `scheme: "public-v1"`: the UTF-8 bytes of the plaintext body
374
+ * string (or the raw `Uint8Array` if the caller pre-encoded).
375
+ * - For `scheme: "x25519-aes256gcm-v1"`: the *ciphertext* bytes (the
376
+ * output of {@link encryptBody}.ciphertext), not the plaintext.
377
+ * This commits the signer to the exact bytes that travel on the
378
+ * wire, preventing a malicious relay from substituting alternative
379
+ * ciphertext with the same plaintext (which GCM nonces would
380
+ * actually preclude, but the EIP-712 commitment is independent of
381
+ * that).
382
+ *
383
+ * The output is a 0x-prefixed lowercase 66-char hex string (32-byte
384
+ * keccak256 digest), exactly matching the `bytes32` field shape in
385
+ * the EIP-712 types.
386
+ *
387
+ * @param body - The bytes to hash. A `string` is interpreted as UTF-8.
388
+ * @returns The keccak256 digest as `0x` + 64 lowercase hex chars.
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * // Public scheme:
393
+ * const h1 = bodyHash('{"result":"ok"}');
394
+ *
395
+ * // Encrypted scheme — hash the CIPHERTEXT, not the plaintext:
396
+ * const { ciphertext } = encryptBody(plaintext, key);
397
+ * const h2 = bodyHash(ciphertext);
398
+ * ```
399
+ */
400
+ function bodyHash(body) {
401
+ const bytes = toBytes(body, 'body');
402
+ // ethers.keccak256 accepts `BytesLike`; a Uint8Array is one of the
403
+ // accepted forms. The return value is already a 0x-prefixed
404
+ // lowercase hex string of length 66.
405
+ const digest = ethers_1.ethers.keccak256(bytes);
406
+ return digest;
407
+ }
408
+ exports.bodyHash = bodyHash;
409
+ // ============================================================================
410
+ // Public API: Hex format helpers
411
+ // ============================================================================
412
+ /**
413
+ * Encode raw bytes to a lowercase 0x-prefixed hex string.
414
+ *
415
+ * Intentionally byte-for-byte equivalent to the equivalent helper in
416
+ * `./keys.ts` (which is `internal` there). Exposed here at the
417
+ * module surface so envelope-builder callers can serialize their
418
+ * ciphertext / nonce / tag without reaching into `./keys.ts` internals.
419
+ *
420
+ * Hand-rolled rather than `Buffer.from(b).toString('hex')` so the
421
+ * implementation is portable to non-Node runtimes (Bun, web) without
422
+ * polyfills, and to avoid Buffer-vs-Uint8Array subclass confusion.
423
+ *
424
+ * @param b - Raw bytes to encode.
425
+ * @returns A `0x`-prefixed lowercase hex string of length
426
+ * `2 + 2 * b.length`.
427
+ *
428
+ * @example
429
+ * ```typescript
430
+ * bytesToHex(new Uint8Array([0xab, 0xcd])); // "0xabcd"
431
+ * ```
432
+ */
433
+ function bytesToHex(b) {
434
+ if (!(b instanceof Uint8Array)) {
435
+ throw new keys_1.DeliveryCryptoError('crypto_encrypt_failed', `bytesToHex expected Uint8Array, got ${typeof b}`, { type: typeof b });
436
+ }
437
+ let out = '0x';
438
+ for (let i = 0; i < b.length; i++) {
439
+ const byte = b[i];
440
+ out += HEX_CHARS[(byte >>> 4) & 0x0f];
441
+ out += HEX_CHARS[byte & 0x0f];
442
+ }
443
+ return out;
444
+ }
445
+ exports.bytesToHex = bytesToHex;
446
+ /**
447
+ * Decode a 0x-prefixed hex string to raw bytes.
448
+ *
449
+ * Strict on shape: the string MUST start with `0x` (case-insensitive
450
+ * prefix), MUST contain only hex digits after the prefix, and MUST
451
+ * have an even number of hex digits. Returns a fresh `Uint8Array`.
452
+ *
453
+ * Used at the wire boundary to decode `bodyCiphertextHex`, `nonceHex`,
454
+ * `tagHex`, and any other hex-serialized byte field into the byte
455
+ * forms expected by {@link decryptBody}.
456
+ *
457
+ * @param hex - 0x-prefixed hex string, even number of hex digits.
458
+ * @returns A fresh `Uint8Array` of length `(hex.length - 2) / 2`.
459
+ * @throws {DeliveryCryptoError} `crypto_decrypt_failed` if `hex` is
460
+ * missing the `0x` prefix, has odd length, or contains non-hex
461
+ * characters. (`crypto_decrypt_failed` is the most likely site of
462
+ * failure for this helper; encrypt-side callers will instead get
463
+ * the structural validation in {@link encryptBody}.)
464
+ *
465
+ * @example
466
+ * ```typescript
467
+ * bytesFromHex('0xabcd'); // Uint8Array(2) [0xab, 0xcd]
468
+ * ```
469
+ */
470
+ function bytesFromHex(hex) {
471
+ if (typeof hex !== 'string') {
472
+ throw new keys_1.DeliveryCryptoError('crypto_decrypt_failed', `bytesFromHex expected string, got ${typeof hex}`, { type: typeof hex });
473
+ }
474
+ if (hex.length < 2 ||
475
+ hex[0] !== '0' ||
476
+ (hex[1] !== 'x' && hex[1] !== 'X')) {
477
+ throw new keys_1.DeliveryCryptoError('crypto_decrypt_failed', 'bytesFromHex requires a 0x-prefixed string', { prefix: hex.slice(0, 4) });
478
+ }
479
+ const body = hex.slice(2);
480
+ if (body.length % 2 !== 0) {
481
+ throw new keys_1.DeliveryCryptoError('crypto_decrypt_failed', `bytesFromHex requires an even number of hex digits (got ${body.length})`, { hexChars: body.length });
482
+ }
483
+ if (!/^[0-9a-fA-F]*$/.test(body)) {
484
+ throw new keys_1.DeliveryCryptoError('crypto_decrypt_failed', 'bytesFromHex received non-hex characters after the 0x prefix', {});
485
+ }
486
+ const out = new Uint8Array(body.length / 2);
487
+ for (let i = 0; i < out.length; i++) {
488
+ const hi = parseInt(body[i * 2], 16);
489
+ const lo = parseInt(body[i * 2 + 1], 16);
490
+ out[i] = (hi << 4) | lo;
491
+ }
492
+ return out;
493
+ }
494
+ exports.bytesFromHex = bytesFromHex;
495
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/delivery/crypto.ts"],"names":[],"mappings":"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"}