@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.
- package/dist/KeypairEncryptionAdapter-EOBRCIGP-5PFPNLLA.mjs +8 -0
- package/dist/{KeypairEncryptionAdapter-XUKCLRFU-AYDAZ2TZ.mjs → KeypairEncryptionAdapter-EOBRCIGP-FLPJIL26.mjs} +3 -3
- package/dist/{MnemonicEncryptionAdapter-RCHUETBP-M7NHGSHO.mjs → MnemonicEncryptionAdapter-S56YG63Q-B3F3TO3T.mjs} +3 -3
- package/dist/MnemonicEncryptionAdapter-S56YG63Q-POTD74UN.mjs +8 -0
- package/dist/{PasswordEncryptionAdapter-ECHND672-MUTHAMZY.mjs → PasswordEncryptionAdapter-B2UG7MWB-M4C3KJ4S.mjs} +3 -3
- package/dist/{PasswordEncryptionAdapter-ECHND672-3DEFO6FP.mjs → PasswordEncryptionAdapter-B2UG7MWB-QCSOIQJA.mjs} +3 -3
- package/dist/browser.d.mts +91 -8
- package/dist/browser.mjs +171 -67
- package/dist/{chunk-HDD6SUU4.mjs → chunk-42O7KEL4.mjs} +30 -11
- package/dist/{chunk-X4LEBNK6.mjs → chunk-5F3HZ2RJ.mjs} +30 -11
- package/dist/{chunk-6IAQVMSM.mjs → chunk-E73HFT6J.mjs} +5 -5
- package/dist/{chunk-UDYXMII2.mjs → chunk-EOPUNIUH.mjs} +5 -5
- package/dist/{chunk-O37NHERH.mjs → chunk-L6WCT64V.mjs} +4 -2
- package/dist/{chunk-4X5K43JF.mjs → chunk-M3F2LR3B.mjs} +3 -1
- package/dist/{chunk-JMPRZK5D.mjs → chunk-O6COTUD4.mjs} +3 -1
- package/dist/{chunk-BWLEAAFW.mjs → chunk-PCXBQRCO.mjs} +55 -2056
- package/dist/{chunk-OLGVVM5Y.mjs → chunk-QFJ2Y4XE.mjs} +5 -5
- package/dist/{chunk-Z6DUAI5B.mjs → chunk-XW4RZG2X.mjs} +5 -5
- package/dist/{contract-api-TJ7JPHZA-6FUBJ6DS.mjs → contract-api-NUY4UEKE-ZANT3ICG.mjs} +3 -3
- package/dist/{contract-api-AO4RGPLT-ENC72WCG.mjs → contract-api-P6YEDYQ6-2X6BMD64.mjs} +3 -3
- package/dist/{dist-INTAFXQ7.mjs → dist-AGNOIJI4.mjs} +3 -1
- package/dist/{dist-MOLWJ4Y7.mjs → dist-J4JUJ2J5.mjs} +3 -1
- package/dist/errors.d.mts +2 -0
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +10 -2054
- package/dist/errors.mjs +10 -2054
- package/dist/index.d.mts +108 -8
- package/dist/index.d.ts +108 -8
- package/dist/index.js +306 -2187
- package/dist/index.mjs +174 -70
- package/package.json +3 -2
- package/dist/KeypairEncryptionAdapter-XUKCLRFU-ERPYK5S4.mjs +0 -8
- 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-
|
|
3
|
+
} from "./chunk-M3F2LR3B.mjs";
|
|
4
4
|
import {
|
|
5
5
|
MnemonicEncryptionAdapter
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QFJ2Y4XE.mjs";
|
|
7
7
|
import {
|
|
8
8
|
KDF_PRESETS,
|
|
9
9
|
PasswordEncryptionAdapter,
|
|
10
10
|
generatePqsPassword
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-5F3HZ2RJ.mjs";
|
|
12
12
|
import {
|
|
13
13
|
KeypairEncryptionAdapter
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-EOPUNIUH.mjs";
|
|
15
15
|
import {
|
|
16
16
|
EncryptionErrorCode
|
|
17
|
-
} from "./chunk-
|
|
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-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
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(
|
|
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
|
-
|
|
973
|
-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
2624
|
+
const anchorHash = options?.expectedContentHash;
|
|
2625
|
+
if (!anchorHash && !storedHash) {
|
|
2588
2626
|
throw new DStorageError(
|
|
2589
2627
|
StorageErrorCode.ARWEAVE_HASH_TAG_MISSING,
|
|
2590
|
-
`[dStorage/arweave]
|
|
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 ??
|
|
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(
|
|
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
|
|
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]
|
|
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
|
-
|
|
2835
|
-
|
|
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-
|
|
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(
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
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(
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
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(
|
|
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 =
|
|
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(
|
|
3761
|
-
|
|
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 =
|
|
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(
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
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/
|
|
3864
|
-
indexerWs: "wss://indexer.preprod.midnight.network/api/
|
|
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/
|
|
3872
|
-
indexerWs: "ws://127.0.0.1:8088/api/
|
|
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-
|
|
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.
|
|
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.
|
|
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": {
|