@dstorage-tech/dstorage-sdk 0.0.4

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 (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +530 -0
  3. package/dist/KeypairEncryptionAdapter-AE75YC4W-AOWNSH2M.mjs +9 -0
  4. package/dist/KeypairEncryptionAdapter-AE75YC4W-BAVHRNNJ.mjs +1 -0
  5. package/dist/KeypairEncryptionAdapter-AE75YC4W-BEYO4RUO.mjs +1 -0
  6. package/dist/KeypairEncryptionAdapter-AE75YC4W-VAOH6AAL.mjs +9 -0
  7. package/dist/KeypairEncryptionAdapter-XUKCLRFU-6ERIZN2M.mjs +1 -0
  8. package/dist/KeypairEncryptionAdapter-XUKCLRFU-AYDAZ2TZ.mjs +9 -0
  9. package/dist/KeypairEncryptionAdapter-XUKCLRFU-ERPYK5S4.mjs +8 -0
  10. package/dist/MnemonicEncryptionAdapter-J6IE5OKA-6DFVUVD6.mjs +1 -0
  11. package/dist/MnemonicEncryptionAdapter-J6IE5OKA-O5AJPX42.mjs +1 -0
  12. package/dist/MnemonicEncryptionAdapter-J6IE5OKA-SI6TBLTQ.mjs +9 -0
  13. package/dist/MnemonicEncryptionAdapter-J6IE5OKA-WEPFOTSJ.mjs +9 -0
  14. package/dist/MnemonicEncryptionAdapter-RCHUETBP-DZPBGQG6.mjs +8 -0
  15. package/dist/MnemonicEncryptionAdapter-RCHUETBP-ELAMJMMO.mjs +1 -0
  16. package/dist/MnemonicEncryptionAdapter-RCHUETBP-M7NHGSHO.mjs +9 -0
  17. package/dist/PasswordEncryptionAdapter-CWOXUGR4-2YZ64B4A.mjs +1 -0
  18. package/dist/PasswordEncryptionAdapter-CWOXUGR4-DCEGC2NX.mjs +1 -0
  19. package/dist/PasswordEncryptionAdapter-CWOXUGR4-QEGGYPFJ.mjs +13 -0
  20. package/dist/PasswordEncryptionAdapter-CWOXUGR4-ZYUBUYUI.mjs +13 -0
  21. package/dist/PasswordEncryptionAdapter-ECHND672-3DEFO6FP.mjs +13 -0
  22. package/dist/PasswordEncryptionAdapter-ECHND672-MUTHAMZY.mjs +12 -0
  23. package/dist/PasswordEncryptionAdapter-ECHND672-XVBPHPPT.mjs +1 -0
  24. package/dist/browser.d.mts +2418 -0
  25. package/dist/browser.mjs +5175 -0
  26. package/dist/chunk-25I6ZXUC.mjs +9403 -0
  27. package/dist/chunk-4X5K43JF.mjs +62 -0
  28. package/dist/chunk-4YMF57VY.mjs +1 -0
  29. package/dist/chunk-5MZ7FPPY.mjs +1 -0
  30. package/dist/chunk-5P4EW2YL.mjs +1 -0
  31. package/dist/chunk-5QOKJEH3.mjs +8 -0
  32. package/dist/chunk-5RW7SGA7.mjs +1 -0
  33. package/dist/chunk-62RSKZ6T.mjs +118 -0
  34. package/dist/chunk-6IAQVMSM.mjs +102 -0
  35. package/dist/chunk-BBJCQFWP.mjs +275 -0
  36. package/dist/chunk-BWLEAAFW.mjs +2599 -0
  37. package/dist/chunk-EYF3263P.mjs +2049 -0
  38. package/dist/chunk-FJ7LSZOW.mjs +5537 -0
  39. package/dist/chunk-GUYENY5N.mjs +1 -0
  40. package/dist/chunk-HDD6SUU4.mjs +276 -0
  41. package/dist/chunk-JMPRZK5D.mjs +62 -0
  42. package/dist/chunk-L5QD6GHB.mjs +101 -0
  43. package/dist/chunk-O37NHERH.mjs +17 -0
  44. package/dist/chunk-OLGVVM5Y.mjs +102 -0
  45. package/dist/chunk-PKHRAYFD.mjs +1 -0
  46. package/dist/chunk-PLAOCKSS.mjs +101 -0
  47. package/dist/chunk-QKA2DCR6.mjs +118 -0
  48. package/dist/chunk-RPSRFFXN.mjs +275 -0
  49. package/dist/chunk-TESUOXRJ.mjs +1 -0
  50. package/dist/chunk-TMLXCRJU.mjs +1 -0
  51. package/dist/chunk-TNRKN4LB.mjs +1 -0
  52. package/dist/chunk-TSZ37JDY.mjs +2596 -0
  53. package/dist/chunk-U3MS6KMF.mjs +1 -0
  54. package/dist/chunk-UBALMYIY.mjs +2049 -0
  55. package/dist/chunk-UDYXMII2.mjs +121 -0
  56. package/dist/chunk-UJCSKKID.mjs +30 -0
  57. package/dist/chunk-UOOF4V2Y.mjs +1 -0
  58. package/dist/chunk-VDZ7F7MP.mjs +1329 -0
  59. package/dist/chunk-X4LEBNK6.mjs +276 -0
  60. package/dist/chunk-Z2TH6U4C.mjs +3 -0
  61. package/dist/chunk-Z6DUAI5B.mjs +121 -0
  62. package/dist/chunk-ZEPZ4QDD.mjs +1 -0
  63. package/dist/chunk-ZGUY5EIR.mjs +1 -0
  64. package/dist/cjs-RMZ3L2IO.mjs +5 -0
  65. package/dist/contract-api-AO4RGPLT-4HRCMSCE.mjs +279 -0
  66. package/dist/contract-api-AO4RGPLT-ADH6ZDKC.mjs +279 -0
  67. package/dist/contract-api-AO4RGPLT-ENC72WCG.mjs +280 -0
  68. package/dist/contract-api-AO4RGPLT-PAMIPEI3.mjs +1 -0
  69. package/dist/contract-api-AO4RGPLT-W3RSVP5A.mjs +1 -0
  70. package/dist/contract-api-AO4RGPLT-WENYDV6I.mjs +1 -0
  71. package/dist/contract-api-TJ7JPHZA-6FUBJ6DS.mjs +279 -0
  72. package/dist/contract-api-TJ7JPHZA-ZWP3EH7D.mjs +279 -0
  73. package/dist/contracts/dataregistry/managed/keys/removeReference.prover +0 -0
  74. package/dist/contracts/dataregistry/managed/keys/removeReference.verifier +0 -0
  75. package/dist/contracts/dataregistry/managed/keys/storeReference.prover +0 -0
  76. package/dist/contracts/dataregistry/managed/keys/storeReference.verifier +0 -0
  77. package/dist/contracts/dataregistry/managed/keys/updateReference.prover +0 -0
  78. package/dist/contracts/dataregistry/managed/keys/updateReference.verifier +0 -0
  79. package/dist/contracts/dataregistry/managed/zkir/removeReference.bzkir +0 -0
  80. package/dist/contracts/dataregistry/managed/zkir/removeReference.zkir +138 -0
  81. package/dist/contracts/dataregistry/managed/zkir/storeReference.bzkir +0 -0
  82. package/dist/contracts/dataregistry/managed/zkir/storeReference.zkir +158 -0
  83. package/dist/contracts/dataregistry/managed/zkir/updateReference.bzkir +0 -0
  84. package/dist/contracts/dataregistry/managed/zkir/updateReference.zkir +190 -0
  85. package/dist/dataregistry-simulator-E6RTGGWT-5YEGBW7P.mjs +108 -0
  86. package/dist/dataregistry-simulator-E6RTGGWT-DJS4MHBD.mjs +109 -0
  87. package/dist/dataregistry-simulator-E6RTGGWT-QGCYR3VF.mjs +1 -0
  88. package/dist/dist-655VYUPJ.mjs +1 -0
  89. package/dist/dist-INTAFXQ7.mjs +65 -0
  90. package/dist/dist-MEZZWKP4.mjs +1 -0
  91. package/dist/dist-MOLWJ4Y7.mjs +64 -0
  92. package/dist/dist-UD4WRMYJ.mjs +65 -0
  93. package/dist/errors.d.mts +117 -0
  94. package/dist/errors.d.ts +117 -0
  95. package/dist/errors.js +2308 -0
  96. package/dist/errors.mjs +2278 -0
  97. package/dist/esm5-AGBDHMNS.mjs +1 -0
  98. package/dist/esm5-GFOBLUFI.mjs +350 -0
  99. package/dist/in-memory-private-state-NGOP37V7-DXWZE42Q.mjs +48 -0
  100. package/dist/in-memory-private-state-NGOP37V7-QXT3RUEH.mjs +49 -0
  101. package/dist/in-memory-private-state-NGOP37V7-XFJFNFCQ.mjs +1 -0
  102. package/dist/index.d.mts +2843 -0
  103. package/dist/index.d.ts +2843 -0
  104. package/dist/index.js +19639 -0
  105. package/dist/index.mjs +5177 -0
  106. package/package.json +87 -0
@@ -0,0 +1,2843 @@
1
+ import { PaymentAdapter, PaymentNetworkName, TokenSymbol, NetworkType, PaymentAdapterLogger, PaymentQuote, PaymentInstruction, PaymentReceipt, MidnightWalletProvider, StorageAdapterLogger, StorageAdapter, StorageProviderName, StorageUploadResult, StorageQuote, ChainAdapter, ChainProviderName, ChainAdapterLogger, ChainReference, ChainWriteResult, ChainReferenceUpdate, DataReferenceSummary, ChainQuote, WalletBalances } from './types.js';
2
+ export { ChainAdapter, ChainAdapterLogger, ChainProviderName, ChainQuote, ChainReference, ChainReferenceUpdate, ChainWriteResult, DataReferenceSummary, MidnightWalletProvider, NetworkType, PaymentAdapter, PaymentAdapterLogger, PaymentNetworkName, PaymentQuote, PaymentReceipt, StorageAdapter, StorageAdapterLogger, StorageProviderName, StorageQuote, StorageUploadResult, TOKENS, Token, TokenSymbol, WalletBalances } from './types.js';
3
+ import Arweave from 'arweave';
4
+ import Transaction from 'arweave/node/lib/transaction';
5
+ import { JWKInterface } from 'arweave/node/lib/wallet';
6
+ import { WalletProvider, MidnightProvider } from '@midnight-ntwrk/midnight-js-types';
7
+ import { WalletFacade, FacadeState } from '@midnight-ntwrk/wallet-sdk/facade';
8
+ import { NetworkId } from '@midnight-ntwrk/midnight-js-network-id';
9
+ export { NetworkId } from '@midnight-ntwrk/midnight-js-network-id';
10
+ export { ChainErrorCode, StorageErrorCode } from './errors.js';
11
+ export { MockChainAdapter, MockPaymentAdapter, MockStorageAdapter, MockStorageAdapterConfig } from './adapters/mock.js';
12
+
13
+ /**
14
+ * @dstorage/payment — adapters/arweave.ts
15
+ *
16
+ * Arweave payment adapter.
17
+ *
18
+ * ── Sign-then-post flow ───────────────────────────────────────────────────────
19
+ *
20
+ * On Arweave, data and fee share a single transaction object. The fee is
21
+ * deducted automatically when the transaction is posted — there is no
22
+ * separate payment channel.
23
+ *
24
+ * This adapter implements the two-phase flow supported by MetaTransaction:
25
+ *
26
+ * 1. provideUploadData(data, metadata)
27
+ * Called after encryption. Stores the data + metadata tags so that
28
+ * pay() can build the complete transaction without a separate round-trip.
29
+ *
30
+ * 2. pay(instruction, onStatus) [payment_storage step]
31
+ * Creates the Arweave transaction, attaches tags, and prompts the
32
+ * wallet for approval (ArConnect popup / JWK signing). Stores the
33
+ * signed transaction for the upload step to pick up.
34
+ *
35
+ * 3. ArweaveStorageAdapter.store() [store step]
36
+ * Detects the pre-signed transaction via consumeSignedTx() and simply
37
+ * posts it — no additional signing or wallet interaction needed.
38
+ *
39
+ * If provideUploadData() was not called (e.g. direct use outside MetaTransaction),
40
+ * pay() falls back to the pass-through behaviour and store() performs the full
41
+ * create → sign → post flow as before.
42
+ *
43
+ * Docs: https://docs.arweave.org/developers
44
+ */
45
+
46
+ type ArweaveWallet = JWKInterface | "use_wallet";
47
+ interface ArweavePaymentAdapterConfig {
48
+ /**
49
+ * Arweave gateway.
50
+ * Defaults to mainnet (arweave.net).
51
+ * Use { host: 'arweave.dev', port: 443, protocol: 'https' } for testnet.
52
+ * Use { host: 'localhost', port: 1984, protocol: 'http' } for arlocal.
53
+ *
54
+ * Security: always use `protocol: 'https'` (the default) in production.
55
+ * The SDK relies on standard OS/runtime TLS — no DNS or certificate pinning
56
+ * is applied. Users in adversarial network environments should enforce
57
+ * certificate pinning at the runtime level (e.g. a custom Node.js HTTPS
58
+ * agent or a trusted corporate proxy).
59
+ */
60
+ gateway?: {
61
+ host: string;
62
+ port: number;
63
+ protocol: "http" | "https";
64
+ };
65
+ /**
66
+ * JWK wallet key for Node.js server-side usage.
67
+ * In the browser leave undefined — ArConnect is used automatically.
68
+ */
69
+ walletKey?: Record<string, string>;
70
+ /**
71
+ * How long in ms before a quote expires.
72
+ * Defaults to 120_000 (2 minutes) — appropriate for Arweave's volatile pricing.
73
+ */
74
+ quoteValidityMs?: number;
75
+ /**
76
+ * Optional logger for SDK operational output.
77
+ */
78
+ logger?: PaymentAdapterLogger;
79
+ }
80
+ /** Internal state stored between provideUploadData() and pay(). */
81
+ interface PendingUpload {
82
+ data: Uint8Array;
83
+ metadata: Record<string, string>;
84
+ }
85
+ /** Result stored after pay() signs the transaction, consumed by store(). */
86
+ interface SignedArweaveUpload {
87
+ tx: Transaction;
88
+ /** AR cost string (e.g. "0.000001234") for the upload result. */
89
+ arCost: string;
90
+ }
91
+ declare class ArweavePaymentAdapter implements PaymentAdapter {
92
+ readonly network: PaymentNetworkName;
93
+ readonly token: TokenSymbol;
94
+ readonly type: NetworkType;
95
+ protected arweaveClient: Arweave | null;
96
+ protected readonly gateway: ArweavePaymentAdapterConfig["gateway"];
97
+ private readonly walletKey;
98
+ protected readonly quoteValidityMs: number;
99
+ protected readonly logger: PaymentAdapterLogger | undefined;
100
+ protected pendingUpload: PendingUpload | null;
101
+ protected signedUpload: SignedArweaveUpload | null;
102
+ constructor(config?: ArweavePaymentAdapterConfig);
103
+ protected getClient(): Promise<Arweave>;
104
+ protected resolveWallet(): ArweaveWallet;
105
+ /**
106
+ * Store the encrypted upload payload and metadata tags so that pay() can
107
+ * build and sign the complete Arweave transaction in one step.
108
+ * Called by MetaTransaction after the encrypt step, before pay().
109
+ */
110
+ provideUploadData(data: Uint8Array, metadata?: Record<string, string>): void;
111
+ /**
112
+ * Query the Arweave fee oracle for the real upload cost.
113
+ */
114
+ estimateCost(dataSizeBytes: number): Promise<PaymentQuote>;
115
+ /**
116
+ * Sign-then-store flow (when provideUploadData was called):
117
+ * Creates the Arweave transaction with data + tags, prompts the wallet
118
+ * for approval (ArConnect popup or JWK signing), and stores the signed
119
+ * transaction for ArweaveStorageAdapter.store() to post.
120
+ *
121
+ * Pass-through fallback (when provideUploadData was NOT called):
122
+ * Returns a receipt acknowledging that payment is bundled with the upload.
123
+ * ArweaveStorageAdapter.store() performs the full create → sign → post flow.
124
+ */
125
+ pay(instruction: PaymentInstruction, onStatus?: (message: string) => void): Promise<PaymentReceipt>;
126
+ /**
127
+ * Returns the pre-signed transaction produced by pay(), then clears it.
128
+ * Called by ArweaveStorageAdapter.store() to post the already-signed tx.
129
+ * Returns null if pay() did not sign a transaction (pass-through mode).
130
+ */
131
+ consumeSignedUpload(): SignedArweaveUpload | null;
132
+ }
133
+
134
+ /**
135
+ * @dstorage/payment — adapters/managed.ts
136
+ *
137
+ * Managed payment adapter — remote payment via dStorage API services.
138
+ *
139
+ * Routes payment to the correct network-specific flow based on
140
+ * PaymentQuote.network. All networks share the same endpoint:
141
+ * POST {baseUrl}{POST_SIGN_TX_API_PATH}
142
+ * Currently implemented:
143
+ * - "arweave": remote Arweave signing via REST API
144
+ * - "arweave_bundler": remote ANS-104 bundled-upload signing via REST API
145
+ * - "midnight": remote Midnight transaction balancing/signing via REST API
146
+ *
147
+ * ── Arweave flow ──────────────────────────────────────────────────────────────
148
+ *
149
+ * Instead of signing the Arweave transaction locally (ArConnect or JWK),
150
+ * this adapter constructs the Arweave transaction, computes the Merkle tree
151
+ * (data_root) locally, then sends a stripped transaction JSON — containing
152
+ * only metadata, data_root, and data_size but NOT the raw file bytes — to a
153
+ * remote REST API. The server holds a funded Arweave account, signs the
154
+ * stripped transaction, and returns the signature and id. The file content
155
+ * never leaves the client.
156
+ *
157
+ * POST {baseUrl}{POST_SIGN_TX_API_PATH}
158
+ * → { txData: object, network: string, userId: string }
159
+ * txData — Arweave transaction JSON with data stripped (tx.toJSON()
160
+ * after clearing tx.data; data_root + data_size preserved).
161
+ * network — Arweave network identifier (e.g. "arweave", "arlocal").
162
+ * userId — caller identity forwarded to the server.
163
+ * ← { txId: string, signature: string, publicKey: string, txAmount: string, ... }
164
+ * txId — valid 43-char base64url Arweave transaction id.
165
+ * signature — base64url RSA-PSS signature.
166
+ * publicKey — server wallet's RSA modulus n (base64url).
167
+ * The adapter calls tx.setSignature({ id, signature, owner }).
168
+ *
169
+ * ── Integration (Arweave) ─────────────────────────────────────────────────────
170
+ *
171
+ * ManagedPaymentAdapter extends ArweavePaymentAdapter and slots into the
172
+ * same sign-then-post flow used by ArweaveStorageAdapter:
173
+ *
174
+ * MetaTransaction:
175
+ * provideUploadData(data, metadata) ← stores data + tags
176
+ * pay(instruction, onStatus) ← routes by instruction.network, creates tx,
177
+ * sends JSON to server, applies signature
178
+ *
179
+ * ArweaveStorageAdapter.store():
180
+ * consumeSignedUpload() ← picks up the pre-signed tx
181
+ * postWithRetry(arweave, tx) ← broadcasts to Arweave network
182
+ */
183
+
184
+ interface ManagedPaymentAdapterConfig extends Omit<ArweavePaymentAdapterConfig, "walletKey"> {
185
+ /** Which network this adapter is used for */
186
+ network: PaymentNetworkName;
187
+ /** Whether this covers a storage network fee or a chain transaction fee */
188
+ type: NetworkType;
189
+ /**
190
+ * Base URL of the remote signing server (no trailing slash).
191
+ * Example: "https://api.my-server.com"
192
+ */
193
+ signingServerUrl: string;
194
+ /**
195
+ * Bearer token sent as the `Authorization` header to authenticate with the signing server.
196
+ * Must be a non-empty, non-whitespace string — the constructor throws immediately on
197
+ * an empty value so a misconfigured caller (e.g. unresolved env var) fails fast
198
+ * rather than silently sending unauthenticated requests to the signing service.
199
+ */
200
+ authToken: string;
201
+ /**
202
+ * Maximum time in milliseconds to wait for the signing server to respond before
203
+ * aborting the request and throwing. Defaults to 30 000 ms (30 s).
204
+ * Pass `0` to disable the timeout entirely (not recommended for production).
205
+ */
206
+ requestTimeoutMs?: number;
207
+ }
208
+ declare class ManagedPaymentAdapter extends ArweavePaymentAdapter {
209
+ readonly network: PaymentNetworkName;
210
+ readonly type: NetworkType;
211
+ private readonly signingServerUrl;
212
+ private readonly authToken;
213
+ private readonly requestTimeoutMs;
214
+ private readonly ownerPublicKey;
215
+ /**
216
+ * Strip a RSA-4096 modulus suffix from a compound auth token
217
+ * (<credential>.<base64url_683_chars>), returning only the credential.
218
+ * A plain token (no '.' or wrong suffix length) is returned unchanged.
219
+ * This lets ArweaveBundlerStorageAdapter compound tokens be passed directly
220
+ * to any adapter that uses ManagedPaymentAdapter without breaking authentication.
221
+ *
222
+ * lastIndexOf is intentional: the credential part may itself contain dots
223
+ * (e.g. a JWT), so we always split at the *last* dot to reach the modulus.
224
+ */
225
+ private static _parseAuthToken;
226
+ constructor(config: ManagedPaymentAdapterConfig);
227
+ /**
228
+ * Query the Arweave fee oracle for the real upload cost.
229
+ */
230
+ estimateCost(dataSizeBytes: number): Promise<PaymentQuote>;
231
+ /**
232
+ * Routes payment to the correct network-specific handler based on quote.network.
233
+ *
234
+ * The Arweave path falls back to the base-class pass-through if
235
+ * provideUploadData() was not called. An unrecognised network throws.
236
+ */
237
+ pay(instruction: PaymentInstruction, onStatus?: (message: string) => void): Promise<PaymentReceipt>;
238
+ /**
239
+ * Returns a WalletProvider-compatible object for the Midnight chain whose
240
+ * `balanceTx()` is fulfilled by the managed signing server instead of a
241
+ * local wallet. The caller supplies the public keys (from whichever source
242
+ * they have — HD derivation, a server endpoint, etc.); the SDK only handles
243
+ * the signing-server round-trip.
244
+ *
245
+ * The returned object satisfies the @midnight-ntwrk/midnight-js-types
246
+ * WalletProvider interface via structural typing — no Midnight package
247
+ * import is required from the caller's side.
248
+ *
249
+ * @param coinPublicKey Midnight coin public key (hex) for the ZK fee circuit.
250
+ * @param encryptionPublicKey Midnight encryption public key (hex).
251
+ * @param onReceipt Optional callback invoked with the PaymentReceipt
252
+ * after each successful balanceTx call. Used internally
253
+ * by MidnightChainAdapter to capture receipt metadata;
254
+ * external callers can omit it.
255
+ */
256
+ createMidnightWalletProvider(coinPublicKey: string, encryptionPublicKey: string, onReceipt?: (receipt: PaymentReceipt) => void): MidnightWalletProvider;
257
+ /**
258
+ * Arweave remote-signing flow:
259
+ * 1. Creates the Arweave transaction locally (data + tags, no local signing).
260
+ * 2. Calls prepareChunks() to compute data_root (Merkle root) locally.
261
+ * 3. Strips the raw data from the transaction before serialising — only the
262
+ * data_root and data_size (not the actual bytes) are sent to the server.
263
+ * 4. POSTs the stripped transaction JSON to the signing server.
264
+ * 5. Applies the returned id, signature, and owner to the transaction.
265
+ * 6. Restores the raw data so the chunked uploader can post it directly to
266
+ * the Arweave gateway — the server never sees the file content.
267
+ *
268
+ * Falls back to the base-class pass-through if provideUploadData() was not called.
269
+ */
270
+ private _payArweave;
271
+ /**
272
+ * Midnight payment flow:
273
+ * POSTs the fee amount to the dStorage API service, which holds a funded
274
+ * Midnight account and submits the chain transaction on behalf of the user.
275
+ *
276
+ * POST {baseUrl}{POST_SIGN_TX_API_PATH}
277
+ * → { txData: string (hex-serialized UnboundTransaction), network: string, userId: string }
278
+ * ← { txId: string, signature: string (hex-serialized FinalizedTransaction), ... }
279
+ *
280
+ * The hex-serialized FinalizedTransaction is returned in PaymentReceipt.signedTx
281
+ * for the chain adapter to deserialize and pass to submitTx().
282
+ */
283
+ private _payMidnight;
284
+ /**
285
+ * Arweave Bundler
286
+ */
287
+ private _payArweaveBundler;
288
+ /**
289
+ * Managed mock flow:
290
+ * Sends a minimal request to the signing server with the literal network
291
+ * identifier "TEST" — the server treats this as a sandbox/test flow with no
292
+ * real funds involved. The SDK-side network name is "managedmock" to follow
293
+ * the lowercase naming convention; the server-side string is always "TEST".
294
+ */
295
+ private _payManagedMock;
296
+ /**
297
+ * Shared HTTP helper: POSTs a transaction payload to the signing server and
298
+ * returns the parsed SignTxResponse.
299
+ *
300
+ * - Arweave: txJson is the Arweave tx JSON object (from tx.toJSON()); the server
301
+ * signs it and returns the signature + owner in the response fields.
302
+ * - Midnight: txJson is the hex-serialized UnboundTransaction; the server balances
303
+ * and signs it, returning the hex-serialized FinalizedTransaction in the
304
+ * `signature` response field.
305
+ *
306
+ * Throws on network errors or non-2xx HTTP responses.
307
+ */
308
+ private _sendSignTxRequest;
309
+ }
310
+
311
+ /**
312
+ * @dstorage/storage — adapters/arweave.ts
313
+ *
314
+ * Real Arweave storage adapter.
315
+ * Uploads encrypted blobs to the Arweave permaweb — pay once, store forever.
316
+ *
317
+ * ── Runtime environments ──────────────────────────────────────────────────────
318
+ *
319
+ * Browser (ArConnect):
320
+ * const adapter = new ArweaveStorageAdapter();
321
+ * // Requires the ArConnect extension: https://arconnect.io
322
+ *
323
+ * Node.js (JWK wallet file):
324
+ * const adapter = new ArweaveStorageAdapter({
325
+ * walletKey: JSON.parse(fs.readFileSync('wallet.json', 'utf8')),
326
+ * });
327
+ *
328
+ * ── Testnet ───────────────────────────────────────────────────────────────────
329
+ *
330
+ * const adapter = new ArweaveStorageAdapter({
331
+ * gateway: { host: 'arweave.dev', port: 443, protocol: 'https' },
332
+ * });
333
+ *
334
+ * ── Peer dependency ───────────────────────────────────────────────────────────
335
+ * npm install arweave
336
+ *
337
+ * ── Notes ─────────────────────────────────────────────────────────────────────
338
+ *
339
+ * • Arweave transactions are optimistic: a 202 response means accepted, not
340
+ * confirmed. Confirmation (inclusion in a block) typically takes 2–20 minutes.
341
+ * Set waitForConfirmation: true to block until the tx is on-chain.
342
+ *
343
+ * • For large files or high-volume uploads, consider Irys (https://irys.xyz)
344
+ * which bundles many transactions together for cheaper and near-instant
345
+ * finality. An IrysStorageAdapter can be added alongside this one.
346
+ *
347
+ * • storageId (txId) is PUBLIC on Arweave. Data security relies entirely on
348
+ * the XChaCha20-Poly1305 encryption applied by @dstorage/crypto before reaching here.
349
+ */
350
+
351
+ interface ArweaveGatewayConfig {
352
+ host: string;
353
+ port: number;
354
+ protocol: "http" | "https";
355
+ }
356
+ interface ArweaveAdapterConfig {
357
+ /**
358
+ * Arweave gateway to broadcast transactions to.
359
+ * Defaults to mainnet (arweave.net:443).
360
+ *
361
+ * Testnet: { host: 'arweave.dev', port: 443, protocol: 'https' }
362
+ *
363
+ * Security: always use `protocol: 'https'` (the default) in production.
364
+ * The SDK relies on standard OS/runtime TLS — no DNS or certificate pinning
365
+ * is applied. Users in adversarial network environments should enforce
366
+ * certificate pinning at the runtime level (e.g. a custom Node.js HTTPS
367
+ * agent or a trusted corporate proxy).
368
+ */
369
+ gateway?: ArweaveGatewayConfig;
370
+ /**
371
+ * JWK wallet key for Node.js server-side usage.
372
+ * Leave undefined in the browser — ArConnect is used automatically.
373
+ *
374
+ * Obtain a free wallet at https://arweave.app or generate via arweave-js:
375
+ * const jwk = await Arweave.init({}).wallets.generate();
376
+ */
377
+ walletKey?: Record<string, string>;
378
+ /**
379
+ * Base URL of a local ManagedPaymentAdapter signing server.
380
+ * When provided, the adapter uses ManagedPaymentAdapter (remote signing)
381
+ * instead of the default ArweavePaymentAdapter (local signing).
382
+ * Example: "http://localhost:3000"
383
+ */
384
+ signingServerUrl?: string;
385
+ /**
386
+ * Bearer token sent as the `Authorization` header to authenticate with the signing server.
387
+ * Required when `signingServerUrl` is provided.
388
+ */
389
+ authToken?: string;
390
+ /**
391
+ * How many times to retry a failed transaction post before throwing.
392
+ * Uses a simple linear back-off: 1 s, 2 s, 3 s…
393
+ * Defaults to 3.
394
+ */
395
+ maxRetries?: number;
396
+ /**
397
+ * If true, poll Arweave until the transaction is confirmed (block included)
398
+ * before returning from store(). Confirmation typically takes 2–20 minutes.
399
+ *
400
+ * Defaults to false (optimistic — returns as soon as the gateway accepts
401
+ * the transaction with HTTP 200 or 202).
402
+ */
403
+ waitForConfirmation?: boolean;
404
+ /**
405
+ * Polling interval in ms while waiting for confirmation.
406
+ * Defaults to 30_000 (30 seconds).
407
+ */
408
+ confirmationPollMs?: number;
409
+ /**
410
+ * Maximum time in ms to wait for confirmation before throwing a timeout error.
411
+ * Defaults to 1_200_000 (20 minutes).
412
+ */
413
+ confirmationTimeoutMs?: number;
414
+ /**
415
+ * When true, skip the BLAKE3 content-hash check on retrieve.
416
+ * By default (false) the adapter fetches the transaction metadata and verifies
417
+ * that the `X-Content-Hash` tag recorded at upload time matches the retrieved
418
+ * bytes. Set to true only if you trust the gateway entirely or are using an
419
+ * Arweave node that does not expose the transaction metadata endpoint.
420
+ */
421
+ skipIntegrityCheck?: boolean;
422
+ /**
423
+ * Maximum number of bytes allowed in a single retrieve() call.
424
+ * The adapter rejects the download before materialising the blob if the
425
+ * Arweave transaction metadata reports a larger `data_size`, and always
426
+ * rejects after loading if the actual byte count exceeds this value.
427
+ * Defaults to 268_435_456 (256 MB).
428
+ */
429
+ maxRetrieveSizeBytes?: number;
430
+ /**
431
+ * Optional logger for SDK operational output.
432
+ * Pass `logger: console` to see all output, or inject your own logger.
433
+ * Omit to suppress all SDK log output.
434
+ */
435
+ logger?: StorageAdapterLogger;
436
+ }
437
+ declare class ArweaveStorageAdapter implements StorageAdapter {
438
+ readonly name: StorageProviderName;
439
+ readonly providerName: string;
440
+ paymentAdapter: PaymentAdapter;
441
+ private readonly gateway;
442
+ private readonly maxRetries;
443
+ private readonly shouldWaitForConfirm;
444
+ private readonly confirmationPollMs;
445
+ private readonly confirmationTimeoutMs;
446
+ private readonly skipIntegrityCheck;
447
+ private readonly maxRetrieveSizeBytes;
448
+ protected readonly logger: StorageAdapterLogger | undefined;
449
+ private arweaveClient;
450
+ constructor(config?: ArweaveAdapterConfig);
451
+ private getClient;
452
+ store(data: Uint8Array, metadata?: Record<string, string>): Promise<StorageUploadResult>;
453
+ retrieve(id: string): Promise<{
454
+ bytes: Uint8Array;
455
+ tags: Record<string, string>;
456
+ }>;
457
+ estimateCost(dataSizeBytes: number): Promise<StorageQuote>;
458
+ /**
459
+ * Upload a signed transaction using arweave-js getUploader().
460
+ *
461
+ * getUploader() sends just the tx header to /tx, then streams each 256 KB
462
+ * data slice to the /chunk endpoint. This avoids the ~12 MB HTTP body limit
463
+ * of transactions.post() and supports arbitrarily large transactions.
464
+ *
465
+ * Failed slices are retried individually up to maxRetries times with linear
466
+ * back-off, so a transient network error won't restart the entire upload.
467
+ */
468
+ private uploadWithChunker;
469
+ private pollUntilConfirmed;
470
+ }
471
+
472
+ /**
473
+ * @dstorage/storage — adapters/arweave-bundler.ts
474
+ *
475
+ * Arweave Bundler storage adapter — ANS-104 bundled uploads with server-side signing.
476
+ *
477
+ * ── Upload flow (no client-side Arweave wallet needed) ────────────────────────
478
+ *
479
+ * 1. Client creates an ANS-104 data item locally with the already-encrypted data.
480
+ * 2. Computes the 48-byte deep_hash locally — the ANS-104 signing digest.
481
+ * 3. Sends ONLY the hash to the dStorage API signing server.
482
+ * Raw file bytes never leave the client — same privacy invariant as the
483
+ * current managed Arweave flow where only the stripped tx JSON (data_root)
484
+ * goes to the server.
485
+ * 4. Server signs the hash with its Arweave JWK (funded Turbo Credits account).
486
+ * 5. Client assembles the complete signed data item locally.
487
+ * 6. Client POSTs the signed data item directly to the ArDrive bundler.
488
+ * 7. Returns with near-instant finality — txId is available immediately.
489
+ *
490
+ * ── Retrieve flow ─────────────────────────────────────────────────────────────
491
+ * Standard Arweave gateway fetch (identical to ArweaveStorageAdapter.retrieve).
492
+ *
493
+ * ── Peer dependency ───────────────────────────────────────────────────────────
494
+ * No extra install needed — @dha-team/arbundles ships as a dependency of @ardrive/turbo-sdk.
495
+ *
496
+ * ── Server requirements ───────────────────────────────────────────────────────
497
+ * The dStorage API server must expose (auth-protected via Bearer token):
498
+ * POST /api/service/sign-tx → { signature: string, txId: string, success: boolean, … }
499
+ * The server's Arweave wallet must have Turbo Credits funded at https://ardrive.io.
500
+ *
501
+ * ── Auth token format ─────────────────────────────────────────────────────────
502
+ * authToken must be in the format: <credential>.<base64url_modulus>
503
+ * where <base64url_modulus> is the 512-byte RSA-4096 public key modulus
504
+ * base64url-encoded. The adapter validates and pins the key at construction time.
505
+ * Re-issue the token from the signing server to obtain the current key.
506
+ *
507
+ * ── Notes ─────────────────────────────────────────────────────────────────────
508
+ * • The ArDrive bundler provides near-instant finality — unlike the 2–20 min Arweave L1 wait.
509
+ * • The server holds the funded Turbo Credits account; users need no AR tokens.
510
+ * • Only 48 bytes (the deep_hash) go to the server; ciphertext stays on client.
511
+ */
512
+
513
+ interface ArweaveBundlerAdapterConfig {
514
+ /**
515
+ * Base URL of the dStorage API server that holds the funded Turbo Credits account.
516
+ * Example: "https://api.my-dstorage-server.com"
517
+ */
518
+ signingServerUrl?: string;
519
+ /**
520
+ * Bearer token sent as the `Authorization` header to authenticate with the signing server.
521
+ * Required when `signingServerUrl` is provided.
522
+ */
523
+ authToken?: string;
524
+ /**
525
+ * Arweave gateway URL used for data retrieval.
526
+ * Defaults to the public Arweave gateway.
527
+ *
528
+ * Security: always use an `https://` URL (the default) in production.
529
+ * This adapter uses `globalThis.fetch` directly — no DNS or certificate
530
+ * pinning is applied. Users in adversarial network environments can override
531
+ * `globalThis.fetch` before constructing the adapter to inject their own
532
+ * certificate-pinned fetch implementation.
533
+ */
534
+ gateway?: string;
535
+ /**
536
+ * Maximum number of bytes allowed in a single retrieve() call.
537
+ * Rejects if the `Content-Length` response header exceeds this value, and
538
+ * always rejects after loading if the actual byte count exceeds it.
539
+ * Defaults to 268_435_456 (256 MB).
540
+ */
541
+ maxRetrieveSizeBytes?: number;
542
+ /**
543
+ * Skip BLAKE3 content-hash verification on retrieve.
544
+ * Only set to true when connecting to a fully trusted gateway.
545
+ * Defaults to false.
546
+ */
547
+ skipIntegrityCheck?: boolean;
548
+ /**
549
+ * Optional logger for SDK operational output.
550
+ */
551
+ logger?: StorageAdapterLogger;
552
+ }
553
+ /**
554
+ * Stores encrypted data on Arweave via the ArDrive bundler (near-instant finality).
555
+ *
556
+ * Signing is delegated to the dStorage API server, which holds a funded Turbo Credits
557
+ * account. The client sends only a 48-byte ANS-104 deep_hash to the server — the
558
+ * encrypted file bytes never leave the client, preserving the same privacy invariant
559
+ * as the existing managed Arweave flow.
560
+ *
561
+ * @example
562
+ * const adapter = new ArweaveBundlerStorageAdapter({
563
+ * signingServerUrl: "https://api.my-server.com",
564
+ * authToken: "ds_...",
565
+ * });
566
+ * const { id } = await adapter.store(encryptedBytes, { "Content-Type": "application/octet-stream" });
567
+ */
568
+ declare class ArweaveBundlerStorageAdapter implements StorageAdapter {
569
+ readonly name: StorageProviderName;
570
+ readonly providerName = "Arweave (Bundler)";
571
+ readonly paymentAdapter: PaymentAdapter;
572
+ private readonly signingServerUrl;
573
+ private readonly gateway;
574
+ private readonly maxRetrieveSizeBytes;
575
+ private readonly skipIntegrityCheck;
576
+ protected readonly logger: StorageAdapterLogger | undefined;
577
+ /** RSA-4096 public key modulus (512 bytes) parsed from the auth token at construction time. */
578
+ private readonly ownerPublicKey;
579
+ constructor(config?: ArweaveBundlerAdapterConfig);
580
+ store(data: Uint8Array, metadata?: Record<string, string>): Promise<StorageUploadResult>;
581
+ retrieve(id: string): Promise<{
582
+ bytes: Uint8Array;
583
+ tags: Record<string, string>;
584
+ }>;
585
+ estimateCost(dataSizeBytes: number): Promise<StorageQuote>;
586
+ /**
587
+ * Build a minimal signer object compatible with the @dha-team/arbundles DataItem API.
588
+ *
589
+ * The only non-trivial method is sign(): it sends the deep_hash produced by
590
+ * the DataItem's internal ANS-104 signing procedure to the selected payment adapter.
591
+ * The payment adapter responds with the RSA-PSS signature over that hash (512 bytes, ANS-104 type 1).
592
+ * Raw file bytes never leave the client.
593
+ *
594
+ * The owner public key is parsed from the auth token at construction time — no
595
+ * network round-trip is needed here.
596
+ */
597
+ private _buildSigner;
598
+ /**
599
+ * POST the 48-byte ANS-104 deep_hash to the signing server via the shared sign-tx endpoint.
600
+ *
601
+ * Uses network: "arweave_bundler" so the server routes to the bundler-specific signing path.
602
+ * The `dataSizeBytes` field lets the server estimate and quote the upload cost.
603
+ */
604
+ private _signHash;
605
+ /**
606
+ * Parse the compound auth token (<credential>.<base64url_modulus>) issued by the
607
+ * signing server. Validates that the embedded key is exactly 512 bytes (RSA-4096).
608
+ * Throws at construction time if the format is wrong — fail-fast before any network call.
609
+ *
610
+ * lastIndexOf is intentional: the credential part may itself contain dots
611
+ * (e.g. a JWT), so we always split at the *last* dot to reach the modulus.
612
+ */
613
+ private static _parseToken;
614
+ /**
615
+ * POST the complete signed ANS-104 data item bytes directly to the ArDrive bundler.
616
+ * Server Turbo Credits are consumed based on the signing key — no client wallet needed.
617
+ */
618
+ private _uploadToBundler;
619
+ }
620
+
621
+ /**
622
+ * @dstorage/storage — arweave-local.ts
623
+ *
624
+ * Local Arweave testing utilities built on top of arlocal:
625
+ * https://github.com/textury/arlocal
626
+ *
627
+ * arlocal is a zero-configuration local Arweave gateway for integration
628
+ * testing. It accepts transactions without requiring real AR tokens, exposes
629
+ * a /mint endpoint to fund test wallets instantly, and a /mine endpoint to
630
+ * fast-forward block confirmation — all fully offline.
631
+ *
632
+ * ── Quick start ───────────────────────────────────────────────────────────────
633
+ *
634
+ * # 1. Start arlocal (once per dev session) — Docker is recommended:
635
+ * docker run -d --rm -p 1984:1984 --name arlocal textury/arlocal
636
+ * # alternatively, without Docker:
637
+ * npx arlocal
638
+ *
639
+ * # 2. In your code, use ArweaveLocalStorageAdapter instead of the real one
640
+ * const { adapter, walletKey, address } =
641
+ * await ArweaveLocalStorageAdapter.createWithTestWallet();
642
+ *
643
+ * # 3. Mint test tokens
644
+ * await adapter.testnet.mintTokens(address, 5_000_000_000_000n); // 5 AR
645
+ *
646
+ * # 4. Use exactly like ArweaveStorageAdapter
647
+ * const { id } = await adapter.store('my encrypted data');
648
+ * await adapter.testnet.mine(); // confirm the tx instantly
649
+ * const data = await adapter.retrieve(id);
650
+ *
651
+ * ── Exports ───────────────────────────────────────────────────────────────────
652
+ *
653
+ * ARWEAVE_MAINNET — gateway preset for arweave.net
654
+ * ARWEAVE_LOCAL — gateway preset for localhost:1984
655
+ * arlocalGateway(port) — build a custom-port local preset
656
+ * ArweaveLocalHelper — mint / mine / balance / reset helpers
657
+ * ArweaveLocalStorageAdapter — drop-in adapter for local testing
658
+ * ArweaveLocalError — typed error thrown by helper methods
659
+ */
660
+
661
+ /**
662
+ * Local arlocal gateway preset (default port 1984).
663
+ *
664
+ * @example
665
+ * new ArweaveStorageAdapter({ gateway: ARWEAVE_LOCAL, walletKey: testJwk })
666
+ * // or:
667
+ * new ArweaveLocalStorageAdapter({ walletKey: testJwk })
668
+ */
669
+ declare const ARWEAVE_LOCAL: ArweaveGatewayConfig;
670
+ /**
671
+ * Build a local arlocal gateway preset on a non-default port.
672
+ *
673
+ * @example
674
+ * const gw = arlocalGateway(1985);
675
+ * new ArweaveLocalStorageAdapter({ gateway: gw, walletKey: testJwk })
676
+ */
677
+ declare function arlocalGateway(port?: number): ArweaveGatewayConfig;
678
+ interface ArweaveLocalHelperConfig {
679
+ /** Base URL of the arlocal instance. Defaults to 'http://localhost:1984'. */
680
+ url?: string;
681
+ }
682
+ interface ArweaveLocalInfo {
683
+ network: string;
684
+ version: number;
685
+ release: number;
686
+ height: number;
687
+ current: string;
688
+ peers: number;
689
+ queue_length: number;
690
+ node_state_latency: number;
691
+ }
692
+ interface ArweaveLocalBalance {
693
+ /** Raw balance in Winstons (1 AR = 1_000_000_000_000 Winstons). */
694
+ winstons: string;
695
+ /** Human-readable balance, e.g. "5" for 5 AR. */
696
+ ar: string;
697
+ }
698
+ /**
699
+ * Helper for controlling a running arlocal instance.
700
+ *
701
+ * Use this to fund test wallets, fast-forward block confirmations, and
702
+ * inspect state during integration tests.
703
+ *
704
+ * @example
705
+ * const helper = new ArweaveLocalHelper();
706
+ * await helper.mintTokens(address, 1_000_000_000_000n); // 1 AR
707
+ * await helper.mine();
708
+ * const { ar } = await helper.getBalance(address);
709
+ */
710
+ declare class ArweaveLocalHelper {
711
+ private readonly baseUrl;
712
+ constructor(config?: ArweaveLocalHelperConfig);
713
+ /**
714
+ * Credit a wallet address with test AR tokens.
715
+ *
716
+ * The amount is in Winstons (1 AR = 1_000_000_000_000 Winstons).
717
+ * Defaults to 1 AR if not specified.
718
+ *
719
+ * @example
720
+ * await helper.mintTokens(address, 5_000_000_000_000n); // 5 AR
721
+ */
722
+ mintTokens(address: string, winstons?: bigint | number): Promise<void>;
723
+ /**
724
+ * Fast-forward the arlocal blockchain by mining one or more blocks.
725
+ *
726
+ * Pending transactions only become "confirmed" after a block is mined.
727
+ * Call this after uploading if your test checks confirmed status
728
+ * (e.g. when using `waitForConfirmation: true`).
729
+ *
730
+ * @example
731
+ * await helper.mine(); // mine 1 block
732
+ * await helper.mine(3); // mine 3 blocks
733
+ */
734
+ mine(blocks?: number): Promise<void>;
735
+ /**
736
+ * Query the AR token balance of a wallet address on arlocal.
737
+ *
738
+ * @example
739
+ * const { ar, winstons } = await helper.getBalance(address);
740
+ * console.log(`Balance: ${ar} AR (${winstons} winstons)`);
741
+ */
742
+ getBalance(address: string): Promise<ArweaveLocalBalance>;
743
+ /**
744
+ * Retrieve general info about the arlocal instance.
745
+ * Useful for confirming the server is reachable before running tests.
746
+ */
747
+ getInfo(): Promise<ArweaveLocalInfo>;
748
+ /**
749
+ * Returns `true` if the arlocal instance is reachable, `false` otherwise.
750
+ *
751
+ * Use in `beforeAll` to skip integration tests gracefully when arlocal
752
+ * is not running in the local environment.
753
+ *
754
+ * @example
755
+ * beforeAll(async () => {
756
+ * if (!(await helper.isRunning())) {
757
+ * console.warn('arlocal not running — skipping integration tests');
758
+ * }
759
+ * });
760
+ */
761
+ isRunning(): Promise<boolean>;
762
+ /**
763
+ * Drop all transactions and reset arlocal state to a clean slate.
764
+ * Only available when arlocal is started with persistence disabled (the default).
765
+ */
766
+ reset(): Promise<void>;
767
+ private get;
768
+ }
769
+ type ArweaveLocalAdapterConfig = ArweaveAdapterConfig;
770
+ /**
771
+ * A storage adapter for local Arweave integration testing using arlocal.
772
+ *
773
+ * Identical API to `ArweaveStorageAdapter` but pre-configured for a local
774
+ * arlocal instance. Exposes a `.testnet` helper for minting tokens, mining
775
+ * blocks, and inspecting state — without touching the real Arweave network.
776
+ *
777
+ * ── Requirements ──────────────────────────────────────────────────────────────
778
+ *
779
+ * Start arlocal (Docker recommended — no npm install needed):
780
+ * docker run -d --rm -p 1984:1984 --name arlocal textury/arlocal
781
+ * or, via npx (installs arlocal on demand):
782
+ * npx arlocal
783
+ *
784
+ * ── Usage ─────────────────────────────────────────────────────────────────────
785
+ *
786
+ * Option A — static factory (recommended for tests): auto-generates & funds wallet
787
+ *
788
+ * const { adapter, walletKey, address } =
789
+ * await ArweaveLocalStorageAdapter.createWithTestWallet();
790
+ *
791
+ * const ds = new DStorage({
792
+ * storageAdapter: adapter,
793
+ * chainAdapter: new MockChainAdapter(),
794
+ * });
795
+ *
796
+ * Option B — manual config (when you already have a wallet):
797
+ *
798
+ * const adapter = new ArweaveLocalStorageAdapter({ walletKey: myJwk });
799
+ * await adapter.testnet.mintTokens(address, 2_000_000_000_000n); // 2 AR
800
+ *
801
+ * ── Replacing the real adapter ────────────────────────────────────────────────
802
+ *
803
+ * // Development / CI — local arlocal
804
+ * storageAdapter: new ArweaveLocalStorageAdapter({ walletKey: testJwk })
805
+ *
806
+ * // Production — real Arweave mainnet
807
+ * storageAdapter: new ArweaveStorageAdapter({ walletKey: realJwk })
808
+ */
809
+ declare class ArweaveLocalStorageAdapter extends ArweaveStorageAdapter {
810
+ readonly name: StorageProviderName;
811
+ readonly providerName: string;
812
+ /** Access arlocal control methods: mint, mine, balance, reset. */
813
+ readonly testnet: ArweaveLocalHelper;
814
+ /** Resolves when the wallet has been funded on arlocal (if walletKey was provided). */
815
+ private readonly _initMintPromise;
816
+ constructor(config?: ArweaveLocalAdapterConfig);
817
+ /**
818
+ * Extract the 683-char base64url RSA modulus suffix from a compound auth token
819
+ * (<credential>.<modulus>). Returns undefined for plain tokens.
820
+ * Mirrors the same logic in ManagedPaymentAdapter._parseAuthToken.
821
+ */
822
+ private static _extractOwnerKey;
823
+ private _mintWallet;
824
+ private _mintManagedOwner;
825
+ private _mintToOwnerKey;
826
+ /**
827
+ * Factory method: generates a fresh Arweave wallet, mints test AR tokens
828
+ * into it, and returns a fully-configured adapter ready for testing.
829
+ *
830
+ * Requires arlocal to be running at the given URL.
831
+ *
832
+ * @param options.fundAr AR to mint into the test wallet (default: 10)
833
+ * @param options.gateway Override the arlocal gateway (default: localhost:1984)
834
+ *
835
+ * @example
836
+ * const { adapter, walletKey, address } =
837
+ * await ArweaveLocalStorageAdapter.createWithTestWallet({ fundAr: 5 });
838
+ *
839
+ * // Then use adapter in your DStorage instance:
840
+ * const ds = new DStorage({ storageAdapter: adapter, chainAdapter: new MockChainAdapter() });
841
+ */
842
+ static createWithTestWallet(options?: {
843
+ fundAr?: number;
844
+ gateway?: ArweaveGatewayConfig;
845
+ }): Promise<{
846
+ adapter: ArweaveLocalStorageAdapter;
847
+ walletKey: Record<string, string>;
848
+ address: string;
849
+ }>;
850
+ store(data: Uint8Array, metadata?: Record<string, string>): Promise<StorageUploadResult>;
851
+ }
852
+ declare class ArweaveLocalError extends Error {
853
+ readonly statusCode: number;
854
+ constructor(message: string, statusCode: number);
855
+ }
856
+
857
+ declare class DStorageError extends Error {
858
+ readonly code: number;
859
+ readonly httpStatus?: number;
860
+ constructor(code: number, message: string, options?: ErrorOptions & {
861
+ httpStatus?: number;
862
+ });
863
+ }
864
+ declare function isDStorageError(err: unknown): err is DStorageError;
865
+ declare const CryptoErrorCode: {
866
+ readonly WEBCRYPTO_NOT_AVAILABLE: 12000;
867
+ readonly BASE64URL_INVALID: 12001;
868
+ readonly MISSING_KEY_INPUT: 12002;
869
+ readonly MNEMONIC_TOO_SHORT: 12003;
870
+ readonly SEED_INVALID_LENGTH: 12004;
871
+ readonly MNEMONIC_INVALID: 12005;
872
+ readonly HEX_ODD_LENGTH: 12006;
873
+ readonly HEX_INVALID_CHARS: 12007;
874
+ readonly DEK_INVALID_LENGTH: 12008;
875
+ readonly WRAP_KEK_INVALID_LENGTH: 12009;
876
+ readonly UNWRAP_KEK_INVALID_LENGTH: 12010;
877
+ readonly ENVELOPE_EMPTY_WRAPPERS: 12011;
878
+ readonly XCHACHA_INVALID_STORAGE_ID_LEN: 12012;
879
+ readonly XCHACHA_PAYLOAD_MALFORMED: 12013;
880
+ readonly XCHACHA_STORAGE_ID_MALFORMED: 12014;
881
+ readonly MLKEM_SEED_INVALID_LENGTH: 12015;
882
+ readonly MLKEM_MISSING_CIPHERTEXT: 12016;
883
+ readonly MLKEM_UNKNOWN_ALGORITHM: 12017;
884
+ readonly MLKEM_UNKNOWN_VARIANT: 12018;
885
+ };
886
+ type CryptoErrorCode = (typeof CryptoErrorCode)[keyof typeof CryptoErrorCode];
887
+
888
+ /**
889
+ * @dstorage/crypto — types.ts
890
+ *
891
+ * Core types and interfaces for the crypto package:
892
+ * - EncryptionScheme — on-chain scheme identifier
893
+ * - CryptoScheme — interface every scheme implementation must satisfy
894
+ * - base64url helpers — shared encoding utilities used across scheme implementations
895
+ */
896
+ /**
897
+ * Identifies the encryption algorithm used to encrypt a storageId and content.
898
+ * Recorded on-chain in ReferenceEntry.encryptionScheme so the SDK can dispatch
899
+ * the correct decryption function at read time.
900
+ *
901
+ * Values:
902
+ * "xchacha20poly1305-v1" — XChaCha20-Poly1305 (per-upload random DEK, wrapped in keyEnvelope); default
903
+ * "" — No encryption; storageId and content are stored as plaintext (public data)
904
+ */
905
+ type EncryptionScheme = "xchacha20poly1305-v1" | "";
906
+ /**
907
+ * The result of wrapping a DEK under a provider's key material.
908
+ * Returned by every EncryptionAdapter.wrapDek() implementation and
909
+ * stored as a KeyWrapper entry inside the on-chain KeyEnvelope.
910
+ *
911
+ * Symmetric providers set algorithm/kekDerivation for their own scheme and
912
+ * leave kemCiphertext undefined. Asymmetric providers (ML-KEM) additionally
913
+ * populate kemCiphertext with the KEM ciphertext needed for decapsulation.
914
+ */
915
+ interface WrappedDekResult {
916
+ /** Algorithm identifier, e.g. "xchacha20poly1305-v1" or "mlkem768-xchacha20poly1305-v1". */
917
+ algorithm: string;
918
+ /** How the KEK was derived from its source material, e.g. "hkdf-sha256-v1". */
919
+ kekDerivation: string;
920
+ /** base64url-encoded wrapped DEK ciphertext. */
921
+ wrappedDek: string;
922
+ /** base64url-encoded KEM ciphertext — present only for asymmetric providers. */
923
+ kemCiphertext?: string;
924
+ }
925
+ /**
926
+ * Interface for a symmetric encryption scheme.
927
+ *
928
+ * Implementations are instantiated from a random DEK via a static factory
929
+ * (e.g. XChaChaScheme.fromKey(dek)) for per-upload encryption.
930
+ */
931
+ interface CryptoScheme {
932
+ /** Scheme identifier recorded on-chain. */
933
+ readonly schemeName: Exclude<EncryptionScheme, "">;
934
+ /**
935
+ * Encrypt raw bytes and return a self-contained serialized payload
936
+ * ready to be uploaded to off-chain storage.
937
+ *
938
+ * `aad` is bound into the Poly1305 auth tag and must match on decrypt.
939
+ * Use PAYLOAD_AAD for single-shot uploads and manifests; use chunkAad(i, n)
940
+ * for individual chunks so a malicious gateway cannot swap chunk order.
941
+ */
942
+ encryptPayload(bytes: Uint8Array, aad: Uint8Array): Promise<Uint8Array>;
943
+ /**
944
+ * Deserialize and decrypt a payload previously produced by encryptPayload().
945
+ * Throws if the payload format is invalid, the auth tag fails, or the AAD mismatches.
946
+ */
947
+ decryptPayload(data: Uint8Array, aad: Uint8Array): Promise<Uint8Array>;
948
+ /**
949
+ * Encrypt a 43-char base64url storage ID (32 decoded bytes) for on-chain storage.
950
+ * Returns a base64url-encoded encrypted form.
951
+ */
952
+ encryptStorageId(storageId: string): Promise<string>;
953
+ /**
954
+ * Decrypt a storage ID previously encrypted by encryptStorageId().
955
+ * Returns the original 43-char base64url storage ID.
956
+ */
957
+ decryptStorageId(encryptedId: string): Promise<string>;
958
+ }
959
+ /** Decode a base64url string to a Uint8Array. */
960
+ declare function base64urlToBytes(b64url: string): Uint8Array;
961
+ /** Encode a Uint8Array to a base64url string (no padding). */
962
+ declare function bytesToBase64url(bytes: Uint8Array): string;
963
+
964
+ /**
965
+ * @dstorage/crypto — keys.ts
966
+ * Provides seed-based key derivation utilities:
967
+ *
968
+ * - KeyDeriver: resolves a BIP-39 mnemonic or raw hex seed to raw bytes,
969
+ * importing seed bytes as a CryptoKey for use with deriveKek() (keyEnvelope.ts).
970
+ * - hexToBytes: parses a hex string into a Uint8Array.
971
+ */
972
+ /**
973
+ * Resolves a BIP-39 mnemonic or raw hex seed to raw bytes.
974
+ * Implements EncryptionAdapter — pass an instance to DStorage config.
975
+ */
976
+ declare class KeyDeriver {
977
+ private readonly input;
978
+ constructor(input: {
979
+ mnemonic?: string;
980
+ seedHex?: string;
981
+ });
982
+ /**
983
+ * Return the raw seed bytes.
984
+ * Import the result as a non-extractable HKDF CryptoKey before passing to deriveKek().
985
+ */
986
+ getSeed(): Promise<Uint8Array>;
987
+ /** Resolves and validates the seed as a Buffer. */
988
+ private getSeedBuffer;
989
+ }
990
+ declare function hexToBytes(hex: string, label?: string): Uint8Array<ArrayBuffer>;
991
+
992
+ /**
993
+ * @dstorage/crypto — xchacha.ts
994
+ * Symmetric authenticated encryption using XChaCha20-Poly1305.
995
+ *
996
+ * Key derivation:
997
+ * seed bytes (from EncryptionAdapter)
998
+ * → HKDF-SHA-256 (domain-separated, optionally address-bound)
999
+ * → 32-byte symmetric key (KEK)
1000
+ * → per-upload random DEK wrapped under KEK
1001
+ *
1002
+ * Why XChaCha20-Poly1305:
1003
+ * - 192-bit nonce eliminates birthday-bound collision risk —
1004
+ * safe to generate random nonces indefinitely
1005
+ * - Pure bytes in / bytes out — no WebCrypto CryptoKey ceremony
1006
+ * - Better performance on hardware without AES acceleration (mobile, ARM, IoT)
1007
+ *
1008
+ * Why a single symmetric key instead of a KEM keypair:
1009
+ * A KEM step would only add value if data needed to be
1010
+ * encrypted for a different recipient using their public key. For single-user
1011
+ * self-encryption where the same party encrypts and decrypts, HKDF → XChaCha20
1012
+ * is simpler, has much smaller ciphertext overhead, and provides equivalent
1013
+ * security. If cross-user encryption is required in the future the scheme
1014
+ * can be extended with a KEM layer at that point.
1015
+ *
1016
+ * On-chain storageId format (JSON):
1017
+ * Same envelope as off-chain payloads — handles arbitrary-length string IDs.
1018
+ * { ciphertext: base64, nonce: base64, algorithm: "XChaCha20-Poly1305" }
1019
+ *
1020
+ * Off-chain payload format (JSON):
1021
+ * { ciphertext: base64, nonce: base64, algorithm: "XChaCha20-Poly1305" }
1022
+ */
1023
+
1024
+ /** Encrypted payload stored off-chain (Arweave, etc.). All binary fields are base64. */
1025
+ interface XChaChaPayload {
1026
+ /** base64 — XChaCha20-Poly1305 output: ciphertext || 16-byte Poly1305 tag */
1027
+ ciphertext: string;
1028
+ /** base64 — 24-byte random nonce */
1029
+ nonce: string;
1030
+ /** Algorithm identifier */
1031
+ algorithm: "XChaCha20-Poly1305";
1032
+ }
1033
+ /**
1034
+ * Derive a 32-byte symmetric key for XChaCha20-Poly1305 from arbitrary seed bytes.
1035
+ *
1036
+ * Uses HKDF-SHA-256 with a fixed global salt (domain separator) and a versioned,
1037
+ * context-bound `info` string per RFC 5869:
1038
+ * - `salt` = fixed application-level extraction key ("dstorage-xchacha-v1")
1039
+ * - `info` = versioned label, optionally binding a wallet address
1040
+ *
1041
+ * @param seed High-entropy seed bytes (wallet signature, BIP-39 seed, hex seed, etc.)
1042
+ * @param context Optional wallet address or other per-context binding value.
1043
+ * Incorporated into `info` to bind the derived key to a specific account.
1044
+ */
1045
+ declare function deriveSymmetricKeyFromSeed(seed: Uint8Array, context?: string): Promise<Uint8Array>;
1046
+ /**
1047
+ * Encrypt arbitrary bytes with XChaCha20-Poly1305.
1048
+ *
1049
+ * Non-deterministic: fresh random 24-byte nonce per call.
1050
+ *
1051
+ * @param key 32-byte symmetric key from deriveSymmetricKeyFromSeed()
1052
+ * @param data Arbitrary plaintext bytes
1053
+ * @param aad Additional authenticated data bound to the ciphertext (recommended)
1054
+ */
1055
+ declare function encryptXChaCha(key: Uint8Array, data: Uint8Array, aad?: Uint8Array): Promise<XChaChaPayload>;
1056
+ /**
1057
+ * Decrypt a payload produced by encryptXChaCha().
1058
+ * The `aad` must match exactly what was passed to encryptXChaCha() — the Poly1305
1059
+ * auth tag covers the AAD, so any mismatch causes decryption to throw.
1060
+ *
1061
+ * @param key 32-byte symmetric key (must match the key used to encrypt)
1062
+ * @param payload XChaChaPayload from encryptXChaCha()
1063
+ * @param aad Must match the AAD used during encryption
1064
+ * @throws If Poly1305 auth tag verification fails (wrong key, tampered data, or wrong AAD)
1065
+ */
1066
+ declare function decryptXChaCha(key: Uint8Array, payload: XChaChaPayload, aad?: Uint8Array): Promise<Uint8Array>;
1067
+ /**
1068
+ * Encrypt a 32-byte storage ID for on-chain storage.
1069
+ *
1070
+ * Output is exactly 72 bytes: [ nonce(24) | ciphertext(32) | auth-tag(16) ].
1071
+ *
1072
+ * @param key 32-byte symmetric key from deriveSymmetricKeyFromSeed()
1073
+ * @param storageIdBytes Raw 32-byte storage ID
1074
+ */
1075
+ declare function encryptStorageIdXChaCha(key: Uint8Array, storageIdBytes: Uint8Array): Promise<Uint8Array>;
1076
+ /**
1077
+ * Decrypt a storage ID previously encrypted with encryptStorageIdXChaCha().
1078
+ * Expects exactly 72 bytes.
1079
+ * Throws if the Poly1305 auth tag does not match (tamper-evident).
1080
+ *
1081
+ * @param key 32-byte symmetric key (must match encryption key)
1082
+ * @param encryptedBytes 72-byte on-chain payload
1083
+ */
1084
+ declare function decryptStorageIdXChaCha(key: Uint8Array, encryptedBytes: Uint8Array): Promise<Uint8Array>;
1085
+ /**
1086
+ * Serialize an XChaChaPayload to a compact JSON string.
1087
+ * Safe to pass to off-chain storage APIs.
1088
+ */
1089
+ declare function serializeXChaChaPayload(payload: XChaChaPayload): string;
1090
+ /**
1091
+ * Deserialize a JSON string back to an XChaChaPayload.
1092
+ * Returns null if the input is invalid or missing required fields.
1093
+ */
1094
+ declare function deserializeXChaChaPayload(raw: string): XChaChaPayload | null;
1095
+ /** XChaCha20-Poly1305 scheme. Key derived via HKDF-SHA-256. */
1096
+ declare class XChaChaScheme implements CryptoScheme {
1097
+ readonly schemeName: "xchacha20poly1305-v1";
1098
+ private readonly key;
1099
+ private constructor();
1100
+ /**
1101
+ * Derive a 32-byte XChaCha20-Poly1305 key from seed bytes using HKDF-SHA-256.
1102
+ *
1103
+ * @param seed High-entropy seed bytes (wallet signature, BIP-39 seed, etc.)
1104
+ * @param context Optional wallet address or other binding context.
1105
+ * Incorporated into the HKDF salt to bind the key to a specific account.
1106
+ */
1107
+ static create(seed: Uint8Array, context?: string): Promise<XChaChaScheme>;
1108
+ /**
1109
+ * Create a scheme instance from a pre-generated key (e.g. a random DEK).
1110
+ * Bypasses HKDF derivation — use when the key is already available.
1111
+ *
1112
+ * @param key 32-byte symmetric key
1113
+ */
1114
+ static fromKey(key: Uint8Array): XChaChaScheme;
1115
+ encryptPayload(bytes: Uint8Array, aad: Uint8Array): Promise<Uint8Array>;
1116
+ decryptPayload(data: Uint8Array, aad: Uint8Array): Promise<Uint8Array>;
1117
+ encryptStorageId(storageId: string): Promise<string>;
1118
+ decryptStorageId(encryptedId: string): Promise<string>;
1119
+ }
1120
+
1121
+ /**
1122
+ * @dstorage/crypto — keyEnvelope.ts
1123
+ *
1124
+ * Multi-key wrapping for Data Encryption Keys (DEKs).
1125
+ *
1126
+ * Each private upload generates a fresh random DEK, which is then wrapped
1127
+ * (encrypted) under a Key Encryption Key (KEK) derived from the wallet seed.
1128
+ * The wrapped DEK and its metadata are serialised as a JSON envelope and
1129
+ * stored on-chain in the `keyEnvelope` field of ReferenceEntry.
1130
+ *
1131
+ * This separates the encryption key (random, unique per upload) from the
1132
+ * key-protecting mechanism (wallet-bound), enabling future multi-recipient
1133
+ * access without re-encrypting stored data — just add another wrapper entry.
1134
+ *
1135
+ * Envelope schema (private uploads only — public uploads have no envelope):
1136
+ * {
1137
+ * "v": 1,
1138
+ * "wrappers": [
1139
+ * {
1140
+ * "wrapKeyName": "password", // identifies the wrapping key source
1141
+ * "algorithm": "xchacha20poly1305-v1",
1142
+ * "kekDerivation": "hkdf-sha256-v1",
1143
+ * "wrappedDek": "<base64url 96 chars>"
1144
+ * }
1145
+ * ]
1146
+ * }
1147
+ *
1148
+ * The ownerSecret for private uploads is derived deterministically from the wrapped DEK:
1149
+ * ownerSecret = HKDF-SHA256(ikm=DEK, salt=rawStorageId, info="dstorage:owner-secret:v1")
1150
+ * Any holder of a valid KEK can unwrap the DEK and re-derive the ownerSecret.
1151
+ *
1152
+ * `wrappedDek` binary layout (72 bytes):
1153
+ * [ nonce(24) | ciphertext(32) | auth-tag(16) ]
1154
+ * base64url-encoded → 96 chars — identical to the on-chain storageId layout.
1155
+ */
1156
+
1157
+ interface KeyWrapper extends WrappedDekResult {
1158
+ /** Identifies the wrapping key source (e.g. "password", "mnemonic", "mlkem768"). */
1159
+ wrapKeyName: string;
1160
+ }
1161
+ interface KeyEnvelope {
1162
+ v: 1;
1163
+ /**
1164
+ * Wrappers for the data DEK (content encryption key). Always present in a valid envelope.
1165
+ * The ownerSecret for ownership proofs is derived from the same DEK:
1166
+ * ownerSecret = HKDF-SHA256(DEK, rawStorageId, "dstorage:owner-secret:v1")
1167
+ * Any holder of a valid KEK can unwrap the DEK and re-derive the ownerSecret.
1168
+ * Public uploads have no envelope (keyEnvelope = "").
1169
+ */
1170
+ wrappers: [KeyWrapper, ...KeyWrapper[]];
1171
+ }
1172
+ /**
1173
+ * Generate a cryptographically random 32-byte Data Encryption Key.
1174
+ * Uses the platform CSPRNG (`crypto.getRandomValues`) — safe in both
1175
+ * browser and Node.js 19+.
1176
+ */
1177
+ declare function generateDek(): Uint8Array;
1178
+ /**
1179
+ * Derive a 32-byte Key Encryption Key from a non-extractable HKDF CryptoKey.
1180
+ *
1181
+ * Callers must import their raw seed bytes via `crypto.subtle.importKey("raw", seed,
1182
+ * "HKDF", false, ["deriveBits"])` before calling this function. Accepting only
1183
+ * CryptoKey enforces that raw key material is never held in a JS-accessible heap
1184
+ * variable at this call site.
1185
+ *
1186
+ * Uses the same salt as the data encryption key ("dstorage-xchacha-v1") but a
1187
+ * distinct info string ("dstorage:xchacha20poly1305:kek:v1") to domain-separate
1188
+ * the KEK from all other keys derived from the same seed.
1189
+ *
1190
+ * @param keyMaterial Non-extractable HKDF CryptoKey imported from the seed.
1191
+ * @param context Optional wallet address or other binding context, incorporated
1192
+ * into the info string to bind the KEK to a specific account.
1193
+ */
1194
+ declare function deriveKek(keyMaterial: CryptoKey, context?: string): Promise<Uint8Array>;
1195
+ /**
1196
+ * Wrap (encrypt) a 32-byte DEK under a KEK using XChaCha20-Poly1305.
1197
+ *
1198
+ * Reuses the same 72-byte binary layout as on-chain storageId encryption:
1199
+ * [ nonce(24) | ciphertext(32) | auth-tag(16) ]
1200
+ * base64url-encoded → 96-char string.
1201
+ *
1202
+ * @param dek 32-byte Data Encryption Key to protect
1203
+ * @param kek 32-byte Key Encryption Key (from deriveKek())
1204
+ */
1205
+ declare function wrapKey(dek: Uint8Array, kek: Uint8Array): Promise<string>;
1206
+ /**
1207
+ * Unwrap (decrypt) a wrapped DEK string back to the original 32-byte DEK.
1208
+ *
1209
+ * @param wrappedDek base64url-encoded 96-char string from wrapKey()
1210
+ * @param kek 32-byte Key Encryption Key (from deriveKek())
1211
+ */
1212
+ declare function unwrapKey(wrappedDek: string, kek: Uint8Array): Promise<Uint8Array>;
1213
+ /**
1214
+ * Derive a 32-byte owner secret from the data DEK and the raw storage ID.
1215
+ *
1216
+ * Derivation: HKDF-SHA-256(ikm=dek, salt=rawStorageId, info=OWNER_SECRET_DOMAIN)
1217
+ *
1218
+ * Security properties:
1219
+ * - Post-quantum resistant: HKDF-SHA-256 is purely symmetric (no elliptic-curve math).
1220
+ * - One-way: the DEK cannot be recovered from the ownerSecret (HKDF preimage resistance).
1221
+ * - Key-separated: the ownerSecret cannot be used for data encryption.
1222
+ * - Per-upload unique: different DEK + storageId per upload → different ownerSecret.
1223
+ * - Derivable: any holder of a valid KEK can unwrap the DEK and re-derive the ownerSecret.
1224
+ *
1225
+ * @param ikm 32-byte key material (DEK for private uploads; KEK for public uploads)
1226
+ * @param rawStorageId Raw storage network ID bytes (e.g. Arweave txId encoded as UTF-8)
1227
+ * @param info HKDF info / domain separator (defaults to private-upload domain)
1228
+ */
1229
+ declare function deriveOwnerSecret(ikm: Uint8Array, rawStorageId: Uint8Array, info?: string): Promise<Uint8Array>;
1230
+ /**
1231
+ * Build a v1 key envelope wrapping the data DEK under one or more KEKs.
1232
+ *
1233
+ * Each entry wraps the same random DEK under a different KEK (one per seed
1234
+ * provider), allowing any of the corresponding recipients to independently
1235
+ * decrypt the same content without re-encryption.
1236
+ *
1237
+ * The ownerSecret for ownership proofs is derived from the same DEK:
1238
+ * ownerSecret = HKDF-SHA256(DEK, rawStorageId, "dstorage:owner-secret:v1")
1239
+ * No separate ownership key is needed.
1240
+ *
1241
+ * @param wrappers Non-empty array of `{ wrappedDek, wrapKeyName }` pairs.
1242
+ * `wrappedDek` is the base64url-encoded output of wrapKey().
1243
+ * `wrapKeyName` is a caller-chosen label (e.g. "provider-0").
1244
+ *
1245
+ * @throws if `wrappers` is empty.
1246
+ */
1247
+ declare function buildKeyEnvelope(wrappers: Array<KeyWrapper>): KeyEnvelope;
1248
+ /**
1249
+ * Serialise a KeyEnvelope to the JSON string stored on-chain.
1250
+ */
1251
+ declare function serializeKeyEnvelope(envelope: KeyEnvelope): string;
1252
+ /**
1253
+ * Parse and validate a JSON string from the chain.
1254
+ * Returns null for empty strings or malformed / unrecognised envelopes.
1255
+ */
1256
+ declare function parseKeyEnvelope(raw: string): KeyEnvelope | null;
1257
+ /**
1258
+ * Find a wrapper by its wrapKeyName. Returns null if not found.
1259
+ */
1260
+ declare function findWrapper(envelope: KeyEnvelope, wrapKeyName: string): KeyWrapper | null;
1261
+
1262
+ /**
1263
+ * @dstorage/crypto — mlkem.ts
1264
+ *
1265
+ * Post-quantum DEK wrapping via ML-KEM (CRYSTALS-Kyber, NIST FIPS 203).
1266
+ *
1267
+ * Hybrid encryption pattern:
1268
+ * wrapDek: ML-KEM encapsulate(PK) → sharedSecret → HKDF → KEK → XChaCha20 wraps DEK
1269
+ * unwrapDek: ML-KEM decapsulate(SK, ct) → sharedSecret → HKDF → KEK → XChaCha20 unwraps DEK
1270
+ *
1271
+ * This provides post-quantum confidentiality for the DEK:
1272
+ * - Only the holder of the Secret Key can recover the DEK.
1273
+ * - Encapsulation (upload) requires only the Public Key.
1274
+ * - A quantum computer cannot recover sharedSecret from the KEM ciphertext alone.
1275
+ *
1276
+ * Key sizes (variant mlkem768, NIST recommended):
1277
+ * Public key: 1184 bytes
1278
+ * Secret key: 2400 bytes
1279
+ * Ciphertext: 1088 bytes
1280
+ * Shared secret: 32 bytes
1281
+ */
1282
+
1283
+ type MLKemVariant = "mlkem512" | "mlkem768" | "mlkem1024";
1284
+ /**
1285
+ * Generate a random ML-KEM keypair.
1286
+ *
1287
+ * @param variant ML-KEM variant. Default: "mlkem768" (NIST recommended, 192-bit security).
1288
+ */
1289
+ declare function mlkemGenerateKeypair(variant?: MLKemVariant): {
1290
+ pk: Uint8Array;
1291
+ sk: Uint8Array;
1292
+ };
1293
+ /**
1294
+ * Generate a deterministic ML-KEM keypair from a 64-byte seed (d‖z, per FIPS 203).
1295
+ * The same seed always produces the same keypair.
1296
+ *
1297
+ * Requires exactly 64 bytes — derive via Web Crypto HKDF deriveBits (512 bits) before calling.
1298
+ *
1299
+ * @param seed64 64-byte seed material
1300
+ * @param variant ML-KEM variant. Default: "mlkem768".
1301
+ */
1302
+ declare function mlkemGenerateKeypairFromSeed(seed64: Uint8Array, variant?: MLKemVariant): {
1303
+ pk: Uint8Array;
1304
+ sk: Uint8Array;
1305
+ };
1306
+ /**
1307
+ * Wrap a DEK under a ML-KEM public key.
1308
+ *
1309
+ * Encapsulates a shared secret, derives a KEK from it via HKDF, then wraps
1310
+ * the DEK with the same XChaCha20-Poly1305 scheme used by symmetric providers.
1311
+ * The KEM ciphertext is stored alongside the wrapped DEK so the holder of the
1312
+ * secret key can reverse the process at retrieval time.
1313
+ *
1314
+ * @param dek 32-byte Data Encryption Key to protect
1315
+ * @param pk ML-KEM public key
1316
+ * @param context Domain-separation string bound into the KEK derivation
1317
+ * @param variant ML-KEM variant. Default: "mlkem768".
1318
+ */
1319
+ declare function mlkemWrapDek(dek: Uint8Array, pk: Uint8Array, context: string, variant?: MLKemVariant): Promise<WrappedDekResult>;
1320
+ /**
1321
+ * Unwrap a DEK from a ML-KEM wrapped DEK result.
1322
+ *
1323
+ * The ML-KEM variant is read from `data.algorithm` (e.g. "mlkem768-xchacha20poly1305-v1"),
1324
+ * so the caller does not need to supply it — the key envelope is self-describing.
1325
+ *
1326
+ * @param data WrappedDekResult containing algorithm, kemCiphertext, and wrappedDek
1327
+ * @param sk ML-KEM secret key
1328
+ * @param context Domain-separation string bound into the KEK derivation (must match
1329
+ * the value used to wrap)
1330
+ */
1331
+ declare function mlkemUnwrapDek(data: WrappedDekResult, sk: Uint8Array, context: string): Promise<Uint8Array>;
1332
+
1333
+ /** BLAKE3 hash of `bytes`, returned as a raw 32-byte Uint8Array. */
1334
+ declare function computeBlake3(bytes: Uint8Array): Promise<Uint8Array>;
1335
+ /** BLAKE3 hash of `bytes`, returned as a 64-character lowercase hex string. */
1336
+ declare function computeBlake3Hex(bytes: Uint8Array): Promise<string>;
1337
+
1338
+ /**
1339
+ * @dstorage/chain — adapters/midnightSimulator.ts
1340
+ *
1341
+ * Midnight chain adapter backed by DataRegistrySimulator — runs the real
1342
+ * DataRegistry Compact circuits in-process without requiring a live network,
1343
+ * proof server, indexer, or wallet.
1344
+ *
1345
+ * Ownership is enforced by the real circuit (ownerSecret/ownerCommitment).
1346
+ * RefIds are circuit-derived (not random UUIDs). State is per-instance (no
1347
+ * shared module-level Map).
1348
+ *
1349
+ * ⚠️ Not for production: not decentralised, not immutable.
1350
+ * Replace with the real MidnightChainAdapter for production use.
1351
+ */
1352
+
1353
+ declare class MidnightSimulatorChainAdapter implements ChainAdapter {
1354
+ readonly name: ChainProviderName;
1355
+ readonly providerName: string;
1356
+ readonly paymentAdapter: PaymentAdapter;
1357
+ private readonly senderPk;
1358
+ private simulatorPromise;
1359
+ private readonly logger;
1360
+ private blockHeight;
1361
+ constructor(options?: {
1362
+ /**
1363
+ * Sender public key passed to the DataRegistrySimulator.
1364
+ * Affects Zswap local state only — does not influence DataRegistry circuit
1365
+ * ownership (which is controlled by ownerSecret).
1366
+ * Defaults to a fixed all-zeros test key.
1367
+ */
1368
+ senderPk?: string;
1369
+ logger?: ChainAdapterLogger;
1370
+ } & ({
1371
+ signingServerUrl: string;
1372
+ authToken: string;
1373
+ } | {
1374
+ signingServerUrl?: never;
1375
+ authToken?: never;
1376
+ }));
1377
+ private getSimulator;
1378
+ estimateCost(): Promise<ChainQuote>;
1379
+ writeReference(ref: ChainReference): Promise<ChainWriteResult>;
1380
+ readReference(refId: string): Promise<ChainReference>;
1381
+ listReferences(): Promise<DataReferenceSummary[]>;
1382
+ removeReference(refId: string, ownerSecret?: Uint8Array): Promise<void>;
1383
+ updateReference(refId: string, update: ChainReferenceUpdate, ownerSecret?: Uint8Array, newOwnerSecret?: Uint8Array): Promise<void>;
1384
+ setContractAddress(_address: string): void;
1385
+ getContractAddress(): string;
1386
+ deployDataRegistry(): Promise<string>;
1387
+ }
1388
+
1389
+ /**
1390
+ * @dstorage/chain — adapters/httpGateway.ts
1391
+ *
1392
+ * HTTP Gateway chain adapter — delegates reference storage to a remote REST
1393
+ * service. Useful for testing, staging environments, or custom backends that
1394
+ * expose a simple HTTP API instead of a blockchain node.
1395
+ */
1396
+
1397
+ interface HttpGatewayChainAdapterConfig {
1398
+ /** Scheme + host (+ optional port) shared by all endpoints. e.g. "http://localhost:3200" */
1399
+ baseUrl: string;
1400
+ /** Path appended to baseUrl for write (POST /{refId}) and update operations. e.g. "/api/refs" */
1401
+ writePath: string;
1402
+ /** Path appended to baseUrl for read (GET /{refId}) operations. */
1403
+ readPath: string;
1404
+ /** Path appended to baseUrl for listReferences (GET) operations. */
1405
+ listPath: string;
1406
+ /** Path appended to baseUrl for removeReference (DELETE /{refId}) operations. */
1407
+ deletePath: string;
1408
+ /**
1409
+ * Optional headers included in every outgoing request.
1410
+ * Useful for API tokens, authorization, or any other fixed headers required by
1411
+ * the gateway. Example: `{ "Authorization": "Bearer mytoken", "X-Api-Key": "abc" }`
1412
+ */
1413
+ headers?: Record<string, string>;
1414
+ /**
1415
+ * Optional custom fetch implementation. Useful when the gateway uses a custom CA
1416
+ * or client certificate: supply an undici Agent configured with the appropriate
1417
+ * `ca`, `cert`, and `key` options. Defaults to `globalThis.fetch` when omitted.
1418
+ */
1419
+ customFetch?: typeof fetch;
1420
+ logger?: ChainAdapterLogger;
1421
+ }
1422
+ declare class HttpGatewayChainAdapter implements ChainAdapter {
1423
+ readonly name: ChainProviderName;
1424
+ readonly providerName = "HTTP-Gateway-Chain-Adapter";
1425
+ private readonly logger;
1426
+ private readonly fetchFn;
1427
+ private readonly extraHeaders;
1428
+ private readonly writeUrl;
1429
+ private readonly readUrl;
1430
+ private readonly listUrl;
1431
+ private readonly deleteUrl;
1432
+ constructor(config: HttpGatewayChainAdapterConfig);
1433
+ writeReference(ref: ChainReference): Promise<ChainWriteResult>;
1434
+ updateReference(refId: string, update: ChainReferenceUpdate, _ownerSecret?: Uint8Array, _newOwnerSecret?: Uint8Array): Promise<void>;
1435
+ readReference(refId: string): Promise<ChainReference>;
1436
+ listReferences(): Promise<DataReferenceSummary[]>;
1437
+ removeReference(refId: string, ownerSecret?: Uint8Array): Promise<void>;
1438
+ getContractAddress(): string;
1439
+ estimateCost(): Promise<ChainQuote>;
1440
+ }
1441
+
1442
+ /**
1443
+ * Minimal interface the adapter requires from a wallet provider passed via
1444
+ * walletMode: "provider". Any object implementing WalletProvider and
1445
+ * MidnightProvider with an accessible WalletFacade satisfies this.
1446
+ */
1447
+ interface AdapterWalletProvider extends WalletProvider, MidnightProvider {
1448
+ readonly wallet: WalletFacade;
1449
+ }
1450
+
1451
+ /**
1452
+ * @dstorage/chain — adapters/midnight.ts
1453
+ *
1454
+ * Midnight Network chain adapter.
1455
+ *
1456
+ * Uses DataRegistryAPI (deployContract / findDeployedContract / callTx) from
1457
+ * @midnight-ntwrk/midnight-js-contracts via the api.ts wrapper, so that
1458
+ * midnight.ts only needs to manage the wallet lifecycle and provider assembly.
1459
+ *
1460
+ * Wallet lifecycle:
1461
+ * - 'provider': accepts a pre-built wallet provider (Node.js CLI)
1462
+ * - 'connector': connect to browser wallet extension (browser dApp)
1463
+ *
1464
+ * Transaction flow (handled by DataRegistryAPI internally):
1465
+ * 1. Build — construct the unproven circuit call
1466
+ * 2. Prove — send to proof server for ZK proof generation
1467
+ * 3. Balance — attach DUST fees via the connected wallet
1468
+ * 4. Submit — broadcast to the Midnight node
1469
+ * 5. Confirm — wait for block inclusion
1470
+ *
1471
+ * Docs: https://docs.midnight.network/develop/tutorial/building-a-dapp
1472
+ */
1473
+
1474
+ interface WalletAddresses {
1475
+ unshielded: string;
1476
+ shielded: string;
1477
+ dust: string;
1478
+ }
1479
+ type SUPPORTED_NETWORKS = {
1480
+ [K in "preprod" | "undeployed"]: EnvironmentConfiguration;
1481
+ };
1482
+ declare const NETWORKS: SUPPORTED_NETWORKS;
1483
+ /** Internal environment configuration passed to wallet SDK providers. */
1484
+ interface EnvironmentConfiguration {
1485
+ networkId: string;
1486
+ nodeHttp: string;
1487
+ nodeWs: string;
1488
+ indexerHttp: string;
1489
+ indexerWs: string;
1490
+ proofServer: string;
1491
+ proofServerMaxRetries?: number;
1492
+ }
1493
+ interface BaseConfig {
1494
+ /**
1495
+ * Midnight node RPC endpoint.
1496
+ */
1497
+ nodeEndpoint?: string;
1498
+ nodeWsEndpoint?: string;
1499
+ /**
1500
+ * Optional logger for SDK operational output.
1501
+ * Pass `logger: console` to see all output, or inject your own logger.
1502
+ * Omit to suppress all SDK log output.
1503
+ */
1504
+ logger?: ChainAdapterLogger;
1505
+ /**
1506
+ * Midnight indexer HTTP (GraphQL) endpoint for state queries.
1507
+ */
1508
+ indexerEndpoint?: string;
1509
+ /**
1510
+ * Midnight indexer WebSocket endpoint for real-time subscriptions.
1511
+ */
1512
+ indexerWsEndpoint?: string;
1513
+ /**
1514
+ * Proof server URL.
1515
+ */
1516
+ proofServerEndpoint: string;
1517
+ /**
1518
+ * Number of times to retry a proof-server circuit call on failure before
1519
+ * giving up. Uses exponential backoff (1 s, 2 s, 4 s, …).
1520
+ * Defaults to 3. Set to 1 to disable retries.
1521
+ */
1522
+ proofServerMaxRetries?: number;
1523
+ /**
1524
+ * On-chain address of an already-deployed DataRegistry contract.
1525
+ * If omitted, sdk.init() will deploy a new contract and return its address.
1526
+ */
1527
+ contractAddress?: string;
1528
+ /**
1529
+ * Target network. Controls wallet networkId, address format, and fee overhead.
1530
+ */
1531
+ network: NetworkId;
1532
+ /**
1533
+ * Base URL of the dStorage managed payment signing server (no trailing slash).
1534
+ * When provided, transaction balancing is delegated to the server instead of
1535
+ * the local wallet.
1536
+ */
1537
+ signingServerUrl?: string;
1538
+ /**
1539
+ * Bearer token sent as the `Authorization` header to authenticate with the signing server.
1540
+ * Required when `signingServerUrl` is provided.
1541
+ */
1542
+ authToken?: string;
1543
+ }
1544
+ type MidnightChainAdapterConfig = BaseConfig & ({
1545
+ /**
1546
+ * Provider mode: the caller builds, starts, syncs, and passes in a wallet provider.
1547
+ * The adapter uses it directly without managing any wallet lifecycle.
1548
+ * Use this mode for Node.js CLI apps (e.g., the dStorage console demo).
1549
+ */
1550
+ walletMode: "provider";
1551
+ /**
1552
+ * A fully initialised wallet provider (started and synced before passing in).
1553
+ * Must implement AdapterWalletProvider (WalletProvider + MidnightProvider + .wallet).
1554
+ */
1555
+ walletProvider: AdapterWalletProvider;
1556
+ /**
1557
+ * LevelDB encryption password for the private state store.
1558
+ * Must satisfy the policy: at least 3 of 4 character classes
1559
+ * (uppercase, lowercase, digits, special characters).
1560
+ * Recommended derivation: "Aa1!" + seedHex (all 4 classes guaranteed).
1561
+ */
1562
+ privateStatePassword: string;
1563
+ /**
1564
+ * Path to the directory that contains the compiled DataRegistry contract's ZK artifacts.
1565
+ * Expected sub-directories:
1566
+ * ${zkArtifactsPath}/keys/${circuitId}.prover
1567
+ * ${zkArtifactsPath}/keys/${circuitId}.verifier
1568
+ * ${zkArtifactsPath}/zkir/${circuitId}.bzkir
1569
+ *
1570
+ * Required for write operations (storeReference, etc.) in provider mode.
1571
+ */
1572
+ zkArtifactsPath?: string;
1573
+ } | {
1574
+ /**
1575
+ * Browser wallet connector mode.
1576
+ * Delegates all key management to the wallet extension (e.g., Midnight Lace).
1577
+ */
1578
+ walletMode: "connector";
1579
+ /**
1580
+ * Wallet connector name. Default: 'mnLace' (Midnight Lace).
1581
+ * Example: window.midnight.mnLace
1582
+ */
1583
+ connectorName?: string;
1584
+ /**
1585
+ * Base URL from which the ZK artifacts for the DataRegistry contract are served.
1586
+ * Must be an absolute http/https URL.
1587
+ *
1588
+ * In Vite apps: copy the compiled contract's keys/ and zkir/ directories
1589
+ * to public/ and set this to window.location.origin.
1590
+ *
1591
+ * Required for write operations (storeReference, etc.) in connector mode.
1592
+ */
1593
+ zkConfigBaseUrl?: string;
1594
+ /**
1595
+ * Allow a proof server URL supplied by the wallet extension to override
1596
+ * `proofServerEndpoint`. Default: `false`.
1597
+ *
1598
+ * When `false` (default): if the wallet returns a `proverServerUri` that differs
1599
+ * from the configured endpoint, it is logged as a warning and ignored — the
1600
+ * developer-configured endpoint is always used.
1601
+ *
1602
+ * Set to `true` only when you trust the connected wallet extension to supply a safe
1603
+ * proof server (e.g. Midnight Lace in a controlled deployment). A compromised wallet
1604
+ * extension can redirect ZK witness inputs — including the ownerSecret — to an
1605
+ * attacker-controlled server, allowing reference takeover or deletion.
1606
+ */
1607
+ allowWalletProofServer?: boolean;
1608
+ });
1609
+ declare class MidnightChainAdapter implements ChainAdapter {
1610
+ readonly name: ChainProviderName;
1611
+ readonly providerName: string;
1612
+ readonly managedPaymentAdapter: ManagedPaymentAdapter | null;
1613
+ _lastPaymentReceipt: PaymentReceipt | undefined;
1614
+ private facade;
1615
+ private connectorAPI;
1616
+ private addresses;
1617
+ private connectorCoinPublicKey;
1618
+ private connectorEncPublicKey;
1619
+ private connectorIndexerHttp;
1620
+ private connectorIndexerWs;
1621
+ private connectorProofServer;
1622
+ private readonly walletMode;
1623
+ private readonly connectorName;
1624
+ private readonly allowWalletProofServer;
1625
+ private readonly logger;
1626
+ private _contractAddress;
1627
+ private _zkArtifactsPath;
1628
+ private _zkConfigBaseUrl;
1629
+ private _initialized;
1630
+ private _api;
1631
+ private _injectedWalletProvider;
1632
+ private _injectedPrivateStatePassword;
1633
+ private readonly config;
1634
+ constructor(config: MidnightChainAdapterConfig);
1635
+ /**
1636
+ * If a payment adapter was set, it delegates wallet provider wrapping to
1637
+ * the payment adapter, otherwise returns the provider unchanged (no wrapping needed).
1638
+ * When the managed payment adaper is set, It wraps the wallet provider's balanceTx()
1639
+ * to route transaction balancing through the managed signing server instead of the
1640
+ * local wallet. The server receives the hex-serialized UnboundTransaction,
1641
+ * balances and signs it, and returns the FinalizedTransaction in the receipt.
1642
+ */
1643
+ private _withProofRetry;
1644
+ private _wrapPaymentProvider;
1645
+ /**
1646
+ * Build a mode-specific ZK config provider.
1647
+ *
1648
+ * Facade (Node.js): reads ZK artifact files from the local filesystem via zkArtifactsPath.
1649
+ * Connector (browser): fetches ZK artifacts over HTTP via zkConfigBaseUrl.
1650
+ */
1651
+ private _buildZkConfigProvider;
1652
+ /**
1653
+ * midnight-js-contracts expects privateStateProvider.setContractAddress().
1654
+ * Some providers (e.g. in-memory) do not implement it, so we add a no-op shim.
1655
+ * Providers that already implement it (e.g. levelPrivateStateProvider) are left
1656
+ * untouched — their real implementation must run so the contract address is set
1657
+ * before any private state access.
1658
+ */
1659
+ private _withContractAddressShim;
1660
+ /**
1661
+ * Assemble DataRegistryProviders from mode-specific pieces.
1662
+ */
1663
+ private _assembleDataRegistryProviders;
1664
+ /**
1665
+ * Build providers for connector (browser) mode.
1666
+ * Uses in-memory private state, FetchZkConfigProvider, and the Lace wallet connector API.
1667
+ */
1668
+ private _buildConnectorProviders;
1669
+ /**
1670
+ * Build DataRegistryProviders using a pre-built, already-started wallet provider.
1671
+ * The caller is responsible for wallet construction, sync, and fund-waiting before
1672
+ * passing the provider to the adapter via walletMode: "provider".
1673
+ */
1674
+ private _buildWalletProviderMode;
1675
+ /**
1676
+ * Lazily initialize and return the DataRegistryAPI.
1677
+ * Joins the existing contract at the configured address.
1678
+ * Throws if no address is configured and no deployment has occurred.
1679
+ */
1680
+ private _getAPI;
1681
+ /** Midnight contract addresses are 32 bytes encoded as 64 lowercase hex chars. */
1682
+ private static _validateContractAddress;
1683
+ /**
1684
+ * Set the contract address to use for subsequent operations.
1685
+ * Resets the cached DataRegistryAPI so the next call re-joins at the new address.
1686
+ */
1687
+ setContractAddress(address: string): void;
1688
+ /**
1689
+ * Get the contract address
1690
+ */
1691
+ getContractAddress(): string;
1692
+ /**
1693
+ * List references currently stored in the joined/deployed DataRegistry contract.
1694
+ * For Arweave references, storageId is the original txId string.
1695
+ * For other providers, storageId is the hex of the stored Bytes<32>.
1696
+ */
1697
+ listReferences(): Promise<DataReferenceSummary[]>;
1698
+ /**
1699
+ * Look up a single reference by its refId.
1700
+ * Returns { storageId, storageProvider } with the storageId decoded to the
1701
+ * original storage network identifier (e.g. Arweave txId), or null if not found.
1702
+ */
1703
+ readReference(refId: string): Promise<ChainReference>;
1704
+ estimateCost(): Promise<ChainQuote>;
1705
+ writeReference(ref: ChainReference): Promise<ChainWriteResult>;
1706
+ removeReference(refId: string, ownerSecret?: Uint8Array): Promise<void>;
1707
+ /**
1708
+ * Update the mutable fields of an existing reference.
1709
+ *
1710
+ * `update.storageId` is stored verbatim on-chain without format validation. Passing a
1711
+ * malformed storageId permanently bricks the reference (silent decryption failure on read).
1712
+ * Validate the format against the storage provider before calling this method.
1713
+ */
1714
+ updateReference(refId: string, update: ChainReferenceUpdate, ownerSecret?: Uint8Array, newOwnerSecret?: Uint8Array): Promise<void>;
1715
+ /**
1716
+ * Initialize the wallet.
1717
+ * Branches based on wallet mode:
1718
+ * - 'facade': derive keys, build WalletFacade, wait for sync (Node.js CLI)
1719
+ * - 'connector': connect to browser wallet extension, extract addresses (browser dApp)
1720
+ *
1721
+ * Must be called before write operations or getBalances().
1722
+ * All Midnight wallet SDK imports are dynamic to avoid hard build-time failures.
1723
+ */
1724
+ init(): Promise<string>;
1725
+ /**
1726
+ * Initialize in connector mode: connect to browser wallet extension.
1727
+ *
1728
+ * Discovers available wallets by enumerating window.midnight, as per the
1729
+ * dApp connector spec: https://docs.midnight.network/api-reference/dapp-connector
1730
+ */
1731
+ private _initConnector;
1732
+ /**
1733
+ * Return wallet addresses derived during init().
1734
+ * Throws if init() not yet called.
1735
+ */
1736
+ getAddresses(): WalletAddresses;
1737
+ /**
1738
+ * Read NIGHT and DUST balances.
1739
+ */
1740
+ getBalances(): Promise<WalletBalances>;
1741
+ }
1742
+
1743
+ /**
1744
+ * @dstorage/chain — adapters/midnight/sync.ts
1745
+ *
1746
+ * Wallet sync-waiting helper.
1747
+ */
1748
+
1749
+ /**
1750
+ * Wait for a WalletFacade to report `isSynced`, falling back to the current
1751
+ * facade state after `timeoutMs`.
1752
+ *
1753
+ * `isSynced` (and `waitForSyncedState()`) gate on an internal `isConnected` flag
1754
+ * on the shielded/dust sub-wallets that only flips true once a non-empty batch of
1755
+ * events arrives from the indexer — on a quiet chain (idle Preprod, fresh
1756
+ * undeployed network) it can stay false forever even though the wallet has
1757
+ * genuinely caught up, so waiting on it unconditionally can hang indefinitely.
1758
+ */
1759
+ declare function waitForFacadeSync(facade: Pick<WalletFacade, "state">, timeoutMs?: number): Promise<FacadeState>;
1760
+
1761
+ declare const EncryptionErrorCode: {
1762
+ readonly KEYPAIR_MISSING_SECRET_KEY: 13001;
1763
+ readonly MNEMONIC_TOO_SHORT: 13002;
1764
+ readonly PASSWORD_UNSUPPORTED_KDF: 13003;
1765
+ readonly PASSWORD_EMPTY_SALT: 13004;
1766
+ readonly PASSWORD_UNKNOWN_PRESET: 13005;
1767
+ readonly PASSWORD_TOO_SHORT: 13006;
1768
+ readonly PASSWORD_TOO_FEW_DISTINCT: 13007;
1769
+ readonly PASSWORD_SEQUENTIAL_RUN: 13008;
1770
+ readonly PASSWORD_KEYBOARD_WALK: 13009;
1771
+ readonly PASSWORD_ENTROPY_TOO_LOW: 13010;
1772
+ };
1773
+ type EncryptionErrorCode = (typeof EncryptionErrorCode)[keyof typeof EncryptionErrorCode];
1774
+
1775
+ /**
1776
+ * @dstorage/encryption — types.ts
1777
+ *
1778
+ * The EncryptionAdapter interface: the unified abstraction for how the
1779
+ * dStorage SDK wraps and unwraps per-upload Data Encryption Keys (DEKs).
1780
+ *
1781
+ * Both symmetric (password, mnemonic) and asymmetric (ML-KEM) adapters implement
1782
+ * this interface, so the core SDK calls wrapDek/unwrapDek uniformly with no
1783
+ * knowledge of which algorithm is in use.
1784
+ *
1785
+ * The result of wrapDek() is stored as a KeyWrapper entry in the on-chain
1786
+ * KeyEnvelope. At retrieval time, the same result is passed back to unwrapDek()
1787
+ * to recover the DEK.
1788
+ */
1789
+
1790
+ /**
1791
+ * Wraps and unwraps per-upload DEKs using adapter-specific key material.
1792
+ *
1793
+ * Implementations:
1794
+ * PasswordEncryptionAdapter — symmetric: scrypt → HKDF → KEK → XChaCha20
1795
+ * MnemonicEncryptionAdapter — symmetric: BIP-39 seed → HKDF → KEK → XChaCha20
1796
+ * KeypairEncryptionAdapter — asymmetric: ML-KEM encapsulate/decapsulate + HKDF + XChaCha20
1797
+ */
1798
+ interface EncryptionAdapter {
1799
+ /** Stable identifier used as wrapKeyName in key envelopes. */
1800
+ readonly name: string;
1801
+ /**
1802
+ * Wrap a DEK under this adapter's key material.
1803
+ * Called once per upload, per adapter.
1804
+ *
1805
+ * @param dek 32-byte Data Encryption Key to protect
1806
+ * @returns WrappedDekResult to store in the on-chain key envelope
1807
+ */
1808
+ wrapDek(dek: Uint8Array): Promise<WrappedDekResult>;
1809
+ /**
1810
+ * Unwrap a DEK from a previously wrapped result.
1811
+ * Called at retrieval time using the same result that wrapDek() returned.
1812
+ *
1813
+ * @param data WrappedDekResult from the on-chain key envelope
1814
+ * @returns 32-byte Data Encryption Key
1815
+ * @throws If the adapter's key material cannot decrypt the wrapped DEK
1816
+ */
1817
+ unwrapDek(data: WrappedDekResult): Promise<Uint8Array>;
1818
+ /**
1819
+ * Zero any raw key bytes held by this adapter and mark it unusable.
1820
+ * Optional — only adapters holding raw byte arrays implement this.
1821
+ * Call after the adapter is no longer needed to minimise the window
1822
+ * during which secret key material sits in GC-reachable memory.
1823
+ */
1824
+ destroy?(): void;
1825
+ }
1826
+
1827
+ declare class KeypairEncryptionAdapter implements EncryptionAdapter {
1828
+ readonly name: string;
1829
+ readonly publicKey: Uint8Array;
1830
+ private secretKey;
1831
+ private readonly variant;
1832
+ private readonly context;
1833
+ private constructor();
1834
+ /**
1835
+ * Upload-only adapter — holds only the Public Key.
1836
+ * wrapDek() works normally; unwrapDek() throws (no SK available).
1837
+ */
1838
+ static fromPublicKey(pk: Uint8Array, context: string, variant?: MLKemVariant): KeypairEncryptionAdapter;
1839
+ /**
1840
+ * Full adapter — holds both Public Key and Secret Key.
1841
+ * Both wrapDek() and unwrapDek() work.
1842
+ */
1843
+ static fromKeypair(pk: Uint8Array, sk: Uint8Array, context: string, variant?: MLKemVariant): KeypairEncryptionAdapter;
1844
+ /**
1845
+ * Generate a fresh random ML-KEM keypair.
1846
+ *
1847
+ * Returns the adapter (with both PK+SK) plus the raw keys so the caller
1848
+ * can persist the secret key and share the public key separately.
1849
+ *
1850
+ * @param context Domain-separation string bound into the KEK derivation
1851
+ * @param variant Default: "mlkem768".
1852
+ */
1853
+ static generateKeypair(context: string, variant?: MLKemVariant): {
1854
+ adapter: KeypairEncryptionAdapter;
1855
+ publicKey: Uint8Array;
1856
+ secretKey: Uint8Array;
1857
+ };
1858
+ /**
1859
+ * Deterministically derive a ML-KEM keypair from a BIP-39 mnemonic phrase or hex seed.
1860
+ *
1861
+ * Delegates to MnemonicEncryptionAdapter.intoKeypairEncryptionAdapter() so all
1862
+ * mnemonic/seed handling lives in a single place.
1863
+ *
1864
+ * Same inputs + variant always produce the same keypair.
1865
+ *
1866
+ * `seedHex` may be either 32 bytes (64 hex chars) or 64 bytes (128 hex chars) —
1867
+ * both are expanded to the 64-byte ML-KEM seed via HKDF.
1868
+ *
1869
+ * @param input { mnemonic } (24-word BIP-39) or { seedHex } (32- or 64-byte hex)
1870
+ * @param context Domain-separation string bound into the KEK derivation
1871
+ * @param variant Default: "mlkem768"
1872
+ */
1873
+ static fromMnemonic(input: {
1874
+ mnemonic?: string;
1875
+ seedHex?: string;
1876
+ }, context: string, variant?: MLKemVariant): Promise<KeypairEncryptionAdapter>;
1877
+ /**
1878
+ * Deterministically derive a ML-KEM keypair from a password and salt.
1879
+ *
1880
+ * Delegates to PasswordEncryptionAdapter.intoKeypairEncryptionAdapter() so all
1881
+ * password handling (scrypt params, entropy validation, 64-byte seed derivation)
1882
+ * lives in a single place.
1883
+ *
1884
+ * Same password + salt + variant always produces the same keypair.
1885
+ *
1886
+ * @param password User password (validated for entropy)
1887
+ * @param salt Domain salt — must not be empty
1888
+ * @param context Domain-separation string bound into the KEK derivation
1889
+ * @param variant Default: "mlkem768"
1890
+ * @param params Optional custom scrypt params
1891
+ */
1892
+ static fromPassword(password: string, salt: string, context: string, variant?: MLKemVariant, params?: {
1893
+ N?: number;
1894
+ r?: number;
1895
+ p?: number;
1896
+ }): Promise<KeypairEncryptionAdapter>;
1897
+ /**
1898
+ * Zero the Secret Key bytes and mark this adapter as read-only.
1899
+ * Call when the adapter is no longer needed to minimise the window
1900
+ * during which raw ML-KEM key material sits in GC-reachable memory.
1901
+ * After destroy(), unwrapDek() will throw.
1902
+ */
1903
+ destroy(): void;
1904
+ wrapDek(dek: Uint8Array): Promise<WrappedDekResult>;
1905
+ unwrapDek(data: WrappedDekResult): Promise<Uint8Array>;
1906
+ }
1907
+
1908
+ declare class MnemonicEncryptionAdapter implements EncryptionAdapter {
1909
+ readonly name = "mnemonic";
1910
+ /**
1911
+ * Non-extractable HKDF CryptoKey imported from the BIP-39 / hex seed.
1912
+ * Raw seed bytes are zeroed immediately after import.
1913
+ */
1914
+ private readonly kekMaterialPromise;
1915
+ constructor(input: {
1916
+ mnemonic?: string;
1917
+ seedHex?: string;
1918
+ });
1919
+ wrapDek(dek: Uint8Array): Promise<WrappedDekResult>;
1920
+ unwrapDek({ wrappedDek }: WrappedDekResult): Promise<Uint8Array>;
1921
+ /**
1922
+ * Deterministically derive a ML-KEM keypair from this adapter's key material.
1923
+ *
1924
+ * Uses Web Crypto HKDF to derive a 64-byte ML-KEM seed from the stored
1925
+ * CryptoKey with info="dstorage:mlkem-seed:v1", domain-separated from the
1926
+ * symmetric KEK derivation path. The same derivation applies to all seed
1927
+ * types (mnemonic or hex), producing consistent, domain-separated keypairs.
1928
+ *
1929
+ * @param context Domain-separation string bound into the KEK derivation
1930
+ * @param variant ML-KEM variant. Default: "mlkem768".
1931
+ */
1932
+ intoKeypairEncryptionAdapter(context: string, variant?: MLKemVariant): Promise<KeypairEncryptionAdapter>;
1933
+ }
1934
+
1935
+ /**
1936
+ * Named scrypt parameter presets. Use these at construction time as a
1937
+ * convenience — they expand to concrete N/r/p values. For persistence,
1938
+ * always store the actual values from `getKdfParams()`, not the preset name.
1939
+ *
1940
+ * "v1" — N=131072, 128 MB, ~500ms–1s — OWASP-recommended minimum.
1941
+ * Use for all sensitive data (default).
1942
+ * "v1-lite" — N=65536, 64 MB, ~200–400ms — half the work factor of "v1".
1943
+ * An offline attacker needs half the resources to brute-force the
1944
+ * same password. Use only on memory-constrained devices (mobile,
1945
+ * low-RAM embedded). Prefer "v1" whenever the environment allows.
1946
+ */
1947
+ declare const KDF_PRESETS: {
1948
+ readonly v1: {
1949
+ readonly N: 131072;
1950
+ readonly r: 8;
1951
+ readonly p: 1;
1952
+ };
1953
+ readonly "v1-lite": {
1954
+ readonly N: 65536;
1955
+ readonly r: 8;
1956
+ readonly p: 1;
1957
+ };
1958
+ };
1959
+ type KdfPreset = keyof typeof KDF_PRESETS;
1960
+ /**
1961
+ * The resolved scrypt parameters to store alongside encrypted data.
1962
+ * Interoperable: any scrypt implementation in any language can re-derive
1963
+ * the key from these values without knowledge of this SDK's preset names.
1964
+ */
1965
+ interface StoredKdfParams {
1966
+ /** Always "scrypt" — identifies the KDF algorithm. */
1967
+ kdf: "scrypt";
1968
+ N: number;
1969
+ r: number;
1970
+ p: number;
1971
+ }
1972
+ interface PasswordEncryptionAdapterConfig {
1973
+ /** The user's password. Validated for entropy at construction time. */
1974
+ password: string;
1975
+ /**
1976
+ * Domain salt — REQUIRED, must not be empty.
1977
+ *
1978
+ * Recommended: an app-specific label combined with a per-user identifier,
1979
+ * e.g. `"myapp:v1:alice@example.com"` or `"myapp:v1:" + tenantId`.
1980
+ *
1981
+ * Using a string is convenient; it is UTF-8 encoded before use.
1982
+ * Pass a Uint8Array if you prefer raw bytes.
1983
+ *
1984
+ * Same password + same salt → same seed, forever. Different salts produce
1985
+ * independent seeds even for identical passwords.
1986
+ */
1987
+ salt: string | Uint8Array;
1988
+ /**
1989
+ * Named scrypt preset. Controls N/r/p parameters.
1990
+ * Default: "v1" (N=131072, 128 MB, ~500ms–1s).
1991
+ *
1992
+ * Takes precedence over `params` when both are provided.
1993
+ * Preset names are convenience shorthands — use `getKdfParams()` to get
1994
+ * the actual values for storage.
1995
+ */
1996
+ preset?: KdfPreset;
1997
+ /**
1998
+ * Custom scrypt parameters. Only used when `preset` is not provided.
1999
+ * Prefer `preset` for well-known configurations.
2000
+ */
2001
+ params?: {
2002
+ N?: number;
2003
+ r?: number;
2004
+ p?: number;
2005
+ };
2006
+ /**
2007
+ * Minimum password length. Default: 12 characters.
2008
+ */
2009
+ minPasswordLength?: number;
2010
+ /**
2011
+ * Minimum estimated entropy in bits (charset-based estimate). Default: 60 bits.
2012
+ *
2013
+ * The built-in estimator uses character pool size × length. It catches trivially
2014
+ * weak passwords but does not detect dictionary words. Use `additionalValidators`
2015
+ * for higher assurance.
2016
+ */
2017
+ minEntropyBits?: number;
2018
+ /**
2019
+ * Optional additional password validator functions. Each receives the password
2020
+ * and should throw an Error with a helpful message if the password is rejected.
2021
+ * Run after the built-in checks. Useful for integrating zxcvbn or a blacklist.
2022
+ *
2023
+ * @example
2024
+ * additionalValidators: [(pw) => {
2025
+ * if (zxcvbn(pw).score < 3) throw new Error("Password is too common.");
2026
+ * }]
2027
+ */
2028
+ additionalValidators?: Array<(password: string) => void>;
2029
+ }
2030
+ /** Config for `PasswordEncryptionAdapter.fromKdfParams()` — reconstructs from stored metadata. */
2031
+ interface FromKdfParamsConfig extends StoredKdfParams {
2032
+ password: string;
2033
+ salt: string | Uint8Array;
2034
+ minPasswordLength?: number;
2035
+ minEntropyBits?: number;
2036
+ additionalValidators?: Array<(password: string) => void>;
2037
+ }
2038
+ declare class PasswordEncryptionAdapter implements EncryptionAdapter {
2039
+ readonly name = "password";
2040
+ private readonly salt;
2041
+ private readonly N;
2042
+ private readonly r;
2043
+ private readonly p;
2044
+ /**
2045
+ * Non-extractable HKDF CryptoKey imported from the scrypt output.
2046
+ * The raw scrypt bytes are zeroed immediately after import; this handle is
2047
+ * the only in-memory representation of the secret from this point on.
2048
+ */
2049
+ private readonly kekMaterialPromise;
2050
+ constructor(config: PasswordEncryptionAdapterConfig);
2051
+ /**
2052
+ * Reconstruct an adapter from parameters previously stored via `getKdfParams()`.
2053
+ * Use this when loading existing encrypted data — ensures the exact same N/r/p
2054
+ * are used regardless of what the current SDK defaults are.
2055
+ *
2056
+ * @example
2057
+ * const adapter = PasswordEncryptionAdapter.fromKdfParams({
2058
+ * password,
2059
+ * salt: meta.salt,
2060
+ * kdf: meta.kdf,
2061
+ * N: meta.N,
2062
+ * r: meta.r,
2063
+ * p: meta.p,
2064
+ * });
2065
+ */
2066
+ static fromKdfParams(config: FromKdfParamsConfig): PasswordEncryptionAdapter;
2067
+ /**
2068
+ * Returns the resolved KDF parameters to store alongside encrypted data.
2069
+ *
2070
+ * These values are language- and SDK-agnostic: any scrypt implementation
2071
+ * can re-derive the key from `{ kdf, N, r, p }` + the original salt and
2072
+ * password, without any knowledge of this SDK's preset names.
2073
+ *
2074
+ * @example
2075
+ * const meta = {
2076
+ * ...adapter.getKdfParams(), // { kdf: "scrypt", N: 131072, r: 8, p: 1 }
2077
+ * salt: "myapp:alice@example.com",
2078
+ * };
2079
+ * await db.save({ encryptedData, meta });
2080
+ */
2081
+ getKdfParams(): StoredKdfParams;
2082
+ wrapDek(dek: Uint8Array): Promise<WrappedDekResult>;
2083
+ unwrapDek({ wrappedDek }: WrappedDekResult): Promise<Uint8Array>;
2084
+ /**
2085
+ * Deterministically derive a ML-KEM keypair from this adapter's key material.
2086
+ *
2087
+ * Uses Web Crypto HKDF to derive a 64-byte ML-KEM seed from the stored
2088
+ * CryptoKey, domain-separated from the symmetric KEK derivation path with
2089
+ * info="dstorage:mlkem-seed:v1". This is equivalent to noble's
2090
+ * hkdf(sha256, scryptOutput, undefined, info, 64) but avoids materialising
2091
+ * the raw scrypt output in a JS-accessible variable.
2092
+ *
2093
+ * Same password + salt + variant always produces the same keypair.
2094
+ *
2095
+ * @param context Domain-separation string bound into the KEK derivation
2096
+ * @param variant ML-KEM variant. Default: "mlkem768".
2097
+ */
2098
+ intoKeypairEncryptionAdapter(context: string, variant?: MLKemVariant): Promise<KeypairEncryptionAdapter>;
2099
+ }
2100
+ /**
2101
+ * Generate a cryptographically random password suitable for use with
2102
+ * `PasswordEncryptionAdapter` when post-quantum-safe key derivation is required.
2103
+ *
2104
+ * Produces 32 random bytes (256 bits of real entropy) encoded as a 43-character
2105
+ * base64url string. When combined with `intoKeypairEncryptionAdapter()`, this
2106
+ * provides a fully recoverable path to ML-KEM 192-bit post-quantum security:
2107
+ * the password is the only secret needed to re-derive the same ML-KEM keypair
2108
+ * on any device, without storing the private key itself.
2109
+ *
2110
+ * @example
2111
+ * const password = generatePqsPassword(); // store this securely
2112
+ * const adapter = new PasswordEncryptionAdapter({ password, salt: "myapp:alice" });
2113
+ * const keypairAdapter = await adapter.intoKeypairEncryptionAdapter("myapp:v1");
2114
+ * await sdk.connect(keypairAdapter); // full 192-bit PQ security
2115
+ */
2116
+ declare function generatePqsPassword(): string;
2117
+
2118
+ /**
2119
+ * @dstorage/core — types.ts
2120
+ * Top-level types for the dStorage SDK public API.
2121
+ */
2122
+
2123
+ /**
2124
+ * Minimal logger interface accepted by every SDK class.
2125
+ * Compatible with `console` — pass `logger: console` for zero-boilerplate logging.
2126
+ * Omit the field entirely to suppress all SDK output.
2127
+ */
2128
+ interface Logger {
2129
+ log(component: string, msg: string): void;
2130
+ warn(component: string, msg: string): void;
2131
+ error(component: string, msg: string): void;
2132
+ debug?(component: string, msg: string): void;
2133
+ }
2134
+ /** Wallet connection info returned after connecting */
2135
+ interface WalletInfo {
2136
+ address: string;
2137
+ chainProvider: ChainProviderName;
2138
+ /** The raw signature (or PBKDF2 seed) used to derive the encryption key (kept in memory only) */
2139
+ _signatureHex: string;
2140
+ }
2141
+ /** Configuration passed to dStorage constructor */
2142
+ interface DStorageConfig {
2143
+ /** Storage adapter to use (MockStorageAdapter | ArweaveStorageAdapter | ...) */
2144
+ storageAdapter: StorageAdapter;
2145
+ /**
2146
+ * Chain adapter to use (MockChainAdapter | MidnightChainAdapter | ...).
2147
+ * When omitted the SDK operates in storage-only mode — uploads store to the
2148
+ * storage backend but no on-chain reference is written.
2149
+ */
2150
+ chainAdapter?: ChainAdapter;
2151
+ /**
2152
+ * Encryption adapters that wrap and unwrap per-upload Data Encryption Keys (DEKs).
2153
+ * Each adapter produces an independent wrapped DEK; any of them can independently decrypt.
2154
+ *
2155
+ * Choose the adapter(s) preferred by the user:
2156
+ * PasswordEncryptionAdapter — scrypt-derived from a user password + salt
2157
+ * MnemonicEncryptionAdapter — BIP-39 mnemonic or hex seed (Node.js / facade mode)
2158
+ * KeypairEncryptionAdapter — post-quantum asymmetric (ML-KEM keypair)
2159
+ *
2160
+ * When omitted or empty, no encryption key is available and all uploaded data
2161
+ * will be stored as plaintext (public).
2162
+ *
2163
+ * @example
2164
+ * // Single adapter (most common)
2165
+ * encryptionAdapters: [new PasswordEncryptionAdapter({ password, salt })]
2166
+ *
2167
+ * @example
2168
+ * // Two adapters — data accessible by either password or mnemonic
2169
+ * encryptionAdapters: [
2170
+ * new PasswordEncryptionAdapter({ password, salt }),
2171
+ * new MnemonicEncryptionAdapter({ mnemonic }),
2172
+ * ]
2173
+ */
2174
+ encryptionAdapters?: EncryptionAdapter[];
2175
+ /**
2176
+ * Optional logger for SDK operational output.
2177
+ * Pass `logger: console` to see all output, or inject your own logger.
2178
+ * Omit to suppress all SDK log output.
2179
+ */
2180
+ logger?: Logger;
2181
+ }
2182
+ /**
2183
+ * Payload included in both `StorePartialError.recovery` and the `"stored"`
2184
+ * phase of `StoreProgress`. Contains enough information to retry a failed
2185
+ * chain write via `registerReference()` without re-uploading.
2186
+ *
2187
+ * `keyEnvelope` is the DEK encrypted under the user's KEK — safe to persist
2188
+ * (e.g. in localStorage or a database). It is `undefined` for public uploads
2189
+ * since their on-chain reference does not depend on a content DEK.
2190
+ */
2191
+ interface StoreRecovery {
2192
+ storageId: string;
2193
+ /** Storage provider that holds the content — required by registerReference(). */
2194
+ storageProvider: StorageProviderName;
2195
+ keyEnvelope: string | undefined;
2196
+ /**
2197
+ * BLAKE3 hash of the ciphertext bytes stored at `storageId`, hex-encoded (64 chars).
2198
+ * Pass to `registerReference()` to preserve the on-chain integrity check on the recovered reference.
2199
+ */
2200
+ contentHash?: string;
2201
+ }
2202
+ interface StoreProgress {
2203
+ phase: "encrypting" | "uploading" | "stored" | "finalizing";
2204
+ chunksUploaded: number;
2205
+ totalChunks: number;
2206
+ bytesUploaded: number;
2207
+ totalBytes: number;
2208
+ /**
2209
+ * Present when `phase === "stored"`. Fired after the storage write succeeds
2210
+ * and before the chain write begins — persist this to recover from a partial
2211
+ * failure without re-uploading.
2212
+ */
2213
+ recovery?: StoreRecovery;
2214
+ }
2215
+ interface StoreOptions {
2216
+ /**
2217
+ * Unencrypted key/value tags forwarded to the storage layer (e.g. Arweave tx tags).
2218
+ * Never written on-chain.
2219
+ */
2220
+ tags?: Record<string, string>;
2221
+ /**
2222
+ * Encrypted key/value metadata stored on-chain alongside the key envelope.
2223
+ * Encrypted with the content DEK — only holders of a valid KEK can read it.
2224
+ * Returned in `RetrieveResult.metadata` after decryption.
2225
+ * Not supported for public (`isPublic: true`) stores.
2226
+ */
2227
+ metadata?: Record<string, string>;
2228
+ onProgress?: (progress: StoreProgress) => void;
2229
+ /** When true, content is stored unencrypted and the storageId is written on-chain as plaintext. */
2230
+ isPublic?: boolean;
2231
+ /**
2232
+ * Optional caller-supplied reference ID, forwarded to the chain adapter as
2233
+ * {@link ChainReference.refId}. Adapters that control their own ID generation
2234
+ * (e.g. mock, HTTP gateway) use this as the stored and returned identifier.
2235
+ * Adapters where the on-chain protocol determines the ID (e.g. Midnight)
2236
+ * ignore this field — the chain-assigned ID is returned instead.
2237
+ */
2238
+ refId?: string;
2239
+ }
2240
+ /**
2241
+ * Aggregated cost estimate for a complete store operation.
2242
+ * Built from two quotes — one from the storage adapter and one from the chain adapter.
2243
+ */
2244
+ interface CostEstimate {
2245
+ storageCost: {
2246
+ amount: string;
2247
+ token: TokenSymbol;
2248
+ };
2249
+ /** Chain cost. Undefined when no chain adapter is configured. */
2250
+ chainCost?: {
2251
+ amount: string;
2252
+ token: TokenSymbol;
2253
+ };
2254
+ /** File size in bytes */
2255
+ fileSizeBytes: number;
2256
+ }
2257
+ /** Result returned from dStorage.store() */
2258
+ interface StoreResult {
2259
+ /**
2260
+ * The primary on-chain reference ID.
2261
+ * Undefined when no chain adapter is configured (storage-only mode).
2262
+ */
2263
+ chainRefId?: string;
2264
+ /** The storage network content ID */
2265
+ storageId: string;
2266
+ /** Storage provider used */
2267
+ storageProvider: StorageProviderName;
2268
+ /** Chain provider used. Undefined when no chain adapter is configured. */
2269
+ chainProvider?: ChainProviderName;
2270
+ /** Timestamp */
2271
+ uploadedAt: number;
2272
+ /**
2273
+ * Encryption algorithm used for the stored data and on-chain storageId.
2274
+ * "xchacha20poly1305-v1" for private (encrypted) stores.
2275
+ * Empty string ("") for public (unencrypted) stores.
2276
+ */
2277
+ encryptionScheme: string;
2278
+ /**
2279
+ * Decryption scheme for the stored content.
2280
+ * Present only for private stores in storage-only mode (no chainAdapter).
2281
+ * In chain mode the scheme is recoverable from the on-chain key envelope instead.
2282
+ * Pass this back to retrieveByStorageId() to decrypt locally.
2283
+ */
2284
+ cryptoScheme?: CryptoScheme;
2285
+ /** Estimated cost of the store operation */
2286
+ costEstimate: CostEstimate;
2287
+ }
2288
+ /** Options for dStorage.listReferences() */
2289
+ interface ListReferencesOptions {
2290
+ /** When provided, only references whose refId appears in this array are returned. */
2291
+ refIds?: string[];
2292
+ }
2293
+ /** Options for dStorage.registerReference() */
2294
+ interface RegisterReferenceOptions {
2295
+ /** The pre-existing storage network ID to register. Omit for metadata-only references. */
2296
+ storageId?: string;
2297
+ /**
2298
+ * Storage provider name recorded in the chain reference.
2299
+ * Defaults to the configured `storageAdapter.name`.
2300
+ */
2301
+ storageProvider?: StorageProviderName;
2302
+ /**
2303
+ * Optional caller-supplied reference ID, forwarded to the chain adapter as
2304
+ * {@link ChainReference.refId}. Adapters that control their own ID generation
2305
+ * (e.g. mock, HTTP gateway) use this as the stored and returned identifier.
2306
+ * Adapters where the on-chain protocol determines the ID (e.g. Midnight)
2307
+ * ignore this field — the chain-assigned ID is returned instead.
2308
+ */
2309
+ refId?: string;
2310
+ /**
2311
+ * Encrypted key/value metadata stored on-chain alongside the key envelope.
2312
+ * Encrypted with the content DEK — only holders of a valid KEK can read it.
2313
+ * Returned in `RetrieveResult.metadata` after decryption via retrieveByRefId().
2314
+ */
2315
+ metadata?: Record<string, string>;
2316
+ /**
2317
+ * Recovery: the `keyEnvelope` from a `StorePartialError` (or from the
2318
+ * `"stored"` phase of `onProgress`). When provided, the DEK is unwrapped
2319
+ * from this envelope and used to encrypt the storageId and derive the
2320
+ * ownerSecret — producing a reference identical to what `store()` would have
2321
+ * written, without requiring a re-upload.
2322
+ */
2323
+ keyEnvelope?: string;
2324
+ /**
2325
+ * BLAKE3 hash of the ciphertext bytes at `storageId`, hex-encoded (64 chars).
2326
+ * When passed from `StorePartialError.recovery.contentHash`, this ensures the
2327
+ * recovered reference carries the same on-chain hash as a normal `store()` write.
2328
+ */
2329
+ contentHash?: string;
2330
+ }
2331
+ /** Result returned from dStorage.registerReference() */
2332
+ interface RegisterReferenceResult {
2333
+ /** The on-chain reference ID — use with retrieveByRefId(). */
2334
+ chainRefId: string;
2335
+ }
2336
+ /** Result returned from dStorage.update() */
2337
+ interface UpdateResult {
2338
+ /** Same refId as the input — updated in place. */
2339
+ chainRefId: string;
2340
+ /** StorageId of the newly stored content. */
2341
+ storageId: string;
2342
+ }
2343
+ /** Result returned from dStorage.retrieveByRefId() / retrieveByStorageId() */
2344
+ interface RetrieveResult {
2345
+ /** The raw decrypted bytes */
2346
+ bytes: Uint8Array;
2347
+ /** Decrypted on-chain metadata (empty when none was provided at upload time or when retrieved without a chain reference) */
2348
+ metadata: Record<string, string>;
2349
+ /** Unencrypted tags attached to the storage-layer upload (e.g. Arweave tx tags) */
2350
+ tags: Record<string, string>;
2351
+ }
2352
+ /** AAD for single-shot payload encryption (non-chunked user content). */
2353
+ declare const PAYLOAD_AAD: Uint8Array;
2354
+ /**
2355
+ * AAD for chunked manifest encryption.
2356
+ * Using a distinct label from PAYLOAD_AAD means a ciphertext produced for a
2357
+ * manifest cannot decrypt successfully under PAYLOAD_AAD and vice versa —
2358
+ * manifest detection is cryptographic, not based on JSON shape inspection.
2359
+ */
2360
+ declare const MANIFEST_AAD: Uint8Array;
2361
+ /** AAD for encrypted on-chain metadata (stored in ChainReference.encryptedMetadata). */
2362
+ declare const METADATA_AAD: Uint8Array;
2363
+ /**
2364
+ * HKDF salt for ownerSecret derivation in metadata-only references (no storageId).
2365
+ * Using a fixed non-empty sentinel avoids RFC 5869's empty-salt substitution
2366
+ * (which silently substitutes zeros(32)) and creates a clear domain boundary
2367
+ * from normal-upload ownerSecrets whose salt is the plaintext storageId.
2368
+ */
2369
+ declare const METADATA_ONLY_OWNER_SECRET_SALT: Uint8Array;
2370
+ /**
2371
+ * Per-chunk AAD that binds a ciphertext to its position in a chunked upload.
2372
+ * A malicious gateway swapping two chunks will produce an AEAD auth failure
2373
+ * because the stored AAD won't match the expected index.
2374
+ */
2375
+ declare const chunkAad: (index: number, total: number) => Uint8Array;
2376
+
2377
+ /**
2378
+ * @dstorage/core — metaTx/types.ts
2379
+ *
2380
+ * All public interfaces and type aliases for the MetaTx orchestrator.
2381
+ */
2382
+
2383
+ type MetaTxStepId = "estimate" | "encrypt" | "payment_storage" | "upload" | "chain_reference" | "complete";
2384
+ type MetaTxStepStatus = "pending" | "running" | "done" | "error";
2385
+ interface MetaTxStepState {
2386
+ id: MetaTxStepId;
2387
+ label: string;
2388
+ description: string;
2389
+ status: MetaTxStepStatus;
2390
+ /** Live detail message updated during the step */
2391
+ detail?: string;
2392
+ /** Duration in ms (set when done) */
2393
+ durationMs?: number;
2394
+ startedAt?: number;
2395
+ }
2396
+ interface MetaTxProgress {
2397
+ steps: MetaTxStepState[];
2398
+ currentStepId: MetaTxStepId | null;
2399
+ overallStatus: "idle" | "awaiting_confirmation" | "running" | "complete" | "error";
2400
+ /** Cost estimate — set after 'estimate' step completes */
2401
+ estimate?: CostEstimate;
2402
+ /** Final receipt — set when complete */
2403
+ receipt?: MetaTxReceipt;
2404
+ /** Error message if overallStatus is 'error' */
2405
+ error?: string;
2406
+ }
2407
+ interface MetaTxReceipt {
2408
+ dataId: string;
2409
+ storageId: string;
2410
+ /** Undefined when no chain adapter is configured (storage-only mode). */
2411
+ chainRefId?: string;
2412
+ /** Original file info */
2413
+ file: {
2414
+ name: string;
2415
+ type: string;
2416
+ sizeBytes: number;
2417
+ };
2418
+ /** Payment receipts */
2419
+ storagePayment: PaymentReceipt;
2420
+ /** Undefined when no chain adapter is configured. */
2421
+ chainPayment?: PaymentReceipt;
2422
+ /** Tokens used */
2423
+ storageToken: TokenSymbol;
2424
+ /** Undefined when no chain adapter is configured. */
2425
+ chainToken?: TokenSymbol;
2426
+ /** Contract invoked (if selected) */
2427
+ contract?: {
2428
+ address: string;
2429
+ name: string;
2430
+ };
2431
+ completedAt: number;
2432
+ /** Duration of the full meta-transaction in ms */
2433
+ totalDurationMs: number;
2434
+ }
2435
+ interface MetaTxConfig {
2436
+ /** Optional metadata to attach to the on-chain reference */
2437
+ metadata?: Record<string, string>;
2438
+ /** Selected contract address (from the contract registry) */
2439
+ contractAddress?: string;
2440
+ /** Selected contract name (for display / receipt) */
2441
+ contractName?: string;
2442
+ }
2443
+ /**
2444
+ * Crypto materials for a single upload: a fresh random DEK wrapped in a
2445
+ * key envelope, ready to encrypt payload and storageId.
2446
+ *
2447
+ * For private uploads: uploadScheme encrypts content; dek is the per-upload
2448
+ * Data Encryption Key used both to encrypt content AND to derive
2449
+ * ownerSecret = HKDF(dek, rawStorageId). Any KEK holder can re-derive the
2450
+ * ownerSecret by unwrapping the envelope DEK.
2451
+ * For public uploads: uploadScheme is null; ownerSeed is a random secret wrapped
2452
+ * under every KEK in keyEnvelope, and ownerSecret = HKDF(ownerSeed, rawStorageId).
2453
+ * Any single KEK holder can re-derive the ownerSecret by unwrapping the envelope.
2454
+ */
2455
+ interface UploadCrypto {
2456
+ /** XChaChaScheme built from a fresh random DEK. null for public uploads. */
2457
+ uploadScheme: CryptoScheme | null;
2458
+ /** JSON-encoded KeyEnvelope wrapping the DEK (private) or ownerSeed (public) under every KEK. */
2459
+ keyEnvelope: string;
2460
+ /** Encryption scheme identifier to record on-chain. "" for public uploads. */
2461
+ encryptionScheme: EncryptionScheme;
2462
+ /**
2463
+ * The raw per-upload DEK for private uploads; undefined for public uploads.
2464
+ * Used by MetaTx to derive ownerSecret = HKDF(dek, rawStorageId) after upload.
2465
+ * Not stored anywhere — must not be persisted.
2466
+ */
2467
+ dek?: Uint8Array;
2468
+ /**
2469
+ * The raw ownerSeed for public uploads; undefined for private uploads.
2470
+ * Used by MetaTx to derive ownerSecret = HKDF(ownerSeed, rawStorageId) after upload.
2471
+ * Not stored anywhere — must not be persisted.
2472
+ */
2473
+ ownerSeed?: Uint8Array;
2474
+ }
2475
+ /**
2476
+ * Minimal SDK surface required by MetaTx.
2477
+ * Implemented by DStorage — MetaTx receives the SDK instance directly
2478
+ * rather than individual adapters/keys/address to avoid redundant constructor args.
2479
+ */
2480
+ interface DStorageContext {
2481
+ readonly storageAdapter: StorageAdapter;
2482
+ readonly chainAdapter: ChainAdapter | undefined;
2483
+ /** Wallet address of the connected user, or null if using init() / facade mode. */
2484
+ readonly connectedAddress: string | null;
2485
+ /**
2486
+ * Generate a fresh random DEK, wrap it under the KEK, and return the
2487
+ * upload crypto materials needed to encrypt payload and storageId.
2488
+ * @param isPublic Pass true to skip encryption (returns null scheme + no envelope).
2489
+ */
2490
+ prepareUploadCrypto(isPublic?: boolean): Promise<UploadCrypto>;
2491
+ /** Estimate the full cost (storage + chain) for a given payload size. */
2492
+ estimateCost(sizeBytes: number): Promise<CostEstimate>;
2493
+ }
2494
+
2495
+ /**
2496
+ * @dstorage/core — metaTx/utils.ts
2497
+ *
2498
+ * Helpers used internally by MetaTx and one exported utility.
2499
+ */
2500
+
2501
+ /**
2502
+ * Return the default chain payment token for a given chain provider name.
2503
+ */
2504
+ declare function defaultChainToken(chainProvider: string): TokenSymbol;
2505
+
2506
+ /**
2507
+ * @dstorage/core — metaTx/MetaTx.ts
2508
+ *
2509
+ * The MetaTx orchestrator.
2510
+ *
2511
+ * Presents a single conceptual action to the user while internally executing:
2512
+ * [0] Estimate → compute storage + chain costs
2513
+ * [1] Encrypt → XChaCha20-Poly1305 encrypt the file client-side
2514
+ * [2] PayStorage → simulate storage payment (AR / MOCK)
2515
+ * [3] Upload → upload encrypted blob to decentralised storage
2516
+ * [4] Reference → pay chain fee + write CID + metadata reference on-chain
2517
+ * [✓] Complete → return full receipt
2518
+ *
2519
+ * Usage:
2520
+ * const metaTx = new MetaTx(dStorage);
2521
+ * metaTx.onProgress((progress) => updateUI(progress));
2522
+ * const receipt = await metaTx.execute(file);
2523
+ */
2524
+
2525
+ declare class MetaTx {
2526
+ private sdk;
2527
+ private progressCallback;
2528
+ private steps;
2529
+ private startedAt;
2530
+ constructor(sdk: DStorageContext);
2531
+ /** Register a progress listener. Called after every step state change. */
2532
+ onProgress(cb: (progress: MetaTxProgress) => void): this;
2533
+ execute(file: File, config?: MetaTxConfig): Promise<MetaTxReceipt>;
2534
+ private startStep;
2535
+ private updateStepDetail;
2536
+ private completeStep;
2537
+ private getStep;
2538
+ private emit;
2539
+ }
2540
+
2541
+ /**
2542
+ * @dstorage/core — dStorage.ts
2543
+ *
2544
+ * The main SDK class. Orchestrates:
2545
+ * 1. Encryption adapter key wrapping (@dstorage/encryption + @dstorage/crypto)
2546
+ * 2. Client-side encryption (@dstorage/crypto)
2547
+ * 3. Decentralised storage (@dstorage/storage)
2548
+ * 4. On-chain reference writing (@dstorage/chain)
2549
+ *
2550
+ * Developer API:
2551
+ * const ds = new DStorage(config);
2552
+ * await ds.init();
2553
+ * const { chainRefId, storageId } = await ds.store(new TextEncoder().encode("hello"));
2554
+ * const { bytes } = await ds.retrieveByRefId(chainRefId);
2555
+ * await ds.listReferences();
2556
+ * await ds.removeReference(chainRefId);
2557
+ */
2558
+
2559
+ declare class DStorage implements DStorageContext {
2560
+ private config;
2561
+ private wallet;
2562
+ /** Encryption adapters — each wraps/unwraps per-upload DEKs using its own algorithm. */
2563
+ private _encryptionProviders;
2564
+ private _initialized;
2565
+ private readonly logger;
2566
+ constructor(config: DStorageConfig);
2567
+ get storageAdapter(): StorageAdapter;
2568
+ get chainAdapter(): ChainAdapter | undefined;
2569
+ /**
2570
+ * Initialize the SDK:
2571
+ * 1. Initialize the chain adapter wallet (if supported), and
2572
+ * deploy a new DataRegistry contract, or connect to an existing one.
2573
+ * 2. Derive an encryption key from the chain adapter's credentials (if supported).
2574
+ *
2575
+ * Returns the address of the DataRegistry contract in use.
2576
+ * Call this instead of connect() when using MidnightChainAdapter directly.
2577
+ */
2578
+ init(): Promise<string | undefined>;
2579
+ /** Tear down active state and clear all in-memory key material. */
2580
+ destroy(): void;
2581
+ get isConnected(): boolean;
2582
+ get connectedAddress(): string | null;
2583
+ /**
2584
+ * Encrypt content client-side, store to decentralised storage,
2585
+ * and write a cryptographic reference on-chain.
2586
+ *
2587
+ * Files larger than CHUNK_SIZE (10 MB) are automatically split into chunks,
2588
+ * each encrypted and stored independently. A manifest file ties them together.
2589
+ * Only the manifest's storageId is written on-chain.
2590
+ *
2591
+ * @param bytes Uint8Array to store
2592
+ * @param options Optional StoreOptions (metadata, onProgress, isPublic, refId)
2593
+ * @returns StoreResult containing the chainRefId/storageId needed to retrieve later
2594
+ */
2595
+ store(bytes: Uint8Array, options?: StoreOptions): Promise<StoreResult>;
2596
+ /**
2597
+ * Register a pre-existing storageId as a new on-chain reference.
2598
+ *
2599
+ * Use this when data has already been uploaded to the storage network by
2600
+ * other means (e.g. a third-party tool or a separate pipeline). The content
2601
+ * is not touched — only the chain reference is created.
2602
+ *
2603
+ * A fresh DEK is generated solely to encrypt the storageId and derive the
2604
+ * ownerSecret. The resulting reference round-trips through retrieveByRefId()
2605
+ * exactly like one created by store().
2606
+ *
2607
+ * Note: chunked manifests are not handled here. For large pre-existing
2608
+ * uploads already split into chunks, register the manifest storageId.
2609
+ */
2610
+ registerReference(options?: RegisterReferenceOptions): Promise<RegisterReferenceResult>;
2611
+ /**
2612
+ * Store new content and update an existing on-chain reference in place.
2613
+ *
2614
+ * Ownership is proved by re-deriving the ownerSecret from the existing
2615
+ * reference — the same mechanism used by removeReference(). A fresh DEK is
2616
+ * generated for the new content; the previous version is not modified and remains
2617
+ * independently decryptable if the caller retained the old storageId.
2618
+ *
2619
+ * Note: chunking is not applied here. For large files use store() to get a
2620
+ * new chunked reference, then removeReference() on the old one.
2621
+ *
2622
+ * @param refId The chain reference to update (returned by a prior store/registerReference).
2623
+ * @param bytes New content to encrypt and store.
2624
+ * @param options Optional StoreOptions. isPublic is ignored.
2625
+ */
2626
+ update(refId: string, bytes: Uint8Array, options?: StoreOptions): Promise<UpdateResult>;
2627
+ /**
2628
+ * Retry only the on-chain reference write after a failed `update()` call.
2629
+ *
2630
+ * Use this when `update()` throws a `StorePartialError` — meaning the new
2631
+ * content was stored successfully but the chain write failed. Call with the
2632
+ * `refId` you passed to `update()` and the `err.recovery` from the caught
2633
+ * error (or the `recovery` emitted via `onProgress` at phase `"stored"`).
2634
+ *
2635
+ * The new content is already in storage; this method re-derives all chain
2636
+ * write parameters from the recovery envelope without re-uploading.
2637
+ */
2638
+ retryUpdate(refId: string, recovery: StoreRecovery): Promise<UpdateResult>;
2639
+ /**
2640
+ * Rotate the encryption adapters protecting an existing reference without
2641
+ * re-uploading the content.
2642
+ *
2643
+ * Useful when you want to:
2644
+ * - Change a password: configure [newPassword, mnemonic] and call rotateKeys().
2645
+ * The mnemonic unwraps the old DEK, the new envelope is wrapped under both
2646
+ * new adapters, and the old password wrapper is dropped.
2647
+ * - Add or remove adapters: any single adapter that matches a wrapper in the
2648
+ * existing key envelope can authorise the rotation. The resulting envelope
2649
+ * is wrapped under exactly the adapters currently configured on this SDK.
2650
+ *
2651
+ * The content in storage is not touched — only the on-chain key envelope is
2652
+ * updated. writtenAt is preserved to reflect the original upload time.
2653
+ */
2654
+ rotateKeys(refId: string): Promise<void>;
2655
+ /**
2656
+ * Retrieve and decrypt data by its storageId.
2657
+ * Decryption happens locally — the SDK never sends plaintext anywhere.
2658
+ *
2659
+ * Automatically detects chunked manifests and reassembles the original file.
2660
+ *
2661
+ * @param storageId The storageId returned from store()
2662
+ */
2663
+ retrieveByStorageId(storageId: string, dekScheme?: CryptoScheme, contentHash?: string): Promise<RetrieveResult>;
2664
+ /**
2665
+ * Unwrap the data DEK from a key envelope and return an XChaChaScheme built from it.
2666
+ * Throws if the KEK is not available or the envelope cannot be parsed.
2667
+ * Only valid for private uploads (envelope.wrappers must be present).
2668
+ */
2669
+ private _getDekScheme;
2670
+ /**
2671
+ * Unwrap the raw DEK bytes from a key envelope using the available KEKs.
2672
+ * The ownerSecret for the reference can be re-derived as HKDF(dek, rawStorageId).
2673
+ * Throws if no wrapper matches any available KEK.
2674
+ */
2675
+ private _unwrapDek;
2676
+ /**
2677
+ * Compute the ownerSecret for an existing on-chain reference.
2678
+ * Used by removeReference/updateReference to derive the ZK witness secret.
2679
+ *
2680
+ * Flow:
2681
+ * 1. Read the reference from chain to get keyEnvelope + storageId
2682
+ * 2. Unwrap the DEK from keyEnvelope using available KEKs
2683
+ * 3. Recover raw storageId (decrypt with DEK if private, plaintext if public)
2684
+ * 4. Return HKDF-SHA256(dek, rawStorageId) for private, or HKDF-SHA256(ownerSeed, rawStorageId) for public
2685
+ */
2686
+ private _computeOwnerSecret;
2687
+ private _decryptAndReassemble;
2688
+ /**
2689
+ * Retrieve and decrypt data using only its on-chain reference ID.
2690
+ *
2691
+ * Flow:
2692
+ * 1. Look up the reference on-chain by refId to obtain the storage network ID.
2693
+ * 2. Fetch the blob from the storage network.
2694
+ * 3. Decrypt locally if an encryption key is available.
2695
+ *
2696
+ * Requires the chain adapter to implement readReference() (part of the
2697
+ * ChainAdapter interface — shared by MidnightChainAdapter, MockChainAdapter, etc.).
2698
+ *
2699
+ * @param refId The chainRefId returned from store()
2700
+ */
2701
+ retrieveByRefId(refId: string): Promise<RetrieveResult>;
2702
+ /**
2703
+ * List references currently available from the configured chain adapter.
2704
+ */
2705
+ listReferences(options?: ListReferencesOptions): Promise<DataReferenceSummary[]>;
2706
+ /**
2707
+ * Remove a reference from the on-chain registry.
2708
+ * Only the owner of the reference can successfully call this — the chain
2709
+ * enforces ownership via ZK proof using the witness-derived ownerSecret.
2710
+ */
2711
+ removeReference(refId: string): Promise<void>;
2712
+ /**
2713
+ * Estimate the full cost (storage + chain) for a given payload size before committing.
2714
+ */
2715
+ estimateCost(sizeBytes: number): Promise<CostEstimate>;
2716
+ /**
2717
+ * Execute a full meta-transaction for a file:
2718
+ * estimate → encrypt → pay storage → upload → pay chain → write reference
2719
+ *
2720
+ * Presents the entire flow as a single action with step-by-step progress.
2721
+ *
2722
+ * @param file The File to encrypt and store
2723
+ * @param onProgress Callback fired on every step state change
2724
+ * @param config Optional token overrides and metadata
2725
+ */
2726
+ executeMetaTransaction(file: File, onProgress: (progress: MetaTxProgress) => void, config?: MetaTxConfig): Promise<MetaTxReceipt>;
2727
+ /**
2728
+ * Generate a fresh random DEK, wrap it under the KEK(s), and return the crypto
2729
+ * materials needed by MetaTx to encrypt payload and storageId.
2730
+ *
2731
+ * For private stores: the DEK is wrapped under every available KEK. The ownerSecret
2732
+ * can later be re-derived as HKDF(dek, rawStorageId) by any KEK holder.
2733
+ * For public stores: a random ownerSeed is generated and wrapped under all KEKs (same pattern).
2734
+ */
2735
+ prepareUploadCrypto(isPublic?: boolean): Promise<UploadCrypto>;
2736
+ /**
2737
+ * Upload large content by splitting into CHUNK_SIZE pieces, encrypting each
2738
+ * independently, and storing a manifest that ties them together.
2739
+ * Only the manifest's storageId is written on-chain.
2740
+ */
2741
+ private _uploadChunked;
2742
+ /**
2743
+ * Reassemble a chunked file from its manifest.
2744
+ * Fetches and decrypts each chunk sequentially to bound memory usage.
2745
+ */
2746
+ private _retrieveChunked;
2747
+ private assertConnected;
2748
+ }
2749
+
2750
+ /**
2751
+ * @dstorage/core — chunked.ts
2752
+ *
2753
+ * Defines the manifest shape and helpers for large-file (chunked) uploads.
2754
+ * SDK-level chunking splits files into CHUNK_SIZE pieces before encryption,
2755
+ * bounding peak memory usage to ~2× the chunk size regardless of file size.
2756
+ */
2757
+
2758
+ /**
2759
+ * Nominal SDK chunk size: 10 MB per piece.
2760
+ *
2761
+ * Each chunk becomes one independent Arweave transaction, so larger chunks
2762
+ * mean fewer transactions and therefore less total base-fee overhead.
2763
+ * 10 MB sits comfortably below the arweave.net gateway POST limit (~12 MB)
2764
+ * while halving transaction count compared to 5 MB.
2765
+ *
2766
+ * The Arweave adapter uses getUploader() which sends each transaction's data
2767
+ * in 256 KB network slices, so 10 MB chunks upload reliably without hitting
2768
+ * any HTTP body size limit.
2769
+ */
2770
+ declare const CHUNK_SIZE: number;
2771
+ interface ChunkEntry {
2772
+ index: number;
2773
+ storageId: string;
2774
+ /** Actual byte count in this chunk (last chunk may be smaller). */
2775
+ size: number;
2776
+ }
2777
+ interface ChunkManifest {
2778
+ v: 1;
2779
+ type: "dstorage-chunked-manifest";
2780
+ totalSize: number;
2781
+ chunkSize: number;
2782
+ chunkCount: number;
2783
+ provider: StorageProviderName;
2784
+ chunks: ChunkEntry[];
2785
+ }
2786
+ declare function isManifest(payload: unknown): payload is ChunkManifest;
2787
+
2788
+ declare const CoreErrorCode: {
2789
+ readonly METADATA_WITH_PUBLIC_UPLOAD: 10001;
2790
+ readonly UPLOAD_NO_PROVIDERS: 10002;
2791
+ readonly PUBLIC_UPLOAD_REQUIRES_SEED_PROVIDER: 10003;
2792
+ readonly CHAIN_WRITE_FAILED: 10004;
2793
+ readonly REGISTER_REF_REQUIRES_CHAIN: 10010;
2794
+ readonly REGISTER_REF_REQUIRES_ENCRYPTION: 10011;
2795
+ readonly UPDATE_UPLOAD_REQUIRES_CHAIN: 10020;
2796
+ readonly UPDATE_UPLOAD_NOT_SUPPORTED: 10021;
2797
+ readonly UPDATE_UPLOAD_REQUIRES_ENCRYPTION: 10022;
2798
+ readonly ROTATE_KEYS_REQUIRES_CHAIN: 10023;
2799
+ readonly ROTATE_KEYS_NOT_SUPPORTED: 10024;
2800
+ readonly ROTATE_KEYS_REQUIRES_ENCRYPTION: 10025;
2801
+ readonly DECRYPT_NO_PROVIDERS: 10030;
2802
+ readonly DECRYPT_ENVELOPE_EMPTY: 10031;
2803
+ readonly DECRYPT_ENVELOPE_MALFORMED: 10032;
2804
+ readonly DECRYPT_NO_WRAPPER_MATCHED: 10033;
2805
+ readonly UNWRAP_DEK_NO_PROVIDERS: 10034;
2806
+ readonly UNWRAP_DEK_ENVELOPE_EMPTY: 10035;
2807
+ readonly UNWRAP_DEK_ENVELOPE_MALFORMED: 10036;
2808
+ readonly UNWRAP_DEK_NO_WRAPPER_MATCHED: 10037;
2809
+ readonly DECRYPT_PAYLOAD_FAILED: 10038;
2810
+ readonly RETRIEVE_BY_REF_ID_REQUIRES_CHAIN: 10050;
2811
+ readonly REF_NOT_FOUND: 10051;
2812
+ readonly STORAGE_ADAPTER_MISMATCH: 10052;
2813
+ readonly RETRIEVE_BY_REF_ID_ENVELOPE_EMPTY: 10053;
2814
+ readonly CONTENT_HASH_MISMATCH: 10054;
2815
+ readonly LIST_REFS_REQUIRES_CHAIN: 10060;
2816
+ readonly LIST_REFS_NOT_SUPPORTED: 10061;
2817
+ readonly REMOVE_REF_REQUIRES_CHAIN: 10070;
2818
+ readonly REMOVE_REF_NOT_SUPPORTED: 10071;
2819
+ readonly META_TX_REQUIRES_ENCRYPTION: 10080;
2820
+ readonly PREPARE_UPLOAD_NO_PROVIDERS: 10081;
2821
+ readonly MANIFEST_INVALID_STRUCTURE: 10090;
2822
+ readonly MANIFEST_CHUNK_COUNT_MISMATCH: 10091;
2823
+ readonly MANIFEST_NOT_CONTIGUOUS: 10092;
2824
+ readonly DECRYPT_CHUNK_FAILED: 10093;
2825
+ readonly CHUNK_OVERFLOWS_TOTAL_SIZE: 10094;
2826
+ readonly REASSEMBLY_SIZE_MISMATCH: 10095;
2827
+ readonly NOT_INITIALIZED: 10100;
2828
+ readonly META_TX_UNKNOWN_STEP: 10200;
2829
+ readonly UNKNOWN_ERROR: 10999;
2830
+ };
2831
+ type CoreErrorCode = (typeof CoreErrorCode)[keyof typeof CoreErrorCode];
2832
+ /**
2833
+ * Thrown when `store()` succeeds at the storage layer but fails to write the
2834
+ * on-chain reference. The content is permanently on the storage network — use
2835
+ * `err.recovery` with `registerReference()` to retry only the chain write.
2836
+ */
2837
+ declare class StorePartialError extends DStorageError {
2838
+ readonly recovery: StoreRecovery;
2839
+ constructor(recovery: StoreRecovery);
2840
+ }
2841
+ declare function isStorePartialError(err: unknown): err is StorePartialError;
2842
+
2843
+ export { ARWEAVE_LOCAL, type AdapterWalletProvider, type ArweaveBundlerAdapterConfig, ArweaveBundlerStorageAdapter, type ArweaveLocalAdapterConfig, type ArweaveLocalBalance, ArweaveLocalError, ArweaveLocalHelper, type ArweaveLocalHelperConfig, type ArweaveLocalInfo, ArweaveLocalStorageAdapter, ArweavePaymentAdapter, ArweaveStorageAdapter, CHUNK_SIZE, type ChunkEntry, type ChunkManifest, CoreErrorCode, type CostEstimate, CryptoErrorCode, type CryptoScheme, DStorage, type DStorageConfig, type DStorageContext, DStorageError, type EncryptionAdapter, EncryptionErrorCode, type EncryptionScheme, type FromKdfParamsConfig, HttpGatewayChainAdapter, type HttpGatewayChainAdapterConfig, KDF_PRESETS, type KdfPreset, KeyDeriver, type KeyEnvelope, type KeyWrapper, KeypairEncryptionAdapter, type ListReferencesOptions, type Logger, MANIFEST_AAD, METADATA_AAD, METADATA_ONLY_OWNER_SECRET_SALT, type MLKemVariant, ManagedPaymentAdapter, MetaTx, type MetaTxConfig, type MetaTxProgress, type MetaTxReceipt, type MetaTxStepId, type MetaTxStepState, type MetaTxStepStatus, MidnightChainAdapter, type MidnightChainAdapterConfig, MidnightSimulatorChainAdapter, MnemonicEncryptionAdapter, NETWORKS, PAYLOAD_AAD, PasswordEncryptionAdapter, type PasswordEncryptionAdapterConfig, type RegisterReferenceOptions, type RegisterReferenceResult, type RetrieveResult, type StoreOptions, StorePartialError, type StoreProgress, type StoreRecovery, type StoreResult, type StoredKdfParams, type UpdateResult, type UploadCrypto, type WalletAddresses, type WalletInfo, type WrappedDekResult, type XChaChaPayload, XChaChaScheme, arlocalGateway, base64urlToBytes, buildKeyEnvelope, bytesToBase64url, chunkAad, computeBlake3, computeBlake3Hex, decryptStorageIdXChaCha, decryptXChaCha, defaultChainToken, deriveKek, deriveOwnerSecret, deriveSymmetricKeyFromSeed, deserializeXChaChaPayload, encryptStorageIdXChaCha, encryptXChaCha, findWrapper, generateDek, generatePqsPassword, hexToBytes, isDStorageError, isManifest, isStorePartialError, mlkemGenerateKeypair, mlkemGenerateKeypairFromSeed, mlkemUnwrapDek, mlkemWrapDek, parseKeyEnvelope, serializeKeyEnvelope, serializeXChaChaPayload, unwrapKey, waitForFacadeSync, wrapKey };