@dstorage-tech/dstorage-sdk 0.0.6 → 0.0.8

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 (33) hide show
  1. package/dist/KeypairEncryptionAdapter-EOBRCIGP-5PFPNLLA.mjs +8 -0
  2. package/dist/{KeypairEncryptionAdapter-XUKCLRFU-AYDAZ2TZ.mjs → KeypairEncryptionAdapter-EOBRCIGP-FLPJIL26.mjs} +3 -3
  3. package/dist/{MnemonicEncryptionAdapter-RCHUETBP-M7NHGSHO.mjs → MnemonicEncryptionAdapter-S56YG63Q-B3F3TO3T.mjs} +3 -3
  4. package/dist/MnemonicEncryptionAdapter-S56YG63Q-POTD74UN.mjs +8 -0
  5. package/dist/{PasswordEncryptionAdapter-ECHND672-MUTHAMZY.mjs → PasswordEncryptionAdapter-B2UG7MWB-M4C3KJ4S.mjs} +3 -3
  6. package/dist/{PasswordEncryptionAdapter-ECHND672-3DEFO6FP.mjs → PasswordEncryptionAdapter-B2UG7MWB-QCSOIQJA.mjs} +3 -3
  7. package/dist/browser.d.mts +91 -8
  8. package/dist/browser.mjs +171 -67
  9. package/dist/{chunk-HDD6SUU4.mjs → chunk-42O7KEL4.mjs} +30 -11
  10. package/dist/{chunk-X4LEBNK6.mjs → chunk-5F3HZ2RJ.mjs} +30 -11
  11. package/dist/{chunk-6IAQVMSM.mjs → chunk-E73HFT6J.mjs} +5 -5
  12. package/dist/{chunk-UDYXMII2.mjs → chunk-EOPUNIUH.mjs} +5 -5
  13. package/dist/{chunk-O37NHERH.mjs → chunk-L6WCT64V.mjs} +4 -2
  14. package/dist/{chunk-4X5K43JF.mjs → chunk-M3F2LR3B.mjs} +3 -1
  15. package/dist/{chunk-JMPRZK5D.mjs → chunk-O6COTUD4.mjs} +3 -1
  16. package/dist/{chunk-BWLEAAFW.mjs → chunk-PCXBQRCO.mjs} +55 -2056
  17. package/dist/{chunk-OLGVVM5Y.mjs → chunk-QFJ2Y4XE.mjs} +5 -5
  18. package/dist/{chunk-Z6DUAI5B.mjs → chunk-XW4RZG2X.mjs} +5 -5
  19. package/dist/{contract-api-TJ7JPHZA-6FUBJ6DS.mjs → contract-api-NUY4UEKE-ZANT3ICG.mjs} +3 -3
  20. package/dist/{contract-api-AO4RGPLT-ENC72WCG.mjs → contract-api-P6YEDYQ6-2X6BMD64.mjs} +3 -3
  21. package/dist/{dist-INTAFXQ7.mjs → dist-AGNOIJI4.mjs} +3 -1
  22. package/dist/{dist-MOLWJ4Y7.mjs → dist-J4JUJ2J5.mjs} +3 -1
  23. package/dist/errors.d.mts +2 -0
  24. package/dist/errors.d.ts +2 -0
  25. package/dist/errors.js +10 -2054
  26. package/dist/errors.mjs +10 -2054
  27. package/dist/index.d.mts +108 -8
  28. package/dist/index.d.ts +108 -8
  29. package/dist/index.js +306 -2187
  30. package/dist/index.mjs +174 -70
  31. package/package.json +3 -2
  32. package/dist/KeypairEncryptionAdapter-XUKCLRFU-ERPYK5S4.mjs +0 -8
  33. package/dist/MnemonicEncryptionAdapter-RCHUETBP-DZPBGQG6.mjs +0 -8
