@tinycloud/sdk-services 3.7.0-beta.3 → 3.7.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.
@@ -0,0 +1,328 @@
1
+ import { P as PermissionHint } from './types-DAOyIbXu.js';
2
+
3
+ /**
4
+ * Canonical JSON serialization and content hashing for TinyCloud
5
+ * encryption requests/responses.
6
+ *
7
+ * The node and SDK must agree byte-for-byte on the canonical form so
8
+ * that body-hash bindings (`bodyHash`, `encryptedSymmetricKeyHash`,
9
+ * `receiverPublicKeyHash`) verify on both sides.
10
+ *
11
+ * Canonical rules:
12
+ * - Object keys are sorted lexicographically by code point.
13
+ * - Strings are encoded with the JSON.stringify default (RFC 8259).
14
+ * - Numbers are emitted via JSON.stringify; callers should restrict to
15
+ * integers or use string fields for high-precision values.
16
+ * - `undefined` properties are dropped. `null` is preserved.
17
+ * - Arrays preserve element order.
18
+ *
19
+ * Hashing uses SHA-256 supplied by the caller (via an `EncryptionCrypto`
20
+ * binding) so this module stays platform-agnostic.
21
+ */
22
+ type Json = null | boolean | number | string | Json[] | {
23
+ [key: string]: Json | undefined;
24
+ };
25
+ /**
26
+ * Produce the canonical JSON string for {@link value}. Object keys are
27
+ * sorted, `undefined` properties are dropped, and primitive types are
28
+ * encoded by `JSON.stringify`.
29
+ */
30
+ declare function canonicalize(value: Json | undefined): string;
31
+ declare function hexEncode(bytes: Uint8Array): string;
32
+ declare function hexDecode(hex: string): Uint8Array;
33
+ declare function base64Encode(bytes: Uint8Array): string;
34
+ declare function base64Decode(s: string): Uint8Array;
35
+ declare function utf8Encode(s: string): Uint8Array;
36
+ declare function utf8Decode(b: Uint8Array): string;
37
+ /**
38
+ * Compute `hexEncode(sha256(canonicalize(value)))`. The SHA-256 binding
39
+ * is injected so the module remains usable in both the WASM and pure-JS
40
+ * paths.
41
+ */
42
+ declare function canonicalHashHex(sha256: (bytes: Uint8Array) => Uint8Array, value: Json): string;
43
+
44
+ /**
45
+ * Type definitions for TinyCloud one-of-one encryption.
46
+ *
47
+ * Wire shapes mirror the protocol described in the encryption
48
+ * architecture: inline envelopes carry the encrypted symmetric key
49
+ * alongside the ciphertext; decrypt requests are short-lived UCAN
50
+ * invocations against a target node plus networkId.
51
+ */
52
+
53
+ /** Default ciphersuite identifier for v1 envelopes. */
54
+ declare const DEFAULT_ENCRYPTION_ALG: "x25519-aes256gcm/v1";
55
+ /** Inline-envelope schema version. */
56
+ declare const ENVELOPE_VERSION: 1;
57
+ /** Default key version on freshly-created networks. */
58
+ declare const DEFAULT_KEY_VERSION: 1;
59
+ /** Decrypt-invocation fact type. */
60
+ declare const DECRYPT_FACT_TYPE: "tinycloud.encryption.decrypt/v1";
61
+ /** Decrypt response type. */
62
+ declare const DECRYPT_RESULT_TYPE: "tinycloud.encryption.decrypt-result/v1";
63
+ /** Encryption service identifier (manifest long form). */
64
+ declare const ENCRYPTION_SERVICE: "tinycloud.encryption";
65
+ /** Short form used in recap/abilities maps. */
66
+ declare const ENCRYPTION_SERVICE_SHORT: "encryption";
67
+ /** Decrypt ability URN. */
68
+ declare const DECRYPT_ACTION: "tinycloud.encryption/decrypt";
69
+ /**
70
+ * Inline encrypted envelope persisted in KV/SQL records.
71
+ *
72
+ * - `encryptedSymmetricKey` is opaque to the SDK; only the network can
73
+ * unwrap it.
74
+ * - `encryptedSymmetricKeyHash` is the canonical hash of the wrapped key
75
+ * bytes (hex-encoded sha-256 of the base64 string's canonical JSON
76
+ * form). The node recomputes this on every decrypt request.
77
+ * - `ciphertext` and `aad` are payload bytes only; the node never sees
78
+ * them.
79
+ */
80
+ interface InlineEncryptedEnvelope {
81
+ /** Schema version. */
82
+ v: typeof ENVELOPE_VERSION;
83
+ /** Network id URN. */
84
+ networkId: string;
85
+ /** Ciphersuite identifier. */
86
+ alg: string;
87
+ /** Network key version that was used to wrap the symmetric key. */
88
+ keyVersion: number;
89
+ /** Base64-encoded wrapped symmetric key / capsule. */
90
+ encryptedSymmetricKey: string;
91
+ /** Hex sha-256 of the canonical encryptedSymmetricKey string. */
92
+ encryptedSymmetricKeyHash: string;
93
+ /** Base64-encoded payload ciphertext. */
94
+ ciphertext: string;
95
+ /** Base64-encoded associated data, if any. */
96
+ aad?: string;
97
+ /** Caller-supplied metadata. Not authenticated against the node. */
98
+ metadata?: Record<string, string>;
99
+ }
100
+ /**
101
+ * Node-published network descriptor. The node DB is authoritative; a
102
+ * cached copy may also live under
103
+ * `.well-known/encryption/network/<name>` in the owner's account
104
+ * space (a discovery record only).
105
+ */
106
+ interface NetworkDescriptor {
107
+ networkId: string;
108
+ ownerDid: string;
109
+ name: string;
110
+ members: ReadonlyArray<{
111
+ nodeId: string;
112
+ role: "primary" | "share";
113
+ }>;
114
+ threshold: {
115
+ n: number;
116
+ t: number;
117
+ };
118
+ state: "pending" | "generating" | "active" | "rotating" | "revoked" | "failed";
119
+ /** Base64-encoded network public key. */
120
+ publicEncryptionKey: string;
121
+ alg: string;
122
+ keyVersion: number;
123
+ keyBackend: "local-one-of-one" | "dstack" | "threshold";
124
+ createdAt: string;
125
+ updatedAt: string;
126
+ }
127
+ /**
128
+ * Decrypt-request body sent over the wire. Hashed (canonically) and
129
+ * bound to the UCAN invocation via `facts.bodyHash`.
130
+ */
131
+ interface DecryptRequestBody {
132
+ type: typeof DECRYPT_FACT_TYPE;
133
+ targetNode: string;
134
+ networkId: string;
135
+ alg: string;
136
+ keyVersion: number;
137
+ /** Base64-encoded wrapped symmetric key from the envelope. */
138
+ encryptedSymmetricKey: string;
139
+ /** Recomputed hash of the wrapped key. */
140
+ encryptedSymmetricKeyHash: string;
141
+ /** Base64-encoded per-request receiver public key. */
142
+ receiverPublicKey: string;
143
+ /** Hash of the receiver public key. */
144
+ receiverPublicKeyHash: string;
145
+ }
146
+ /**
147
+ * Decrypt-response body returned by the node. The SDK verifies the
148
+ * signature, recomputes hashes, then unwraps `wrappedKey` with the
149
+ * per-request receiver private key before decrypting the payload.
150
+ */
151
+ interface DecryptResponseBody {
152
+ type: typeof DECRYPT_RESULT_TYPE;
153
+ targetNode: string;
154
+ networkId: string;
155
+ invocationCid: string;
156
+ encryptedSymmetricKeyHash: string;
157
+ receiverPublicKeyHash: string;
158
+ /** Base64-encoded symmetric key re-encrypted to receiverPublicKey. */
159
+ wrappedKey: string;
160
+ alg: string;
161
+ keyVersion: number;
162
+ requestHash: string;
163
+ nodeId: string;
164
+ /** Base64-encoded ed25519 signature over canonical(response - signature field). */
165
+ nodeSignature: string;
166
+ }
167
+ /**
168
+ * Decrypt-invocation facts attached to the UCAN. Verifiers recompute
169
+ * `bodyHash`, `encryptedSymmetricKeyHash`, and `receiverPublicKeyHash`
170
+ * from the request body and reject any mismatch.
171
+ */
172
+ interface DecryptInvocationFact {
173
+ type: typeof DECRYPT_FACT_TYPE;
174
+ targetNode: string;
175
+ networkId: string;
176
+ bodyHash: string;
177
+ encryptedSymmetricKeyHash: string;
178
+ receiverPublicKeyHash: string;
179
+ alg: string;
180
+ keyVersion: number;
181
+ }
182
+ /**
183
+ * Per-request receiver key pair (x25519). The private key never
184
+ * leaves the SDK; the public key is sent to the node so the node can
185
+ * rewrap the symmetric key.
186
+ */
187
+ interface ReceiverKeyPair {
188
+ publicKey: Uint8Array;
189
+ privateKey: Uint8Array;
190
+ }
191
+ /**
192
+ * Crypto primitives injected into the encryption module. The SDK
193
+ * provides these via WASM bindings; tests provide simple in-memory
194
+ * implementations.
195
+ */
196
+ interface EncryptionCrypto {
197
+ /** SHA-256 → 32-byte digest. */
198
+ sha256(data: Uint8Array): Uint8Array;
199
+ /** Cryptographically secure random bytes. */
200
+ randomBytes(length: number): Uint8Array;
201
+ /** Derive an x25519 key pair from a 32-byte seed. */
202
+ x25519FromSeed(seed: Uint8Array): ReceiverKeyPair;
203
+ /** Compute the x25519 ECDH shared secret. */
204
+ x25519Dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;
205
+ /** Authenticated symmetric encryption (the node's symmetric scheme). */
206
+ authEncrypt(key: Uint8Array, plaintext: Uint8Array, aad?: Uint8Array): Uint8Array;
207
+ /** Authenticated symmetric decryption (matched to authEncrypt). */
208
+ authDecrypt(key: Uint8Array, ciphertext: Uint8Array, aad?: Uint8Array): Uint8Array;
209
+ /**
210
+ * Wrap a symmetric key for the network's public encryption key using
211
+ * a sealed-box / hpke / x25519+symmetric construction. Implementation
212
+ * is opaque; only the node can unwrap.
213
+ */
214
+ sealToNetworkKey(networkPublicKey: Uint8Array, symmetricKey: Uint8Array): Uint8Array;
215
+ /**
216
+ * Open a wrapped symmetric key that was re-encrypted to the
217
+ * per-request receiver public key. The matching private key must be
218
+ * supplied here; the SDK never sends it to the node.
219
+ */
220
+ openWithReceiverKey(receiverPrivateKey: Uint8Array, wrappedKey: Uint8Array): Uint8Array;
221
+ /**
222
+ * Verify an ed25519 signature over `message` produced by the node
223
+ * identified by `nodeId` (the public-key DID).
224
+ */
225
+ verifyNodeSignature(nodeId: string, message: Uint8Array, signature: Uint8Array): boolean;
226
+ }
227
+ /**
228
+ * Signer interface used to derive a receiver key pair from a wallet or
229
+ * session signer. The signature is HKDF-extracted into the receiver
230
+ * seed so the public key is reproducible given the same context.
231
+ */
232
+ interface ReceiverKeySigner {
233
+ signMessage(message: string): Promise<string>;
234
+ }
235
+ /** Capability proof material accompanying a decrypt invocation. */
236
+ interface DecryptCapabilityProof {
237
+ /** Delegation chain CIDs rooted at the network owner DID. */
238
+ proofs: ReadonlyArray<string>;
239
+ /** Optional Authorization header value to use instead of building one. */
240
+ authorization?: string;
241
+ }
242
+ /**
243
+ * Inputs to the decrypt invocation builder.
244
+ */
245
+ interface BuildDecryptInvocationInput {
246
+ /** Target node DID — also the UCAN audience. */
247
+ targetNode: string;
248
+ /** Network id URN — also the recap resource. */
249
+ networkId: string;
250
+ /** Canonical body that will be POSTed. */
251
+ body: DecryptRequestBody;
252
+ /** Facts include hashes bound to the canonical body. */
253
+ facts: DecryptInvocationFact;
254
+ /** Capability proof chain. */
255
+ proof: DecryptCapabilityProof;
256
+ /** Optional `nbf` UCAN field as an ISO date string. */
257
+ notBefore?: string;
258
+ /** Optional `exp` UCAN field as an ISO date string. */
259
+ expiration?: string;
260
+ }
261
+ /**
262
+ * The output of {@link buildDecryptInvocation}.
263
+ */
264
+ interface BuiltDecryptInvocation {
265
+ /** HTTP `Authorization` header value. */
266
+ authorization: string;
267
+ /** CID of the invocation (used by the node response binding). */
268
+ invocationCid: string;
269
+ /** Canonical body string the node will hash. */
270
+ canonicalBody: string;
271
+ }
272
+ /**
273
+ * Signer interface for producing the decrypt invocation. WASM bindings
274
+ * implement this with the same session signer used for KV/SQL
275
+ * invocations; tests can stub it.
276
+ */
277
+ interface DecryptInvocationSigner {
278
+ signDecryptInvocation(input: BuildDecryptInvocationInput): Promise<BuiltDecryptInvocation>;
279
+ }
280
+ /**
281
+ * Errors thrown / returned from the encryption module.
282
+ */
283
+ type EncryptionErrorInput = {
284
+ code: "NETWORK_NOT_FOUND";
285
+ networkId?: string;
286
+ name?: string;
287
+ message?: string;
288
+ } | {
289
+ code: "NETWORK_NOT_ACTIVE";
290
+ state: string;
291
+ message?: string;
292
+ } | {
293
+ code: "INVALID_NETWORK_ID";
294
+ message: string;
295
+ } | {
296
+ code: "INVALID_ENVELOPE";
297
+ message: string;
298
+ } | {
299
+ code: "DECRYPT_DENIED";
300
+ message: string;
301
+ permissionHint?: PermissionHint;
302
+ } | {
303
+ code: "INVALID_RESPONSE";
304
+ message: string;
305
+ } | {
306
+ code: "RESPONSE_SIGNATURE_INVALID";
307
+ message?: string;
308
+ } | {
309
+ code: "RESPONSE_BINDING_MISMATCH";
310
+ field: string;
311
+ message?: string;
312
+ } | {
313
+ code: "TRANSPORT_ERROR";
314
+ cause: Error;
315
+ message?: string;
316
+ } | {
317
+ code: "INVALID_INPUT";
318
+ message: string;
319
+ };
320
+ type EncryptionError = EncryptionErrorInput & {
321
+ service: "encryption";
322
+ message: string;
323
+ };
324
+ declare function encryptionError(input: EncryptionErrorInput): EncryptionError;
325
+ /** Re-export for ergonomic typing of canonical payloads. */
326
+ type CanonicalJson = Json;
327
+
328
+ export { type BuildDecryptInvocationInput as B, type CanonicalJson as C, type DecryptCapabilityProof as D, type EncryptionCrypto as E, type InlineEncryptedEnvelope as I, type Json as J, type NetworkDescriptor as N, type ReceiverKeyPair as R, type BuiltDecryptInvocation as a, DECRYPT_ACTION as b, DECRYPT_FACT_TYPE as c, DECRYPT_RESULT_TYPE as d, DEFAULT_ENCRYPTION_ALG as e, DEFAULT_KEY_VERSION as f, type DecryptInvocationFact as g, type DecryptInvocationSigner as h, type DecryptRequestBody as i, type DecryptResponseBody as j, ENCRYPTION_SERVICE as k, ENCRYPTION_SERVICE_SHORT as l, ENVELOPE_VERSION as m, type EncryptionError as n, type EncryptionErrorInput as o, type ReceiverKeySigner as p, base64Decode as q, base64Encode as r, canonicalHashHex as s, canonicalize as t, encryptionError as u, hexDecode as v, hexEncode as w, utf8Decode as x, utf8Encode as y };
@@ -0,0 +1,328 @@
1
+ import { P as PermissionHint } from './types-DAOyIbXu.cjs';
2
+
3
+ /**
4
+ * Canonical JSON serialization and content hashing for TinyCloud
5
+ * encryption requests/responses.
6
+ *
7
+ * The node and SDK must agree byte-for-byte on the canonical form so
8
+ * that body-hash bindings (`bodyHash`, `encryptedSymmetricKeyHash`,
9
+ * `receiverPublicKeyHash`) verify on both sides.
10
+ *
11
+ * Canonical rules:
12
+ * - Object keys are sorted lexicographically by code point.
13
+ * - Strings are encoded with the JSON.stringify default (RFC 8259).
14
+ * - Numbers are emitted via JSON.stringify; callers should restrict to
15
+ * integers or use string fields for high-precision values.
16
+ * - `undefined` properties are dropped. `null` is preserved.
17
+ * - Arrays preserve element order.
18
+ *
19
+ * Hashing uses SHA-256 supplied by the caller (via an `EncryptionCrypto`
20
+ * binding) so this module stays platform-agnostic.
21
+ */
22
+ type Json = null | boolean | number | string | Json[] | {
23
+ [key: string]: Json | undefined;
24
+ };
25
+ /**
26
+ * Produce the canonical JSON string for {@link value}. Object keys are
27
+ * sorted, `undefined` properties are dropped, and primitive types are
28
+ * encoded by `JSON.stringify`.
29
+ */
30
+ declare function canonicalize(value: Json | undefined): string;
31
+ declare function hexEncode(bytes: Uint8Array): string;
32
+ declare function hexDecode(hex: string): Uint8Array;
33
+ declare function base64Encode(bytes: Uint8Array): string;
34
+ declare function base64Decode(s: string): Uint8Array;
35
+ declare function utf8Encode(s: string): Uint8Array;
36
+ declare function utf8Decode(b: Uint8Array): string;
37
+ /**
38
+ * Compute `hexEncode(sha256(canonicalize(value)))`. The SHA-256 binding
39
+ * is injected so the module remains usable in both the WASM and pure-JS
40
+ * paths.
41
+ */
42
+ declare function canonicalHashHex(sha256: (bytes: Uint8Array) => Uint8Array, value: Json): string;
43
+
44
+ /**
45
+ * Type definitions for TinyCloud one-of-one encryption.
46
+ *
47
+ * Wire shapes mirror the protocol described in the encryption
48
+ * architecture: inline envelopes carry the encrypted symmetric key
49
+ * alongside the ciphertext; decrypt requests are short-lived UCAN
50
+ * invocations against a target node plus networkId.
51
+ */
52
+
53
+ /** Default ciphersuite identifier for v1 envelopes. */
54
+ declare const DEFAULT_ENCRYPTION_ALG: "x25519-aes256gcm/v1";
55
+ /** Inline-envelope schema version. */
56
+ declare const ENVELOPE_VERSION: 1;
57
+ /** Default key version on freshly-created networks. */
58
+ declare const DEFAULT_KEY_VERSION: 1;
59
+ /** Decrypt-invocation fact type. */
60
+ declare const DECRYPT_FACT_TYPE: "tinycloud.encryption.decrypt/v1";
61
+ /** Decrypt response type. */
62
+ declare const DECRYPT_RESULT_TYPE: "tinycloud.encryption.decrypt-result/v1";
63
+ /** Encryption service identifier (manifest long form). */
64
+ declare const ENCRYPTION_SERVICE: "tinycloud.encryption";
65
+ /** Short form used in recap/abilities maps. */
66
+ declare const ENCRYPTION_SERVICE_SHORT: "encryption";
67
+ /** Decrypt ability URN. */
68
+ declare const DECRYPT_ACTION: "tinycloud.encryption/decrypt";
69
+ /**
70
+ * Inline encrypted envelope persisted in KV/SQL records.
71
+ *
72
+ * - `encryptedSymmetricKey` is opaque to the SDK; only the network can
73
+ * unwrap it.
74
+ * - `encryptedSymmetricKeyHash` is the canonical hash of the wrapped key
75
+ * bytes (hex-encoded sha-256 of the base64 string's canonical JSON
76
+ * form). The node recomputes this on every decrypt request.
77
+ * - `ciphertext` and `aad` are payload bytes only; the node never sees
78
+ * them.
79
+ */
80
+ interface InlineEncryptedEnvelope {
81
+ /** Schema version. */
82
+ v: typeof ENVELOPE_VERSION;
83
+ /** Network id URN. */
84
+ networkId: string;
85
+ /** Ciphersuite identifier. */
86
+ alg: string;
87
+ /** Network key version that was used to wrap the symmetric key. */
88
+ keyVersion: number;
89
+ /** Base64-encoded wrapped symmetric key / capsule. */
90
+ encryptedSymmetricKey: string;
91
+ /** Hex sha-256 of the canonical encryptedSymmetricKey string. */
92
+ encryptedSymmetricKeyHash: string;
93
+ /** Base64-encoded payload ciphertext. */
94
+ ciphertext: string;
95
+ /** Base64-encoded associated data, if any. */
96
+ aad?: string;
97
+ /** Caller-supplied metadata. Not authenticated against the node. */
98
+ metadata?: Record<string, string>;
99
+ }
100
+ /**
101
+ * Node-published network descriptor. The node DB is authoritative; a
102
+ * cached copy may also live under
103
+ * `.well-known/encryption/network/<name>` in the owner's account
104
+ * space (a discovery record only).
105
+ */
106
+ interface NetworkDescriptor {
107
+ networkId: string;
108
+ ownerDid: string;
109
+ name: string;
110
+ members: ReadonlyArray<{
111
+ nodeId: string;
112
+ role: "primary" | "share";
113
+ }>;
114
+ threshold: {
115
+ n: number;
116
+ t: number;
117
+ };
118
+ state: "pending" | "generating" | "active" | "rotating" | "revoked" | "failed";
119
+ /** Base64-encoded network public key. */
120
+ publicEncryptionKey: string;
121
+ alg: string;
122
+ keyVersion: number;
123
+ keyBackend: "local-one-of-one" | "dstack" | "threshold";
124
+ createdAt: string;
125
+ updatedAt: string;
126
+ }
127
+ /**
128
+ * Decrypt-request body sent over the wire. Hashed (canonically) and
129
+ * bound to the UCAN invocation via `facts.bodyHash`.
130
+ */
131
+ interface DecryptRequestBody {
132
+ type: typeof DECRYPT_FACT_TYPE;
133
+ targetNode: string;
134
+ networkId: string;
135
+ alg: string;
136
+ keyVersion: number;
137
+ /** Base64-encoded wrapped symmetric key from the envelope. */
138
+ encryptedSymmetricKey: string;
139
+ /** Recomputed hash of the wrapped key. */
140
+ encryptedSymmetricKeyHash: string;
141
+ /** Base64-encoded per-request receiver public key. */
142
+ receiverPublicKey: string;
143
+ /** Hash of the receiver public key. */
144
+ receiverPublicKeyHash: string;
145
+ }
146
+ /**
147
+ * Decrypt-response body returned by the node. The SDK verifies the
148
+ * signature, recomputes hashes, then unwraps `wrappedKey` with the
149
+ * per-request receiver private key before decrypting the payload.
150
+ */
151
+ interface DecryptResponseBody {
152
+ type: typeof DECRYPT_RESULT_TYPE;
153
+ targetNode: string;
154
+ networkId: string;
155
+ invocationCid: string;
156
+ encryptedSymmetricKeyHash: string;
157
+ receiverPublicKeyHash: string;
158
+ /** Base64-encoded symmetric key re-encrypted to receiverPublicKey. */
159
+ wrappedKey: string;
160
+ alg: string;
161
+ keyVersion: number;
162
+ requestHash: string;
163
+ nodeId: string;
164
+ /** Base64-encoded ed25519 signature over canonical(response - signature field). */
165
+ nodeSignature: string;
166
+ }
167
+ /**
168
+ * Decrypt-invocation facts attached to the UCAN. Verifiers recompute
169
+ * `bodyHash`, `encryptedSymmetricKeyHash`, and `receiverPublicKeyHash`
170
+ * from the request body and reject any mismatch.
171
+ */
172
+ interface DecryptInvocationFact {
173
+ type: typeof DECRYPT_FACT_TYPE;
174
+ targetNode: string;
175
+ networkId: string;
176
+ bodyHash: string;
177
+ encryptedSymmetricKeyHash: string;
178
+ receiverPublicKeyHash: string;
179
+ alg: string;
180
+ keyVersion: number;
181
+ }
182
+ /**
183
+ * Per-request receiver key pair (x25519). The private key never
184
+ * leaves the SDK; the public key is sent to the node so the node can
185
+ * rewrap the symmetric key.
186
+ */
187
+ interface ReceiverKeyPair {
188
+ publicKey: Uint8Array;
189
+ privateKey: Uint8Array;
190
+ }
191
+ /**
192
+ * Crypto primitives injected into the encryption module. The SDK
193
+ * provides these via WASM bindings; tests provide simple in-memory
194
+ * implementations.
195
+ */
196
+ interface EncryptionCrypto {
197
+ /** SHA-256 → 32-byte digest. */
198
+ sha256(data: Uint8Array): Uint8Array;
199
+ /** Cryptographically secure random bytes. */
200
+ randomBytes(length: number): Uint8Array;
201
+ /** Derive an x25519 key pair from a 32-byte seed. */
202
+ x25519FromSeed(seed: Uint8Array): ReceiverKeyPair;
203
+ /** Compute the x25519 ECDH shared secret. */
204
+ x25519Dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;
205
+ /** Authenticated symmetric encryption (the node's symmetric scheme). */
206
+ authEncrypt(key: Uint8Array, plaintext: Uint8Array, aad?: Uint8Array): Uint8Array;
207
+ /** Authenticated symmetric decryption (matched to authEncrypt). */
208
+ authDecrypt(key: Uint8Array, ciphertext: Uint8Array, aad?: Uint8Array): Uint8Array;
209
+ /**
210
+ * Wrap a symmetric key for the network's public encryption key using
211
+ * a sealed-box / hpke / x25519+symmetric construction. Implementation
212
+ * is opaque; only the node can unwrap.
213
+ */
214
+ sealToNetworkKey(networkPublicKey: Uint8Array, symmetricKey: Uint8Array): Uint8Array;
215
+ /**
216
+ * Open a wrapped symmetric key that was re-encrypted to the
217
+ * per-request receiver public key. The matching private key must be
218
+ * supplied here; the SDK never sends it to the node.
219
+ */
220
+ openWithReceiverKey(receiverPrivateKey: Uint8Array, wrappedKey: Uint8Array): Uint8Array;
221
+ /**
222
+ * Verify an ed25519 signature over `message` produced by the node
223
+ * identified by `nodeId` (the public-key DID).
224
+ */
225
+ verifyNodeSignature(nodeId: string, message: Uint8Array, signature: Uint8Array): boolean;
226
+ }
227
+ /**
228
+ * Signer interface used to derive a receiver key pair from a wallet or
229
+ * session signer. The signature is HKDF-extracted into the receiver
230
+ * seed so the public key is reproducible given the same context.
231
+ */
232
+ interface ReceiverKeySigner {
233
+ signMessage(message: string): Promise<string>;
234
+ }
235
+ /** Capability proof material accompanying a decrypt invocation. */
236
+ interface DecryptCapabilityProof {
237
+ /** Delegation chain CIDs rooted at the network owner DID. */
238
+ proofs: ReadonlyArray<string>;
239
+ /** Optional Authorization header value to use instead of building one. */
240
+ authorization?: string;
241
+ }
242
+ /**
243
+ * Inputs to the decrypt invocation builder.
244
+ */
245
+ interface BuildDecryptInvocationInput {
246
+ /** Target node DID — also the UCAN audience. */
247
+ targetNode: string;
248
+ /** Network id URN — also the recap resource. */
249
+ networkId: string;
250
+ /** Canonical body that will be POSTed. */
251
+ body: DecryptRequestBody;
252
+ /** Facts include hashes bound to the canonical body. */
253
+ facts: DecryptInvocationFact;
254
+ /** Capability proof chain. */
255
+ proof: DecryptCapabilityProof;
256
+ /** Optional `nbf` UCAN field as an ISO date string. */
257
+ notBefore?: string;
258
+ /** Optional `exp` UCAN field as an ISO date string. */
259
+ expiration?: string;
260
+ }
261
+ /**
262
+ * The output of {@link buildDecryptInvocation}.
263
+ */
264
+ interface BuiltDecryptInvocation {
265
+ /** HTTP `Authorization` header value. */
266
+ authorization: string;
267
+ /** CID of the invocation (used by the node response binding). */
268
+ invocationCid: string;
269
+ /** Canonical body string the node will hash. */
270
+ canonicalBody: string;
271
+ }
272
+ /**
273
+ * Signer interface for producing the decrypt invocation. WASM bindings
274
+ * implement this with the same session signer used for KV/SQL
275
+ * invocations; tests can stub it.
276
+ */
277
+ interface DecryptInvocationSigner {
278
+ signDecryptInvocation(input: BuildDecryptInvocationInput): Promise<BuiltDecryptInvocation>;
279
+ }
280
+ /**
281
+ * Errors thrown / returned from the encryption module.
282
+ */
283
+ type EncryptionErrorInput = {
284
+ code: "NETWORK_NOT_FOUND";
285
+ networkId?: string;
286
+ name?: string;
287
+ message?: string;
288
+ } | {
289
+ code: "NETWORK_NOT_ACTIVE";
290
+ state: string;
291
+ message?: string;
292
+ } | {
293
+ code: "INVALID_NETWORK_ID";
294
+ message: string;
295
+ } | {
296
+ code: "INVALID_ENVELOPE";
297
+ message: string;
298
+ } | {
299
+ code: "DECRYPT_DENIED";
300
+ message: string;
301
+ permissionHint?: PermissionHint;
302
+ } | {
303
+ code: "INVALID_RESPONSE";
304
+ message: string;
305
+ } | {
306
+ code: "RESPONSE_SIGNATURE_INVALID";
307
+ message?: string;
308
+ } | {
309
+ code: "RESPONSE_BINDING_MISMATCH";
310
+ field: string;
311
+ message?: string;
312
+ } | {
313
+ code: "TRANSPORT_ERROR";
314
+ cause: Error;
315
+ message?: string;
316
+ } | {
317
+ code: "INVALID_INPUT";
318
+ message: string;
319
+ };
320
+ type EncryptionError = EncryptionErrorInput & {
321
+ service: "encryption";
322
+ message: string;
323
+ };
324
+ declare function encryptionError(input: EncryptionErrorInput): EncryptionError;
325
+ /** Re-export for ergonomic typing of canonical payloads. */
326
+ type CanonicalJson = Json;
327
+
328
+ export { type BuildDecryptInvocationInput as B, type CanonicalJson as C, type DecryptCapabilityProof as D, type EncryptionCrypto as E, type InlineEncryptedEnvelope as I, type Json as J, type NetworkDescriptor as N, type ReceiverKeyPair as R, type BuiltDecryptInvocation as a, DECRYPT_ACTION as b, DECRYPT_FACT_TYPE as c, DECRYPT_RESULT_TYPE as d, DEFAULT_ENCRYPTION_ALG as e, DEFAULT_KEY_VERSION as f, type DecryptInvocationFact as g, type DecryptInvocationSigner as h, type DecryptRequestBody as i, type DecryptResponseBody as j, ENCRYPTION_SERVICE as k, ENCRYPTION_SERVICE_SHORT as l, ENVELOPE_VERSION as m, type EncryptionError as n, type EncryptionErrorInput as o, type ReceiverKeySigner as p, base64Decode as q, base64Encode as r, canonicalHashHex as s, canonicalize as t, encryptionError as u, hexDecode as v, hexEncode as w, utf8Decode as x, utf8Encode as y };