@dignetwork/dig-sdk 0.1.0 → 0.2.1
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/README.md +159 -11
- package/dist/adapters.cjs +56 -15
- package/dist/adapters.cjs.map +1 -1
- package/dist/adapters.d.cts +2 -2
- package/dist/adapters.d.ts +2 -2
- package/dist/adapters.js +56 -15
- package/dist/adapters.js.map +1 -1
- package/dist/{dev-shim-Bgw8X2E9.d.cts → dev-shim-DfKRA1ok.d.cts} +13 -3
- package/dist/{dev-shim-Bgw8X2E9.d.ts → dev-shim-DfKRA1ok.d.ts} +13 -3
- package/dist/{dig-client-entry-BIzuZ7Rs.d.cts → dig-client-entry-Bc95rd_t.d.cts} +120 -7
- package/dist/{dig-client-entry-BIzuZ7Rs.d.ts → dig-client-entry-Bc95rd_t.d.ts} +120 -7
- package/dist/dig-client.cjs +163 -43
- package/dist/dig-client.cjs.map +1 -1
- package/dist/dig-client.d.cts +1 -1
- package/dist/dig-client.d.ts +1 -1
- package/dist/dig-client.js +163 -43
- package/dist/dig-client.js.map +1 -1
- package/dist/index.cjs +495 -56
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +313 -3
- package/dist/index.d.ts +313 -3
- package/dist/index.js +489 -57
- package/dist/index.js.map +1 -1
- package/dist/next.cjs +58 -15
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +1 -1
- package/dist/next.d.ts +1 -1
- package/dist/next.js +58 -15
- package/dist/next.js.map +1 -1
- package/dist/vite.cjs +58 -15
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +58 -15
- package/dist/vite.js.map +1 -1
- package/package.json +5 -6
- package/vendor/PROVENANCE.md +0 -102
- package/vendor/dig_client.d.ts +0 -150
- package/vendor/dig_client.mjs +0 -805
- package/vendor/dig_client_bg.wasm +0 -0
|
@@ -105,6 +105,77 @@ interface ReadResult {
|
|
|
105
105
|
/** Did the bytes decrypt+authenticate under this URN's derived key? */
|
|
106
106
|
decrypted: boolean;
|
|
107
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* The on-chain CHIP-0007 metadata of a collection item, as returned by the dig RPC. Hashes are
|
|
110
|
+
* lowercase-hex 32-byte digests (or `null` when absent); URIs are the dig:// / https locations the
|
|
111
|
+
* bytes are served from. Mirrors the on-chain `NftMetadata` (the dig RPC decodes it from the NFT's
|
|
112
|
+
* metadata pointer). All fields optional/nullable so a non-standard metadata updater still parses.
|
|
113
|
+
*/
|
|
114
|
+
interface CollectionItemMetadata {
|
|
115
|
+
/** 1-based edition number within the series. */
|
|
116
|
+
edition_number?: number;
|
|
117
|
+
/** Total editions in the series. */
|
|
118
|
+
edition_total?: number;
|
|
119
|
+
/** Primary media URIs (dig:// first, https fallback by convention). */
|
|
120
|
+
data_uris?: string[];
|
|
121
|
+
/** `sha256(media_bytes)`, lowercase hex, or null. */
|
|
122
|
+
data_hash?: string | null;
|
|
123
|
+
/** CHIP-0007 metadata-JSON URIs. */
|
|
124
|
+
metadata_uris?: string[];
|
|
125
|
+
/** `sha256(metadata_json_bytes)`, lowercase hex, or null. */
|
|
126
|
+
metadata_hash?: string | null;
|
|
127
|
+
/** License document URIs. */
|
|
128
|
+
license_uris?: string[];
|
|
129
|
+
/** `sha256(license_bytes)`, lowercase hex, or null. */
|
|
130
|
+
license_hash?: string | null;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* One NFT in a collection, resolved to its CURRENT on-chain state by `DigClient.listCollectionItems`
|
|
134
|
+
* (owner-independent: the reported owner is live, walked forward through the singleton lineage, not
|
|
135
|
+
* the mint-time owner). All hashes/ids are lowercase hex.
|
|
136
|
+
*/
|
|
137
|
+
interface CollectionItem {
|
|
138
|
+
/** The NFT's stable launcher id (its `nft1…` id encodes this), lowercase hex. */
|
|
139
|
+
launcher_id: string;
|
|
140
|
+
/** The current (unspent) coin id of the NFT singleton, lowercase hex. */
|
|
141
|
+
coin_id: string;
|
|
142
|
+
/** The current assigned owner DID launcher id (lowercase hex), or null when unattributed. */
|
|
143
|
+
owner_did: string | null;
|
|
144
|
+
/** The puzzle hash royalties are paid to in offer trades, lowercase hex. */
|
|
145
|
+
royalty_puzzle_hash: string;
|
|
146
|
+
/** Royalty as hundredths of a percent (300 = 3%). */
|
|
147
|
+
royalty_basis_points: number;
|
|
148
|
+
/** The CURRENT owner (p2) puzzle hash — where the NFT lives now, lowercase hex. */
|
|
149
|
+
owner_puzzle_hash: string;
|
|
150
|
+
/** The decoded on-chain CHIP-0007 metadata, or null when it does not decode. */
|
|
151
|
+
metadata: CollectionItemMetadata | null;
|
|
152
|
+
}
|
|
153
|
+
/** A deterministic, paginated page of collection items, from `DigClient.listCollectionItems`. */
|
|
154
|
+
interface CollectionItemsPage {
|
|
155
|
+
/** This page's items, in the requested (input launcher-id) order. */
|
|
156
|
+
items: CollectionItem[];
|
|
157
|
+
/** The offset this page started at. */
|
|
158
|
+
offset: number;
|
|
159
|
+
/** The page size requested (clamped to the server cap of 200). */
|
|
160
|
+
limit: number;
|
|
161
|
+
/** Total launcher ids in the requested collection set. */
|
|
162
|
+
total: number;
|
|
163
|
+
/** The offset of the next page, or null when this is the last page. */
|
|
164
|
+
next_offset: number | null;
|
|
165
|
+
}
|
|
166
|
+
/** Collection-level facts from `DigClient.getCollection` — derived from the resolved item set. */
|
|
167
|
+
interface CollectionMeta {
|
|
168
|
+
/** The creator DID launcher id the items AGREE on (lowercase hex), or null when mixed/none. */
|
|
169
|
+
did: string | null;
|
|
170
|
+
/** The DID the caller declared, echoed back (lowercase hex), or null. */
|
|
171
|
+
declared_did: string | null;
|
|
172
|
+
/** How many launcher ids were requested. */
|
|
173
|
+
item_count: number;
|
|
174
|
+
/** How many of those resolved to a live on-chain NFT. */
|
|
175
|
+
resolved_count: number;
|
|
176
|
+
/** The royalty (basis points) every item agrees on, or null when mixed. */
|
|
177
|
+
royalty_basis_points: number | null;
|
|
178
|
+
}
|
|
108
179
|
/** The two root-independent keys a URN maps to (derived client-side, nothing sent to the network). */
|
|
109
180
|
interface UrnKeys {
|
|
110
181
|
storeId: string;
|
|
@@ -187,13 +258,55 @@ declare class DigClient {
|
|
|
187
258
|
root: string;
|
|
188
259
|
salt?: string | null;
|
|
189
260
|
}, opts?: ReadOptions): Promise<ReadResult>;
|
|
261
|
+
/**
|
|
262
|
+
* Read a collection's public, owner-independent facts (creator DID, item count, uniform royalty)
|
|
263
|
+
* from the dig RPC (`dig.getCollection`). The collection's item set is its NFT launcher ids — the
|
|
264
|
+
* authoritative, owner-independent anchor the mint produced (a DID-attributed NFT is hinted to its
|
|
265
|
+
* OWNER at mint, not to the creator DID, so launcher ids — not the DID — are the read key). Pass
|
|
266
|
+
* the optional `did` to have it echoed back and recorded as the declared creator.
|
|
267
|
+
*
|
|
268
|
+
* No wallet, no read-crypto wasm — a plain JSON-RPC read. Throws a coded {@link DigSdkError} on a
|
|
269
|
+
* transport/RPC failure (never a "not found": an empty/partly-confirmed set just resolves to fewer
|
|
270
|
+
* items).
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* const meta = await dig.getCollection({ launcherIds: ["ab…", "cd…"], did: "ef…" });
|
|
274
|
+
* console.log(meta.resolved_count, meta.royalty_basis_points);
|
|
275
|
+
*/
|
|
276
|
+
getCollection(input: {
|
|
277
|
+
launcherIds: string[];
|
|
278
|
+
did?: string | null;
|
|
279
|
+
}, opts?: ReadOptions): Promise<CollectionMeta>;
|
|
280
|
+
/**
|
|
281
|
+
* Read a deterministic, paginated page of a collection's items (`dig.listCollectionItems`), each
|
|
282
|
+
* resolved to its CURRENT on-chain state — current owner, royalty, and CHIP-0007 metadata — by the
|
|
283
|
+
* RPC walking the singleton lineage forward to the live tip (so the owner is never the stale
|
|
284
|
+
* mint-time owner). Items come back in the input launcher-id order. `limit` is clamped to the
|
|
285
|
+
* server cap (200); `offset` defaults to 0.
|
|
286
|
+
*
|
|
287
|
+
* Throws a coded {@link DigSdkError} on a transport/RPC failure.
|
|
288
|
+
*
|
|
289
|
+
* @example
|
|
290
|
+
* let page = await dig.listCollectionItems({ launcherIds, limit: 50 });
|
|
291
|
+
* for (const item of page.items) console.log(item.launcher_id, item.owner_puzzle_hash);
|
|
292
|
+
* // page.next_offset is null on the last page.
|
|
293
|
+
*/
|
|
294
|
+
listCollectionItems(input: {
|
|
295
|
+
launcherIds: string[];
|
|
296
|
+
offset?: number;
|
|
297
|
+
limit?: number;
|
|
298
|
+
}, opts?: ReadOptions): Promise<CollectionItemsPage>;
|
|
190
299
|
private fetchCiphertext;
|
|
191
300
|
private rpcCall;
|
|
192
301
|
}
|
|
193
302
|
|
|
194
|
-
/**
|
|
195
|
-
|
|
196
|
-
|
|
303
|
+
/**
|
|
304
|
+
* SHA-256 (lowercase hex) of `@dignetwork/dig-client`'s `dig_client_bg.wasm` — the SRI digest. It
|
|
305
|
+
* is the canonical trust anchor (pinned regardless of the npm semver), mirrored by the package's
|
|
306
|
+
* `integrity.json` `sha256`. Fail closed on a mismatch.
|
|
307
|
+
*/
|
|
308
|
+
declare const DIG_CLIENT_WASM_SHA256 = "8c983561eabca34778abf698ca7c2fba36117f87282ca649079599ef7d1b1156";
|
|
309
|
+
/** Optional explicit wasm inputs, for environments where package resolution can't reach the wasm. */
|
|
197
310
|
interface WasmConfig {
|
|
198
311
|
/**
|
|
199
312
|
* The wasm bytes (already loaded). When provided, SRI is still enforced unless `skipIntegrity`.
|
|
@@ -201,13 +314,13 @@ interface WasmConfig {
|
|
|
201
314
|
*/
|
|
202
315
|
wasmBytes?: BufferSource;
|
|
203
316
|
/**
|
|
204
|
-
* URL to the wasm-bindgen glue module
|
|
205
|
-
*
|
|
317
|
+
* URL to the wasm-bindgen `web` glue module for browser dynamic import. When omitted in a browser,
|
|
318
|
+
* the loader imports `@dignetwork/dig-client/web` (the bundler resolves it).
|
|
206
319
|
*/
|
|
207
320
|
glueUrl?: string;
|
|
208
321
|
/**
|
|
209
322
|
* URL to fetch the wasm bytes from (browser) when `wasmBytes` is not supplied. The fetched bytes
|
|
210
|
-
* are SRI-verified before init.
|
|
323
|
+
* are SRI-verified before init. Defaults to the package's `dig_client_bg.wasm`.
|
|
211
324
|
*/
|
|
212
325
|
wasmUrl?: string;
|
|
213
326
|
/** Skip the SRI check. Only for tests / trusted custom builds — NOT recommended. */
|
|
@@ -260,4 +373,4 @@ declare function reconstructUrn(storeId: string, resourceKey: string): string;
|
|
|
260
373
|
*/
|
|
261
374
|
declare function reconstructUrnWithRoot(storeId: string, root: string, resourceKey: string): string;
|
|
262
375
|
|
|
263
|
-
export { DEFAULT_RPC as D, type InjectedChiaProvider as I, type ParsedUrn as P, type ReadOptions as R, type SignResult as S, type UrnKeys as U, type WalletBackend as W, type WalletSession as a,
|
|
376
|
+
export { type CollectionItem as C, DEFAULT_RPC as D, type InjectedChiaProvider as I, type ParsedUrn as P, type ReadOptions as R, type SignResult as S, type UrnKeys as U, type WalletBackend as W, type WalletSession as a, type CollectionItemMetadata as b, type CollectionItemsPage as c, type CollectionMeta as d, DIG_CLIENT_WASM_SHA256 as e, DigClient as f, type DigClientOptions as g, type DigClientWasm as h, type ReadResult as i, type WasmConfig as j, configureWasm as k, isUrn as l, loadDigClientWasm as m, reconstructUrnWithRoot as n, parseUrn as p, reconstructUrn as r };
|
package/dist/dig-client.cjs
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
4
|
+
// src/errors.ts
|
|
5
|
+
var DIG_SDK_ERROR_BRAND = "__dignetwork_dig_sdk_error__";
|
|
6
|
+
var DigSdkError = class _DigSdkError extends Error {
|
|
7
|
+
constructor(code, message, context = {}, options = {}) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "DigSdkError";
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.context = context;
|
|
12
|
+
if (options.cause !== void 0) {
|
|
13
|
+
this.cause = options.cause;
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(this, DIG_SDK_ERROR_BRAND, { value: true, enumerable: false });
|
|
16
|
+
Object.setPrototypeOf(this, _DigSdkError.prototype);
|
|
17
|
+
}
|
|
18
|
+
/** A JSON-friendly view of the error: `{ code, message, context }`. */
|
|
19
|
+
toJSON() {
|
|
20
|
+
return { code: this.code, message: this.message, context: this.context };
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
4
24
|
// src/loader.ts
|
|
5
|
-
var DIG_CLIENT_WASM_SHA256 = "
|
|
25
|
+
var DIG_CLIENT_WASM_SHA256 = "8c983561eabca34778abf698ca7c2fba36117f87282ca649079599ef7d1b1156";
|
|
6
26
|
var _config = {};
|
|
7
27
|
var _ready = null;
|
|
8
28
|
function configureWasm(config) {
|
|
@@ -26,49 +46,62 @@ async function sha256Hex(bytes) {
|
|
|
26
46
|
function assertIntegrity(hex) {
|
|
27
47
|
if (_config.skipIntegrity) return;
|
|
28
48
|
if (hex !== DIG_CLIENT_WASM_SHA256) {
|
|
29
|
-
throw new
|
|
30
|
-
|
|
49
|
+
throw new DigSdkError(
|
|
50
|
+
"WASM_INTEGRITY",
|
|
51
|
+
`dig-client wasm integrity check failed \u2014 refusing to run unverified crypto (expected ${DIG_CLIENT_WASM_SHA256}, got ${hex}).`,
|
|
52
|
+
{ expected: DIG_CLIENT_WASM_SHA256, actual: hex }
|
|
31
53
|
);
|
|
32
54
|
}
|
|
33
55
|
}
|
|
34
56
|
async function loadNode() {
|
|
57
|
+
const { createRequire } = await import('module');
|
|
35
58
|
const { readFile } = await import('fs/promises');
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const here = path.dirname(fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('dig-client.cjs', document.baseURI).href))));
|
|
39
|
-
const vendorDir = path.resolve(here, "..", "vendor");
|
|
40
|
-
const wasmPath = path.join(vendorDir, "dig_client_bg.wasm");
|
|
41
|
-
const gluePath = path.join(vendorDir, "dig_client.mjs");
|
|
59
|
+
const require2 = createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('dig-client.cjs', document.baseURI).href)));
|
|
60
|
+
const wasmPath = require2.resolve("@dignetwork/dig-client/dig_client_bg.wasm");
|
|
42
61
|
const buf = await readFile(wasmPath);
|
|
43
62
|
const bytes = new Uint8Array(buf.byteLength);
|
|
44
63
|
bytes.set(buf);
|
|
45
|
-
|
|
64
|
+
assertIntegrity(await sha256Hex(bytes));
|
|
65
|
+
const mod = await import('@dignetwork/dig-client/node');
|
|
66
|
+
return mod;
|
|
46
67
|
}
|
|
47
68
|
async function loadBrowser() {
|
|
48
|
-
const glueHref = _config.glueUrl ??
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
69
|
+
const glueHref = _config.glueUrl ?? "@dignetwork/dig-client/web";
|
|
70
|
+
const mod = await import(
|
|
71
|
+
/* @vite-ignore */
|
|
72
|
+
glueHref
|
|
73
|
+
);
|
|
74
|
+
if (typeof mod.default !== "function") {
|
|
75
|
+
throw new DigSdkError(
|
|
76
|
+
"WASM_LOAD_FAILED",
|
|
77
|
+
"dig-client web build exposed no init function (unexpected module shape)",
|
|
78
|
+
{}
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
if (_config.wasmBytes || _config.wasmUrl) {
|
|
82
|
+
let bytes;
|
|
83
|
+
if (_config.wasmBytes) {
|
|
84
|
+
bytes = _config.wasmBytes;
|
|
85
|
+
} else {
|
|
86
|
+
const wasmUrl = _config.wasmUrl;
|
|
87
|
+
const res = await fetch(wasmUrl);
|
|
88
|
+
if (!res.ok)
|
|
89
|
+
throw new DigSdkError("WASM_LOAD_FAILED", `dig-client wasm fetch failed (${res.status})`, {
|
|
90
|
+
httpStatus: res.status,
|
|
91
|
+
wasmUrl
|
|
92
|
+
});
|
|
93
|
+
bytes = await res.arrayBuffer();
|
|
94
|
+
}
|
|
95
|
+
assertIntegrity(await sha256Hex(bytes));
|
|
96
|
+
await mod.default({ module_or_path: bytes });
|
|
52
97
|
} else {
|
|
53
|
-
|
|
54
|
-
const res = await fetch(wasmUrl);
|
|
55
|
-
if (!res.ok) throw new Error(`dig-client wasm fetch failed (${res.status})`);
|
|
56
|
-
bytes = await res.arrayBuffer();
|
|
98
|
+
await mod.default();
|
|
57
99
|
}
|
|
58
|
-
return
|
|
100
|
+
return mod;
|
|
59
101
|
}
|
|
60
102
|
function loadDigClientWasm() {
|
|
61
103
|
if (_ready) return _ready;
|
|
62
|
-
_ready = (
|
|
63
|
-
const { glueHref, bytes } = isNode ? await loadNode() : await loadBrowser();
|
|
64
|
-
assertIntegrity(await sha256Hex(bytes));
|
|
65
|
-
const mod = await import(
|
|
66
|
-
/* @vite-ignore */
|
|
67
|
-
glueHref
|
|
68
|
-
);
|
|
69
|
-
await mod.default({ module_or_path: bytes });
|
|
70
|
-
return mod;
|
|
71
|
-
})().catch((e) => {
|
|
104
|
+
_ready = (isNode ? loadNode() : loadBrowser()).catch((e) => {
|
|
72
105
|
_ready = null;
|
|
73
106
|
throw e;
|
|
74
107
|
});
|
|
@@ -81,8 +114,10 @@ function parseUrn(raw) {
|
|
|
81
114
|
const s = String(raw ?? "").trim();
|
|
82
115
|
const m = URN_RE.exec(s);
|
|
83
116
|
if (!m) {
|
|
84
|
-
throw new
|
|
85
|
-
"
|
|
117
|
+
throw new DigSdkError(
|
|
118
|
+
"INVALID_ARGUMENT",
|
|
119
|
+
"Not a valid dig URN (expected urn:dig:chia:<store-id>[:<root>]/<path>[?salt=<hex>]).",
|
|
120
|
+
{ value: s, expected: "urn:dig:chia:<store-id>[:<root>]/<path>[?salt=<hex>]" }
|
|
86
121
|
);
|
|
87
122
|
}
|
|
88
123
|
return {
|
|
@@ -174,8 +209,10 @@ var DigClient = class {
|
|
|
174
209
|
const effSalt = input.salt ?? parsed.salt ?? null;
|
|
175
210
|
const effRoot = input.root ?? parsed.root ?? null;
|
|
176
211
|
if (!effRoot) {
|
|
177
|
-
throw new
|
|
178
|
-
"
|
|
212
|
+
throw new DigSdkError(
|
|
213
|
+
"ROOT_REQUIRED",
|
|
214
|
+
"a confirmed on-chain root is required to read content (pass { root } or use a root-pinned URN)",
|
|
215
|
+
{ urn: input.urn }
|
|
179
216
|
);
|
|
180
217
|
}
|
|
181
218
|
return this.readResource(
|
|
@@ -187,8 +224,10 @@ var DigClient = class {
|
|
|
187
224
|
async readText(input, opts = {}) {
|
|
188
225
|
const r = await this.read(input, opts);
|
|
189
226
|
if (!r.decrypted) {
|
|
190
|
-
throw new
|
|
191
|
-
"
|
|
227
|
+
throw new DigSdkError(
|
|
228
|
+
"DECRYPT_FAILED",
|
|
229
|
+
"resource did not decrypt under this URN \u2014 wrong store/key/salt, or a decoy response",
|
|
230
|
+
{ urn: input.urn }
|
|
192
231
|
);
|
|
193
232
|
}
|
|
194
233
|
return new TextDecoder().decode(r.bytes);
|
|
@@ -237,6 +276,62 @@ var DigClient = class {
|
|
|
237
276
|
};
|
|
238
277
|
}
|
|
239
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* Read a collection's public, owner-independent facts (creator DID, item count, uniform royalty)
|
|
281
|
+
* from the dig RPC (`dig.getCollection`). The collection's item set is its NFT launcher ids — the
|
|
282
|
+
* authoritative, owner-independent anchor the mint produced (a DID-attributed NFT is hinted to its
|
|
283
|
+
* OWNER at mint, not to the creator DID, so launcher ids — not the DID — are the read key). Pass
|
|
284
|
+
* the optional `did` to have it echoed back and recorded as the declared creator.
|
|
285
|
+
*
|
|
286
|
+
* No wallet, no read-crypto wasm — a plain JSON-RPC read. Throws a coded {@link DigSdkError} on a
|
|
287
|
+
* transport/RPC failure (never a "not found": an empty/partly-confirmed set just resolves to fewer
|
|
288
|
+
* items).
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* const meta = await dig.getCollection({ launcherIds: ["ab…", "cd…"], did: "ef…" });
|
|
292
|
+
* console.log(meta.resolved_count, meta.royalty_basis_points);
|
|
293
|
+
*/
|
|
294
|
+
async getCollection(input, opts = {}) {
|
|
295
|
+
const rpc = opts.rpc ?? this.rpc;
|
|
296
|
+
const params = { launcher_ids: input.launcherIds };
|
|
297
|
+
if (input.did) params.did = input.did;
|
|
298
|
+
const r = await this.rpcCall(rpc, "dig.getCollection", params);
|
|
299
|
+
if (!r)
|
|
300
|
+
throw new DigSdkError(
|
|
301
|
+
"RPC_MALFORMED_RESPONSE",
|
|
302
|
+
"The content network returned no collection facts for this request.",
|
|
303
|
+
{ rpcMethod: "dig.getCollection" }
|
|
304
|
+
);
|
|
305
|
+
return r;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Read a deterministic, paginated page of a collection's items (`dig.listCollectionItems`), each
|
|
309
|
+
* resolved to its CURRENT on-chain state — current owner, royalty, and CHIP-0007 metadata — by the
|
|
310
|
+
* RPC walking the singleton lineage forward to the live tip (so the owner is never the stale
|
|
311
|
+
* mint-time owner). Items come back in the input launcher-id order. `limit` is clamped to the
|
|
312
|
+
* server cap (200); `offset` defaults to 0.
|
|
313
|
+
*
|
|
314
|
+
* Throws a coded {@link DigSdkError} on a transport/RPC failure.
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* let page = await dig.listCollectionItems({ launcherIds, limit: 50 });
|
|
318
|
+
* for (const item of page.items) console.log(item.launcher_id, item.owner_puzzle_hash);
|
|
319
|
+
* // page.next_offset is null on the last page.
|
|
320
|
+
*/
|
|
321
|
+
async listCollectionItems(input, opts = {}) {
|
|
322
|
+
const rpc = opts.rpc ?? this.rpc;
|
|
323
|
+
const params = { launcher_ids: input.launcherIds };
|
|
324
|
+
if (input.offset !== void 0) params.offset = input.offset;
|
|
325
|
+
if (input.limit !== void 0) params.limit = input.limit;
|
|
326
|
+
const r = await this.rpcCall(rpc, "dig.listCollectionItems", params);
|
|
327
|
+
if (!r)
|
|
328
|
+
throw new DigSdkError(
|
|
329
|
+
"RPC_MALFORMED_RESPONSE",
|
|
330
|
+
"The content network returned no collection items for this request.",
|
|
331
|
+
{ rpcMethod: "dig.listCollectionItems" }
|
|
332
|
+
);
|
|
333
|
+
return r;
|
|
334
|
+
}
|
|
240
335
|
// Stream the FULL ciphertext for a resource from the RPC by retrieval key, reassembling 3-MiB
|
|
241
336
|
// chunks. A null result is a TRANSPORT failure, never a presence judgment.
|
|
242
337
|
async fetchCiphertext(storeId, rk, root, rpc) {
|
|
@@ -253,7 +348,12 @@ var DigClient = class {
|
|
|
253
348
|
offset,
|
|
254
349
|
length: RPC_CHUNK_BYTES
|
|
255
350
|
});
|
|
256
|
-
if (!r)
|
|
351
|
+
if (!r)
|
|
352
|
+
throw new DigSdkError(
|
|
353
|
+
"RPC_MALFORMED_RESPONSE",
|
|
354
|
+
"The content network returned no data for this request.",
|
|
355
|
+
{ rpcMethod: "dig.getContent" }
|
|
356
|
+
);
|
|
257
357
|
if (total === null) {
|
|
258
358
|
total = r.total_length >>> 0;
|
|
259
359
|
buf = new Uint8Array(total);
|
|
@@ -270,7 +370,8 @@ var DigClient = class {
|
|
|
270
370
|
}
|
|
271
371
|
return { ciphertext: buf ?? new Uint8Array(0), proof, chunkLens };
|
|
272
372
|
}
|
|
273
|
-
// One JSON-RPC 2.0 call. Throws on transport failure or a
|
|
373
|
+
// One JSON-RPC 2.0 call. Throws a coded DigSdkError on transport failure (RPC_TRANSPORT) or a
|
|
374
|
+
// JSON-RPC/HTTP error (RPC_ERROR, carrying rpcMethod/httpStatus/rpcCode context); returns `result`.
|
|
274
375
|
async rpcCall(rpc, method, params) {
|
|
275
376
|
let res;
|
|
276
377
|
try {
|
|
@@ -279,12 +380,26 @@ var DigClient = class {
|
|
|
279
380
|
headers: { "content-type": "application/json" },
|
|
280
381
|
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params })
|
|
281
382
|
});
|
|
282
|
-
} catch {
|
|
283
|
-
throw new
|
|
383
|
+
} catch (e) {
|
|
384
|
+
throw new DigSdkError(
|
|
385
|
+
"RPC_TRANSPORT",
|
|
386
|
+
"Could not reach the content network. Check your connection and try again.",
|
|
387
|
+
{ rpcMethod: method },
|
|
388
|
+
{ cause: e }
|
|
389
|
+
);
|
|
284
390
|
}
|
|
285
|
-
if (!res.ok)
|
|
391
|
+
if (!res.ok)
|
|
392
|
+
throw new DigSdkError("RPC_ERROR", `dig RPC ${method} failed (${res.status})`, {
|
|
393
|
+
rpcMethod: method,
|
|
394
|
+
httpStatus: res.status
|
|
395
|
+
});
|
|
286
396
|
const json = await res.json();
|
|
287
|
-
if (json && json.error)
|
|
397
|
+
if (json && json.error)
|
|
398
|
+
throw new DigSdkError(
|
|
399
|
+
"RPC_ERROR",
|
|
400
|
+
`dig RPC ${method}: ${json.error.message ?? "error"}`,
|
|
401
|
+
{ rpcMethod: method, rpcCode: json.error.code }
|
|
402
|
+
);
|
|
288
403
|
return json ? json.result ?? null : null;
|
|
289
404
|
}
|
|
290
405
|
};
|
|
@@ -292,7 +407,11 @@ function decryptResourceChunks(wasm, keyHex, ciphertext, chunkLens) {
|
|
|
292
407
|
const lens = chunkLens && chunkLens.length ? chunkLens : [ciphertext.length];
|
|
293
408
|
const total = lens.reduce((a, n) => a + n, 0);
|
|
294
409
|
if (total !== ciphertext.length) {
|
|
295
|
-
throw new
|
|
410
|
+
throw new DigSdkError(
|
|
411
|
+
"RPC_MALFORMED_RESPONSE",
|
|
412
|
+
"served ciphertext length does not match chunk lengths",
|
|
413
|
+
{ rpcMethod: "dig.getContent", expected: String(total), actual: String(ciphertext.length) }
|
|
414
|
+
);
|
|
296
415
|
}
|
|
297
416
|
if (lens.length === 1) return wasm.decryptChunk(keyHex, ciphertext);
|
|
298
417
|
const parts = [];
|
|
@@ -311,7 +430,8 @@ function decryptResourceChunks(wasm, keyHex, ciphertext, chunkLens) {
|
|
|
311
430
|
}
|
|
312
431
|
function undefinedFetch() {
|
|
313
432
|
return (() => {
|
|
314
|
-
throw new
|
|
433
|
+
throw new DigSdkError(
|
|
434
|
+
"INVALID_ARGUMENT",
|
|
315
435
|
"No global fetch available. Pass { fetch } to DigClient (Node < 18 needs a fetch polyfill)."
|
|
316
436
|
);
|
|
317
437
|
});
|