package/dist/index.mjs CHANGED
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  ChainErrorCode
3
- } from "./chunk-JMPRZK5D.mjs";
3
+ } from "./chunk-M3F2LR3B.mjs";
4
4
  import {
5
5
  MnemonicEncryptionAdapter
6
- } from "./chunk-6IAQVMSM.mjs";
6
+ } from "./chunk-QFJ2Y4XE.mjs";
7
7
  import {
8
8
  KDF_PRESETS,
9
9
  PasswordEncryptionAdapter,
10
10
  generatePqsPassword
11
- } from "./chunk-X4LEBNK6.mjs";
11
+ } from "./chunk-5F3HZ2RJ.mjs";
12
12
  import {
13
13
  KeypairEncryptionAdapter
14
- } from "./chunk-UDYXMII2.mjs";
14
+ } from "./chunk-EOPUNIUH.mjs";
15
15
  import {
16
16
  EncryptionErrorCode
17
- } from "./chunk-O37NHERH.mjs";
17
+ } from "./chunk-L6WCT64V.mjs";
18
18
  import {
19
19
  CryptoErrorCode,
20
20
  DStorageError,
@@ -42,11 +42,12 @@ import {
42
42
  mlkemUnwrapDek,
43
43
  mlkemWrapDek,
44
44
  parseKeyEnvelope,
45
+ readResponseTextWithLimit,
45
46
  serializeKeyEnvelope,
46
47
  serializeXChaChaPayload,
47
48
  unwrapKey,
48
49
  wrapKey
49
- } from "./chunk-BWLEAAFW.mjs";
50
+ } from "./chunk-PCXBQRCO.mjs";
50
51
  import "./chunk-5QOKJEH3.mjs";
51
52
  import "./chunk-UJCSKKID.mjs";
52
53
 
@@ -94,6 +95,7 @@ var CoreErrorCode = {
94
95
  STORAGE_ADAPTER_MISMATCH: 10052,
95
96
  RETRIEVE_BY_REF_ID_ENVELOPE_EMPTY: 10053,
96
97
  CONTENT_HASH_MISMATCH: 10054,
98
+ METADATA_PARSE_FAILED: 10055,
97
99
  // listReferences — 10060-10069
98
100
  LIST_REFS_REQUIRES_CHAIN: 10060,
99
101
  LIST_REFS_NOT_SUPPORTED: 10061,
@@ -107,6 +109,7 @@ var CoreErrorCode = {
107
109
  DECRYPT_CHUNK_FAILED: 10093,
108
110
  CHUNK_OVERFLOWS_TOTAL_SIZE: 10094,
109
111
  REASSEMBLY_SIZE_MISMATCH: 10095,
112
+ MANIFEST_PARSE_FAILED: 10096,
110
113
  // init state — 10100-10109
111
114
  NOT_INITIALIZED: 10100,
112
115
  // generic catch-all — 10999
@@ -129,7 +132,7 @@ function isStorePartialError(err) {
129
132
  // package.json
130
133
  var package_default = {
131
134
  name: "@dstorage-tech/dstorage-sdk",
132
- version: "0.0.6",
135
+ version: "0.0.8",
133
136
  description: "Privacy-first decentralized storage SDK with pluggable adapters",
134
137
  license: "MIT",
135
138
  homepage: "https://dstorage.pro",
@@ -205,10 +208,11 @@ var package_default = {
205
208
  "@midnight-ntwrk/midnight-js-protocol": "4.1.1",
206
209
  "@midnight-ntwrk/midnight-js-types": "4.1.1",
207
210
  "@midnight-ntwrk/midnight-js-utils": "4.1.1",
208
- "@midnight-ntwrk/wallet-sdk": "1.1.0",
211
+ "@midnight-ntwrk/wallet-sdk": "1.2.0",
209
212
  "@noble/ciphers": "^2.2.0",
210
213
  "@noble/hashes": "^1.5.0",
211
214
  "@noble/post-quantum": "^0.6.1",
215
+ "@scure/bip39": "^2.0.1",
212
216
  arweave: "^1.15.7"
213
217
  },
214
218
  devDependencies: {
@@ -283,6 +287,9 @@ var DStorage = class {
283
287
  }
284
288
  /** Tear down active state and clear all in-memory key material. */
285
289
  destroy() {
290
+ for (const provider of this._encryptionProviders) {
291
+ provider.destroy?.();
292
+ }
286
293
  this.wallet = null;
287
294
  this._encryptionProviders = [];
288
295
  this._initialized = false;
@@ -382,20 +389,24 @@ var DStorage = class {
382
389
  );
383
390
  }
384
391
  const ownerSeed = generateDek();
385
- const ownerSeedWrappers = await Promise.all(
386
- this._encryptionProviders.map(async (provider) => ({
387
- wrapKeyName: provider.name,
388
- ...await provider.wrapDek(ownerSeed)
389
- }))
390
- );
391
- keyEnvelope = serializeKeyEnvelope(
392
- buildKeyEnvelope(ownerSeedWrappers)
393
- );
394
- ownerSecret = await deriveOwnerSecret(
395
- ownerSeed,
396
- new TextEncoder().encode(storageResult.id),
397
- "dstorage:owner-secret:public:v1"
398
- );
392
+ try {
393
+ const ownerSeedWrappers = await Promise.all(
394
+ this._encryptionProviders.map(async (provider) => ({
395
+ wrapKeyName: provider.name,
396
+ ...await provider.wrapDek(ownerSeed)
397
+ }))
398
+ );
399
+ keyEnvelope = serializeKeyEnvelope(
400
+ buildKeyEnvelope(ownerSeedWrappers)
401
+ );
402
+ ownerSecret = await deriveOwnerSecret(
403
+ ownerSeed,
404
+ new TextEncoder().encode(storageResult.id),
405
+ "dstorage:owner-secret:public:v1"
406
+ );
407
+ } finally {
408
+ ownerSeed.fill(0);
409
+ }
399
410
  }
400
411
  onChainStorageId = storageResult.id;
401
412
  } else {
@@ -468,6 +479,8 @@ var DStorage = class {
468
479
  };
469
480
  } catch {
470
481
  throw new StorePartialError(storeRecovery);
482
+ } finally {
483
+ dek?.fill(0);
471
484
  }
472
485
  }
473
486
  this.logger?.log(
@@ -828,7 +841,10 @@ var DStorage = class {
828
841
  async retrieveByStorageId(storageId, dekScheme, contentHash) {
829
842
  try {
830
843
  this.assertConnected();
831
- const { bytes: rawBytes, tags } = await this.config.storageAdapter.retrieve(storageId);
844
+ const { bytes: rawBytes, tags } = await this.config.storageAdapter.retrieve(
845
+ storageId,
846
+ contentHash !== void 0 ? { expectedContentHash: contentHash } : void 0
847
+ );
832
848
  if (contentHash) {
833
849
  const computed = await computeBlake3Hex(rawBytes);
834
850
  if (computed !== contentHash) {
@@ -969,9 +985,16 @@ var DStorage = class {
969
985
  } catch {
970
986
  }
971
987
  if (manifestBytes !== null) {
972
- const parsed = JSON.parse(
973
- new TextDecoder().decode(manifestBytes)
974
- );
988
+ let parsed;
989
+ try {
990
+ parsed = JSON.parse(new TextDecoder().decode(manifestBytes));
991
+ } catch (err) {
992
+ throw new DStorageError(
993
+ CoreErrorCode.MANIFEST_PARSE_FAILED,
994
+ `[dStorage] Payload authenticated as manifest but is not valid JSON: ${err}`,
995
+ { cause: err }
996
+ );
997
+ }
975
998
  if (!isManifest(parsed)) {
976
999
  throw new DStorageError(
977
1000
  CoreErrorCode.MANIFEST_INVALID_STRUCTURE,
@@ -1095,7 +1118,15 @@ var DStorage = class {
1095
1118
  base64urlToBytes(ref.encryptedMetadata),
1096
1119
  METADATA_AAD
1097
1120
  );
1098
- metadata = JSON.parse(new TextDecoder().decode(raw));
1121
+ try {
1122
+ metadata = JSON.parse(new TextDecoder().decode(raw));
1123
+ } catch (err) {
1124
+ throw new DStorageError(
1125
+ CoreErrorCode.METADATA_PARSE_FAILED,
1126
+ `[dStorage] Decrypted metadata is not valid JSON: ${err}`,
1127
+ { cause: err }
1128
+ );
1129
+ }
1099
1130
  }
1100
1131
  return { bytes: contentBytes, tags: contentTags, metadata };
1101
1132
  } catch (err) {
@@ -1440,12 +1471,17 @@ var DStorage = class {
1440
1471
  };
1441
1472
  } catch {
1442
1473
  throw new StorePartialError(storeRecovery);
1474
+ } finally {
1475
+ chunkDek?.fill(0);
1476
+ ownerSeed?.fill(0);
1443
1477
  }
1444
1478
  }
1445
1479
  this.logger?.log(
1446
1480
  "dStorage",
1447
1481
  `Chunked upload complete (storage-only) \u2192 ${totalChunks} chunks + manifest, storageId: ${manifestResult.id}`
1448
1482
  );
1483
+ chunkDek?.fill(0);
1484
+ ownerSeed?.fill(0);
1449
1485
  return {
1450
1486
  storageId: manifestResult.id,
1451
1487
  storageProvider: manifestResult.provider,
@@ -1534,7 +1570,7 @@ var DStorage = class {
1534
1570
  }
1535
1571
  };
1536
1572
 
1537
- // ../storage/dist/chunk-URI7FNOW.mjs
1573
+ // ../storage/dist/chunk-3LIX4E3N.mjs
1538
1574
  var StorageErrorCode = {
1539
1575
  // adapters/mock.ts (15000–15049)
1540
1576
  MOCK_AUTH_TOKEN_REQUIRED: 15001,
@@ -1573,7 +1609,8 @@ var StorageErrorCode = {
1573
1609
  ARWEAVE_BUNDLER_INVALID_AUTH_TOKEN_FORMAT: 15411,
1574
1610
  ARWEAVE_BUNDLER_INVALID_AUTH_TOKEN_KEY: 15412,
1575
1611
  ARWEAVE_BUNDLER_NO_TX_ID_RETURNED: 15413,
1576
- ARWEAVE_BUNDLER_UPLOAD_FAILED: 15414
1612
+ ARWEAVE_BUNDLER_UPLOAD_FAILED: 15414,
1613
+ ARWEAVE_BUNDLER_METADATA_TOO_LARGE: 15415
1577
1614
  };
1578
1615
 
1579
1616
  // ../payment/dist/chunk-IVL4WQ5Y.mjs
@@ -2242,7 +2279,7 @@ var ManagedPaymentAdapter = class _ManagedPaymentAdapter extends ArweavePaymentA
2242
2279
  }
2243
2280
  };
2244
2281
 
2245
- // ../storage/dist/chunk-BIT7XMIA.mjs
2282
+ // ../storage/dist/chunk-AE5AGNHP.mjs
2246
2283
  var memoryStore = /* @__PURE__ */ new Map();
2247
2284
  function bytesToBase64url2(bytes) {
2248
2285
  let binary = "";
@@ -2520,7 +2557,7 @@ var ArweaveStorageAdapter = class {
2520
2557
  };
2521
2558
  }
2522
2559
  // ── retrieve ───────────────────────────────────────────────────────────────────
2523
- async retrieve(id) {
2560
+ async retrieve(id, options) {
2524
2561
  if (!/^[A-Za-z0-9_-]{43}$/.test(id)) {
2525
2562
  throw new DStorageError(
2526
2563
  StorageErrorCode.ARWEAVE_INVALID_TX_ID,
@@ -2584,14 +2621,15 @@ Check status at: https://viewblock.io/arweave/tx/${id}`
2584
2621
  );
2585
2622
  }
2586
2623
  if (!this.skipIntegrityCheck) {
2587
- if (!storedHash) {
2624
+ const anchorHash = options?.expectedContentHash;
2625
+ if (!anchorHash && !storedHash) {
2588
2626
  throw new DStorageError(
2589
2627
  StorageErrorCode.ARWEAVE_HASH_TAG_MISSING,
2590
- `[dStorage/arweave] ${CONTENT_HASH_TAG2} tag not found for txId: ${id}.
2628
+ `[dStorage/arweave] Cannot verify content integrity for txId: ${id} \u2014 no expectedContentHash anchor was provided and the ${CONTENT_HASH_TAG2} tag was not found.
2591
2629
  Set skipIntegrityCheck: true to bypass integrity checking for fully trusted gateways.`
2592
2630
  );
2593
2631
  }
2594
- await assertContentHash(id, bytes, storedHash, "arweave");
2632
+ await assertContentHash(id, bytes, anchorHash ?? storedHash, "arweave");
2595
2633
  }
2596
2634
  this.logger?.log("dStorage/arweave", `Retrieved txId: ${id}`);
2597
2635
  return { bytes, tags };
@@ -2715,14 +2753,19 @@ async function getTurboFactory() {
2715
2753
  return TurboFactory;
2716
2754
  }
2717
2755
  var ARWEAVE_GATEWAY_URL = "https://turbo-gateway.com";
2756
+ var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
2757
+ var DEFAULT_MAX_METADATA_RESPONSE_BYTES = 1024 * 1024;
2758
+ var DEFAULT_MAX_RETRIEVE_SIZE_BYTES = 256 * 1024 * 1024;
2718
2759
  var ArweaveBundlerStorageAdapter = class _ArweaveBundlerStorageAdapter {
2719
2760
  constructor(config = {}) {
2720
2761
  this.name = "arweave_bundler";
2721
2762
  this.providerName = "Arweave (Bundler)";
2722
2763
  this.signingServerUrl = config.signingServerUrl ? config.signingServerUrl.replace(/\/$/, "") : null;
2723
2764
  this.gateway = config.gateway ?? ARWEAVE_GATEWAY_URL;
2724
- this.maxRetrieveSizeBytes = config.maxRetrieveSizeBytes ?? 256 * 1024 * 1024;
2765
+ this.maxRetrieveSizeBytes = config.maxRetrieveSizeBytes ?? DEFAULT_MAX_RETRIEVE_SIZE_BYTES;
2725
2766
  this.skipIntegrityCheck = config.skipIntegrityCheck ?? false;
2767
+ this.requestTimeoutMs = config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
2768
+ this.maxMetadataResponseBytes = config.maxMetadataResponseBytes ?? DEFAULT_MAX_METADATA_RESPONSE_BYTES;
2726
2769
  this.logger = config.logger;
2727
2770
  if (config.signingServerUrl) {
2728
2771
  if (!config.authToken?.trim()) {
@@ -2773,8 +2816,13 @@ var ArweaveBundlerStorageAdapter = class _ArweaveBundlerStorageAdapter {
2773
2816
  );
2774
2817
  return { id: txId, provider: this.name, url, uploadedAt: Date.now() };
2775
2818
  }
2819
+ /** Adds an AbortSignal.timeout() to a fetch init object (when requestTimeoutMs > 0). */
2820
+ _withTimeout(init = {}) {
2821
+ const signal = this.requestTimeoutMs > 0 ? AbortSignal.timeout(this.requestTimeoutMs) : void 0;
2822
+ return { ...init, ...signal !== void 0 ? { signal } : {} };
2823
+ }
2776
2824
  // ── retrieve ───────────────────────────────────────────────────────────────────
2777
- async retrieve(id) {
2825
+ async retrieve(id, options) {
2778
2826
  if (!/^[A-Za-z0-9_-]{43}$/.test(id)) {
2779
2827
  throw new DStorageError(
2780
2828
  StorageErrorCode.ARWEAVE_BUNDLER_INVALID_TX_ID,
@@ -2784,29 +2832,37 @@ var ArweaveBundlerStorageAdapter = class _ArweaveBundlerStorageAdapter {
2784
2832
  let storedHash;
2785
2833
  const tags = {};
2786
2834
  if (!this.skipIntegrityCheck) {
2787
- const metaResp = await fetch(`${this.gateway}/tx/${id}`);
2835
+ const metaResp = await fetch(
2836
+ `${this.gateway}/tx/${id}`,
2837
+ this._withTimeout()
2838
+ );
2788
2839
  if (!metaResp.ok) {
2789
2840
  throw new DStorageError(
2790
2841
  StorageErrorCode.ARWEAVE_BUNDLER_TX_METADATA_FAILED,
2791
2842
  `[dStorage/arweave-bundler] Could not fetch transaction metadata for txId: ${id} \u2014 content hash cannot be verified. Set skipIntegrityCheck: true to bypass integrity checking for fully trusted gateways.`
2792
2843
  );
2793
2844
  }
2794
- const tx = await metaResp.json();
2845
+ const metaText = await readResponseTextWithLimit(metaResp, {
2846
+ maxBytes: this.maxMetadataResponseBytes,
2847
+ code: StorageErrorCode.ARWEAVE_BUNDLER_METADATA_TOO_LARGE,
2848
+ component: `[dStorage/arweave-bundler] retrieve(${id}) metadata`
2849
+ });
2850
+ const tx = JSON.parse(metaText);
2795
2851
  for (const tag of tx.tags ?? []) {
2796
2852
  const name = new TextDecoder().decode(_base64urlToBytes(tag.name));
2797
2853
  const value = new TextDecoder().decode(_base64urlToBytes(tag.value));
2798
2854
  tags[name] = value;
2799
2855
  if (name === CONTENT_HASH_TAG2) storedHash = value;
2800
2856
  }
2801
- if (!storedHash) {
2857
+ if (!options?.expectedContentHash && !storedHash) {
2802
2858
  throw new DStorageError(
2803
2859
  StorageErrorCode.ARWEAVE_BUNDLER_HASH_TAG_MISSING,
2804
- `[dStorage/arweave-bundler] ${CONTENT_HASH_TAG2} tag not found for txId: ${id}.
2860
+ `[dStorage/arweave-bundler] Cannot verify content integrity for txId: ${id} \u2014 no expectedContentHash anchor was provided and the ${CONTENT_HASH_TAG2} tag was not found.
2805
2861
  Set skipIntegrityCheck: true to bypass integrity checking for fully trusted gateways.`
2806
2862
  );
2807
2863
  }
2808
2864
  }
2809
- const resp = await fetch(`${this.gateway}/${id}`);
2865
+ const resp = await fetch(`${this.gateway}/${id}`, this._withTimeout());
2810
2866
  if (!resp.ok) {
2811
2867
  throw new DStorageError(
2812
2868
  StorageErrorCode.ARWEAVE_BUNDLER_RETRIEVE_HTTP_ERROR,
@@ -2831,8 +2887,14 @@ Check: https://viewblock.io/arweave/tx/${id}`
2831
2887
  `[dStorage/arweave-bundler] Downloaded ${bytes.byteLength} bytes for txId: ${id}, which exceeds the configured limit of ${this.maxRetrieveSizeBytes} bytes.`
2832
2888
  );
2833
2889
  }
2834
- if (!this.skipIntegrityCheck && storedHash) {
2835
- await assertContentHash(id, bytes, storedHash, "arweave-bundler");
2890
+ const anchorHash = options?.expectedContentHash;
2891
+ if (!this.skipIntegrityCheck && (anchorHash || storedHash)) {
2892
+ await assertContentHash(
2893
+ id,
2894
+ bytes,
2895
+ anchorHash ?? storedHash,
2896
+ "arweave-bundler"
2897
+ );
2836
2898
  }
2837
2899
  this.logger?.log("dStorage/arweave-bundler", `Retrieved txId: ${id}`);
2838
2900
  return { bytes, tags };
@@ -3279,7 +3341,7 @@ var ArweaveLocalError = class extends Error {
3279
3341
  }
3280
3342
  };
3281
3343
 
3282
- // ../chain/dist/chunk-BK2EFMQI.mjs
3344
+ // ../chain/dist/chunk-5EPK5N7O.mjs
3283
3345
  var refs = /* @__PURE__ */ new Map();
3284
3346
  var commitments = /* @__PURE__ */ new Map();
3285
3347
  async function sha256(data) {
@@ -3644,6 +3706,8 @@ var MidnightSimulatorChainAdapter = class {
3644
3706
  }
3645
3707
  };
3646
3708
  var COMPONENT = "[dStorage/http-gateway-chain]";
3709
+ var DEFAULT_REQUEST_TIMEOUT_MS2 = 3e4;
3710
+ var DEFAULT_MAX_RESPONSE_BYTES = 10 * 1024 * 1024;
3647
3711
  function generateRefId2() {
3648
3712
  const id = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : `${Date.now()}-${Math.random().toString(36).slice(2)}`;
3649
3713
  return `ref_${id}`;
@@ -3659,6 +3723,13 @@ var HttpGatewayChainAdapter = class {
3659
3723
  this.readUrl = `${config.baseUrl}${config.readPath}`;
3660
3724
  this.listUrl = `${config.baseUrl}${config.listPath}`;
3661
3725
  this.deleteUrl = `${config.baseUrl}${config.deletePath}`;
3726
+ this.requestTimeoutMs = config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS2;
3727
+ this.maxResponseBytes = config.maxResponseBytes ?? DEFAULT_MAX_RESPONSE_BYTES;
3728
+ }
3729
+ /** Adds an AbortSignal.timeout() to a fetch init object (when requestTimeoutMs > 0). */
3730
+ _withTimeout(init) {
3731
+ const signal = this.requestTimeoutMs > 0 ? AbortSignal.timeout(this.requestTimeoutMs) : void 0;
3732
+ return { ...init, ...signal !== void 0 ? { signal } : {} };
3662
3733
  }
3663
3734
  async writeReference(ref) {
3664
3735
  const { ownerSecret: _omit, ...payload } = ref;
@@ -3666,11 +3737,17 @@ var HttpGatewayChainAdapter = class {
3666
3737
  const url = `${this.writeUrl}/${encodeURIComponent(refId)}`;
3667
3738
  let res;
3668
3739
  try {
3669
- res = await this.fetchFn(url, {
3670
- method: "POST",
3671
- headers: { "Content-Type": "application/json", ...this.extraHeaders },
3672
- body: JSON.stringify(payload)
3673
- });
3740
+ res = await this.fetchFn(
3741
+ url,
3742
+ this._withTimeout({
3743
+ method: "POST",
3744
+ headers: {
3745
+ "Content-Type": "application/json",
3746
+ ...this.extraHeaders
3747
+ },
3748
+ body: JSON.stringify(payload)
3749
+ })
3750
+ );
3674
3751
  } catch (err) {
3675
3752
  throw new DStorageError(
3676
3753
  ChainErrorCode.GATEWAY_WRITE_FAILED,
@@ -3696,11 +3773,17 @@ var HttpGatewayChainAdapter = class {
3696
3773
  const url = `${this.writeUrl}/${encodeURIComponent(refId)}`;
3697
3774
  let res;
3698
3775
  try {
3699
- res = await this.fetchFn(url, {
3700
- method: "POST",
3701
- headers: { "Content-Type": "application/json", ...this.extraHeaders },
3702
- body: JSON.stringify(update)
3703
- });
3776
+ res = await this.fetchFn(
3777
+ url,
3778
+ this._withTimeout({
3779
+ method: "POST",
3780
+ headers: {
3781
+ "Content-Type": "application/json",
3782
+ ...this.extraHeaders
3783
+ },
3784
+ body: JSON.stringify(update)
3785
+ })
3786
+ );
3704
3787
  } catch (err) {
3705
3788
  throw new DStorageError(
3706
3789
  ChainErrorCode.GATEWAY_UPDATE_FAILED,
@@ -3721,7 +3804,10 @@ var HttpGatewayChainAdapter = class {
3721
3804
  const url = `${this.readUrl}/${encodeURIComponent(refId)}`;
3722
3805
  let res;
3723
3806
  try {
3724
- res = await this.fetchFn(url, { headers: { ...this.extraHeaders } });
3807
+ res = await this.fetchFn(
3808
+ url,
3809
+ this._withTimeout({ headers: { ...this.extraHeaders } })
3810
+ );
3725
3811
  } catch (err) {
3726
3812
  throw new DStorageError(
3727
3813
  ChainErrorCode.GATEWAY_READ_FAILED,
@@ -3736,9 +3822,14 @@ var HttpGatewayChainAdapter = class {
3736
3822
  { httpStatus: res.status }
3737
3823
  );
3738
3824
  }
3825
+ const text = await readResponseTextWithLimit(res, {
3826
+ maxBytes: this.maxResponseBytes,
3827
+ code: ChainErrorCode.GATEWAY_READ_RESPONSE_TOO_LARGE,
3828
+ component: `${COMPONENT} readReference`
3829
+ });
3739
3830
  let data;
3740
3831
  try {
3741
- data = await res.json();
3832
+ data = JSON.parse(text);
3742
3833
  } catch {
3743
3834
  throw new DStorageError(
3744
3835
  ChainErrorCode.GATEWAY_READ_INVALID_JSON,
@@ -3757,9 +3848,10 @@ var HttpGatewayChainAdapter = class {
3757
3848
  async listReferences() {
3758
3849
  let res;
3759
3850
  try {
3760
- res = await this.fetchFn(this.listUrl, {
3761
- headers: { ...this.extraHeaders }
3762
- });
3851
+ res = await this.fetchFn(
3852
+ this.listUrl,
3853
+ this._withTimeout({ headers: { ...this.extraHeaders } })
3854
+ );
3763
3855
  } catch (err) {
3764
3856
  throw new DStorageError(
3765
3857
  ChainErrorCode.GATEWAY_LIST_FAILED,
@@ -3774,9 +3866,14 @@ var HttpGatewayChainAdapter = class {
3774
3866
  { httpStatus: res.status }
3775
3867
  );
3776
3868
  }
3869
+ const text = await readResponseTextWithLimit(res, {
3870
+ maxBytes: this.maxResponseBytes,
3871
+ code: ChainErrorCode.GATEWAY_LIST_RESPONSE_TOO_LARGE,
3872
+ component: `${COMPONENT} listReferences`
3873
+ });
3777
3874
  let data;
3778
3875
  try {
3779
- data = await res.json();
3876
+ data = JSON.parse(text);
3780
3877
  } catch {
3781
3878
  throw new DStorageError(
3782
3879
  ChainErrorCode.GATEWAY_LIST_INVALID_JSON,
@@ -3809,11 +3906,17 @@ var HttpGatewayChainAdapter = class {
3809
3906
  const body = ownerSecret !== void 0 ? { ownerSecret: bytesToBase64url(ownerSecret) } : {};
3810
3907
  let res;
3811
3908
  try {
3812
- res = await this.fetchFn(url, {
3813
- method: "DELETE",
3814
- headers: { "Content-Type": "application/json", ...this.extraHeaders },
3815
- body: JSON.stringify(body)
3816
- });
3909
+ res = await this.fetchFn(
3910
+ url,
3911
+ this._withTimeout({
3912
+ method: "DELETE",
3913
+ headers: {
3914
+ "Content-Type": "application/json",
3915
+ ...this.extraHeaders
3916
+ },
3917
+ body: JSON.stringify(body)
3918
+ })
3919
+ );
3817
3920
  } catch (err) {
3818
3921
  throw new DStorageError(
3819
3922
  ChainErrorCode.GATEWAY_REMOVE_FAILED,
@@ -3860,16 +3963,16 @@ var NETWORKS = {
3860
3963
  networkId: "preprod",
3861
3964
  nodeHttp: "https://rpc.preprod.midnight.network",
3862
3965
  nodeWs: "wss://rpc.preprod.midnight.network",
3863
- indexerHttp: "https://indexer.preprod.midnight.network/api/v3/graphql",
3864
- indexerWs: "wss://indexer.preprod.midnight.network/api/v3/graphql/ws",
3966
+ indexerHttp: "https://indexer.preprod.midnight.network/api/v4/graphql",
3967
+ indexerWs: "wss://indexer.preprod.midnight.network/api/v4/graphql/ws",
3865
3968
  proofServer: "http://127.0.0.1:6300"
3866
3969
  },
3867
3970
  undeployed: {
3868
3971
  networkId: "undeployed",
3869
3972
  nodeHttp: "http://127.0.0.1:9944",
3870
3973
  nodeWs: "ws://127.0.0.1:9944",
3871
- indexerHttp: "http://127.0.0.1:8088/api/v3/graphql",
3872
- indexerWs: "ws://127.0.0.1:8088/api/v3/graphql/ws",
3974
+ indexerHttp: "http://127.0.0.1:8088/api/v4/graphql",
3975
+ indexerWs: "ws://127.0.0.1:8088/api/v4/graphql/ws",
3873
3976
  proofServer: "http://127.0.0.1:6300"
3874
3977
  }
3875
3978
  };
@@ -4279,7 +4382,7 @@ var MidnightChainAdapter = class _MidnightChainAdapter {
4279
4382
  } else {
4280
4383
  providers = await this._buildWalletProviderMode();
4281
4384
  }
4282
- const { DataRegistryAPI } = await import("./contract-api-TJ7JPHZA-6FUBJ6DS.mjs");
4385
+ const { DataRegistryAPI } = await import("./contract-api-NUY4UEKE-ZANT3ICG.mjs");
4283
4386
  if (!this._contractAddress) {
4284
4387
  this.logger?.log("dStorage/midnight", "Deploying DataRegistry contract\u2026");
4285
4388
  this._api = await DataRegistryAPI.deploy(providers, this.logger);
@@ -4817,6 +4920,7 @@ export {
4817
4920
  mlkemUnwrapDek,
4818
4921
  mlkemWrapDek,
4819
4922
  parseKeyEnvelope,
4923
+ readResponseTextWithLimit,
4820
4924
  serializeKeyEnvelope,
4821
4925
  serializeXChaChaPayload,
4822
4926
  unwrapKey,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dstorage-tech/dstorage-sdk",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Privacy-first decentralized storage SDK with pluggable adapters",
5
5
  "license": "MIT",
6
6
  "homepage": "https://dstorage.pro",
@@ -76,10 +76,11 @@
76
76
  "@midnight-ntwrk/midnight-js-protocol": "4.1.1",
77
77
  "@midnight-ntwrk/midnight-js-types": "4.1.1",
78
78
  "@midnight-ntwrk/midnight-js-utils": "4.1.1",
79
- "@midnight-ntwrk/wallet-sdk": "1.1.0",
79
+ "@midnight-ntwrk/wallet-sdk": "1.2.0",
80
80
  "@noble/ciphers": "^2.2.0",
81
81
  "@noble/hashes": "^1.5.0",
82
82
  "@noble/post-quantum": "^0.6.1",
83
+ "@scure/bip39": "^2.0.1",
83
84
  "arweave": "^1.15.7"
84
85
  },
85
86
  "devDependencies": {
@@ -1,8 +0,0 @@
1
- import {
2
- KeypairEncryptionAdapter
3
- } from "./chunk-Z6DUAI5B.mjs";
4
- import "./chunk-O37NHERH.mjs";
5
- import "./chunk-BWLEAAFW.mjs";
6
- export {
7
- KeypairEncryptionAdapter
8
- };
@@ -1,8 +0,0 @@
1
- import {
2
- MnemonicEncryptionAdapter
3
- } from "./chunk-OLGVVM5Y.mjs";
4
- import "./chunk-O37NHERH.mjs";
5
- import "./chunk-BWLEAAFW.mjs";
6
- export {
7
- MnemonicEncryptionAdapter
8
- };