@inversealtruism/cairn-sdk 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,13 +4,13 @@ import {
4
4
  } from "./chunk-C452UODV.js";
5
5
  import {
6
6
  ContentClient
7
- } from "./chunk-QEYBWBXC.js";
7
+ } from "./chunk-DTPADO7N.js";
8
8
  import {
9
9
  IndexerClient
10
- } from "./chunk-K5MGEYEU.js";
10
+ } from "./chunk-CI7YODPP.js";
11
11
  import {
12
12
  CairnController
13
- } from "./chunk-MLNW2RQB.js";
13
+ } from "./chunk-JXBO4LV6.js";
14
14
  import {
15
15
  WalletConnection,
16
16
  connect,
@@ -18,14 +18,7 @@ import {
18
18
  discoverProviders,
19
19
  getWallet,
20
20
  isInstalled
21
- } from "./chunk-BMH2MACB.js";
22
- import {
23
- Http,
24
- RegistryClient,
25
- RetryWaitBudget,
26
- readCapped,
27
- retryAfterMs
28
- } from "./chunk-67QBDZPW.js";
21
+ } from "./chunk-WWO3FXHG.js";
29
22
  import {
30
23
  CairnError,
31
24
  ContentVerificationError,
@@ -39,12 +32,181 @@ import {
39
32
  errorCode,
40
33
  mapProviderError,
41
34
  mapSubmitResultError
42
- } from "./chunk-2A4AJBO5.js";
35
+ } from "./chunk-UAPWZZQK.js";
36
+
37
+ // src/http.ts
38
+ var DEFAULT_MAX_BYTES = 16 * 1024 * 1024;
39
+ var ERR_TEXT_CAP = 8 * 1024;
40
+ var MAX_RETRY_AFTER_MS = 6e4;
41
+ function retryAfterMs(res) {
42
+ const secs = Number(res.headers.get("retry-after"));
43
+ return Number.isFinite(secs) && secs > 0 ? Math.min(secs * 1e3, MAX_RETRY_AFTER_MS) : 0;
44
+ }
45
+ var RetryWaitBudget = class {
46
+ left;
47
+ constructor(totalMs) {
48
+ this.left = totalMs;
49
+ }
50
+ /** The ms to sleep before the next attempt (`ownMs` is the caller's backoff, clipped to what is left), or
51
+ * null when the server's hint exceeds the remaining budget. */
52
+ take(ownMs, serverMs) {
53
+ if (serverMs > this.left) return null;
54
+ const ms = Math.min(Math.max(ownMs, serverMs), this.left);
55
+ this.left -= ms;
56
+ return ms;
57
+ }
58
+ };
59
+ var HTTP_RETRY_WAIT_BUDGET_MS = 3e4;
60
+ async function readCapped(res, maxBytes) {
61
+ const cl = Number(res.headers.get("content-length"));
62
+ if (Number.isFinite(cl) && cl > maxBytes) throw new HttpError(res.status, res.url, `response too large (content-length ${cl} > ${maxBytes})`);
63
+ const body = res.body;
64
+ if (!body || typeof body.getReader !== "function") {
65
+ const buf = new Uint8Array(await res.arrayBuffer());
66
+ if (buf.byteLength > maxBytes) throw new HttpError(res.status, res.url, `response too large (${buf.byteLength} > ${maxBytes})`);
67
+ return buf;
68
+ }
69
+ const reader = body.getReader();
70
+ const chunks = [];
71
+ let total = 0;
72
+ for (; ; ) {
73
+ const { done, value } = await reader.read();
74
+ if (done) break;
75
+ if (value) {
76
+ total += value.byteLength;
77
+ if (total > maxBytes) {
78
+ try {
79
+ await reader.cancel();
80
+ } catch {
81
+ }
82
+ throw new HttpError(res.status, res.url, `response exceeded ${maxBytes} bytes`);
83
+ }
84
+ chunks.push(value);
85
+ }
86
+ }
87
+ const out = new Uint8Array(total);
88
+ let off = 0;
89
+ for (const c of chunks) {
90
+ out.set(c, off);
91
+ off += c.byteLength;
92
+ }
93
+ return out;
94
+ }
95
+ var Http = class {
96
+ baseUrl;
97
+ _fetch;
98
+ timeoutMs;
99
+ maxBytes;
100
+ headers;
101
+ retries;
102
+ constructor(opts) {
103
+ this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
104
+ const f = opts.fetch ?? globalThis.fetch;
105
+ if (!f) throw new Error("No fetch available \u2014 pass `fetch` in the SDK options.");
106
+ this._fetch = opts.fetch ? opts.fetch : f.bind(globalThis);
107
+ this.timeoutMs = opts.timeoutMs ?? 15e3;
108
+ this.maxBytes = Number.isFinite(opts.maxBytes) && opts.maxBytes >= 1 ? Math.floor(opts.maxBytes) : DEFAULT_MAX_BYTES;
109
+ this.headers = opts.headers ?? {};
110
+ const retries = Number(opts.retries ?? 0);
111
+ this.retries = Number.isNaN(retries) ? 0 : Math.min(10, Math.max(0, Math.floor(retries)));
112
+ }
113
+ /** Build an absolute URL from a path + optional query params. */
114
+ url(path, query) {
115
+ const p = path.startsWith("/") ? path : `/${path}`;
116
+ const u = new URL(this.baseUrl + p);
117
+ const basePath = new URL(this.baseUrl + "/").pathname;
118
+ if (basePath !== "/" && !(u.pathname + "/").startsWith(basePath)) {
119
+ throw new Error(`illegal path '${path}' \u2014 escapes base ${basePath}`);
120
+ }
121
+ if (query) {
122
+ for (const [k, v] of Object.entries(query)) {
123
+ if (v !== void 0 && v !== null) u.searchParams.set(k, String(v));
124
+ }
125
+ }
126
+ return u.toString();
127
+ }
128
+ async raw(method, path, opts) {
129
+ const url = this.url(path, opts?.query);
130
+ const ctrl = new AbortController();
131
+ const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
132
+ try {
133
+ const res = await this._fetch(url, {
134
+ method,
135
+ signal: ctrl.signal,
136
+ headers: {
137
+ ...opts?.body !== void 0 ? { "content-type": "application/json" } : {},
138
+ ...this.headers,
139
+ ...opts?.headers ?? {}
140
+ },
141
+ body: opts?.body !== void 0 ? JSON.stringify(opts.body) : void 0
142
+ });
143
+ const body = await readCapped(res, this.maxBytes);
144
+ return { res, body };
145
+ } finally {
146
+ clearTimeout(timer);
147
+ }
148
+ }
149
+ // A malformed 2xx body must surface as a TYPED HttpError, not a leaked SyntaxError (B10: dApp
150
+ // code branches on `instanceof CairnError`; a raw parse error escaped that contract).
151
+ parseJson(res, text, url) {
152
+ try {
153
+ return JSON.parse(text);
154
+ } catch (e) {
155
+ throw new HttpError(res.status, url, `invalid JSON body: ${text.slice(0, 120)}`);
156
+ }
157
+ }
158
+ async getJson(path, query) {
159
+ const url = this.url(path, query);
160
+ const budget = new RetryWaitBudget(HTTP_RETRY_WAIT_BUDGET_MS);
161
+ for (let attempt = 0; ; attempt++) {
162
+ let serverWaitMs = 0;
163
+ let last;
164
+ try {
165
+ const { res, body } = await this.raw("GET", path, { query });
166
+ if (!res.ok) {
167
+ last = new HttpError(res.status, url, errText(body));
168
+ if (!(res.status >= 500 && attempt < this.retries)) throw last;
169
+ serverWaitMs = retryAfterMs(res);
170
+ } else {
171
+ return this.parseJson(res, new TextDecoder().decode(body), url);
172
+ }
173
+ } catch (e) {
174
+ if (e instanceof HttpError && e.status < 500) throw e;
175
+ if (attempt >= this.retries) throw e;
176
+ }
177
+ const jitterMs = Math.floor(Math.random() * Math.min(4e3, 250 * 2 ** attempt));
178
+ const waitMs = budget.take(jitterMs, serverWaitMs);
179
+ if (waitMs === null) throw last ?? new HttpError(0, url, "retry wait budget exhausted");
180
+ await new Promise((r) => setTimeout(r, waitMs));
181
+ }
182
+ }
183
+ async postJson(path, body, headers) {
184
+ const url = this.url(path);
185
+ const { res, body: respBody } = await this.raw("POST", path, { body, headers });
186
+ if (!res.ok) throw new HttpError(res.status, url, errText(respBody));
187
+ return this.parseJson(res, new TextDecoder().decode(respBody), url);
188
+ }
189
+ /** GET raw bytes (for content retrieval). Returns null on 404. */
190
+ async getBytes(path) {
191
+ const { res, body } = await this.raw("GET", path);
192
+ if (res.status === 404) return null;
193
+ if (!res.ok) throw new HttpError(res.status, this.url(path), errText(body));
194
+ return { bytes: body, headers: res.headers };
195
+ }
196
+ };
197
+ function errText(body) {
198
+ try {
199
+ return new TextDecoder().decode(body).slice(0, ERR_TEXT_CAP);
200
+ } catch {
201
+ return "";
202
+ }
203
+ }
43
204
 
44
205
  // src/names.ts
45
- import { NAME_RE, RESERVED_NAMES, TICKER_RE, AMOUNT_RE, HASH_RE } from "@inversealtruism/cairnx-core";
206
+ import { NAME_RE, RESERVED_NAMES, TICKER_RE, HASH_RE, MAX_TOKEN_DECIMALS, parseAmount } from "@inversealtruism/cairnx-core";
46
207
  var nameOk = (n) => typeof n === "string" && NAME_RE.test(n) && !RESERVED_NAMES.has(n);
47
- var amountOk = (v) => typeof v === "string" && AMOUNT_RE.test(v);
208
+ var amountOk = (v) => parseAmount(v, { allowZero: true }) !== null;
209
+ var decimalsOk = (d) => Number.isSafeInteger(d) && d >= 0 && d <= MAX_TOKEN_DECIMALS;
48
210
  var heightOk = (v) => Number.isSafeInteger(v) && v >= 0;
49
211
  function nameHistoryProblem(h, name) {
50
212
  if (!h || typeof h !== "object" || Array.isArray(h)) return "not an object";
@@ -61,14 +223,15 @@ function nameHistoryProblem(h, name) {
61
223
  }
62
224
  return null;
63
225
  }
64
- function tokenProblem(t) {
226
+ function tokenProblem(t, ticker) {
65
227
  if (!t || typeof t !== "object") return "not an object";
66
228
  const r = t;
67
229
  if (typeof r.ticker !== "string" || !TICKER_RE.test(r.ticker)) return "bad ticker";
68
- if (!Number.isSafeInteger(r.decimals) || r.decimals < 0) return `bad decimals (${String(r.decimals)})`;
69
- if (!amountOk(r.supply)) return "supply is not a base-unit integer string";
70
- if (!amountOk(r.minted)) return "minted is not a base-unit integer string";
71
- if (r.mintLimit !== void 0 && !amountOk(r.mintLimit)) return "mintLimit is not a base-unit integer string";
230
+ if (ticker !== void 0 && r.ticker !== ticker) return `ticker is ${JSON.stringify(r.ticker)}, expected ${JSON.stringify(ticker)}`;
231
+ if (!decimalsOk(r.decimals)) return `bad decimals (${String(r.decimals)}), not an integer in the consensus range`;
232
+ if (!amountOk(r.supply)) return "supply is not a base-unit integer string within MAX_AMOUNT";
233
+ if (!amountOk(r.minted)) return "minted is not a base-unit integer string within MAX_AMOUNT";
234
+ if (r.mintLimit !== void 0 && !amountOk(r.mintLimit)) return "mintLimit is not a base-unit integer string within MAX_AMOUNT";
72
235
  return null;
73
236
  }
74
237
  var NamesClient = class {
@@ -79,11 +242,17 @@ var NamesClient = class {
79
242
  malformed(path, what) {
80
243
  return new HttpError(200, this.http.url(path), `malformed response: ${what}`);
81
244
  }
82
- async list(path) {
83
- const body = await this.http.getJson(path);
245
+ async list(path, query) {
246
+ const body = await this.http.getJson(path, query);
84
247
  if (!Array.isArray(body)) throw this.malformed(path, "expected an array");
85
248
  return body;
86
249
  }
250
+ /** Rows of a market list with one status, or every row for "all". */
251
+ async byStatus(path, status) {
252
+ if (status === "all") return this.list(path);
253
+ const rows = await this.list(path, { status });
254
+ return rows.filter((r) => r?.status === status);
255
+ }
87
256
  /** Resolve a .csd name for DISPLAY (server-trusted; see the module trust note). null = unknown/invalid name. */
88
257
  async resolve(name) {
89
258
  if (!nameOk(name)) return null;
@@ -154,7 +323,8 @@ var NamesClient = class {
154
323
  });
155
324
  return rows;
156
325
  }
157
- /** One token by ticker. null = unknown/invalid ticker. Throws a typed HttpError on a malformed body. */
326
+ /** One token by ticker. null = unknown/invalid ticker. Throws a typed HttpError on a malformed body or a
327
+ * record for another ticker. */
158
328
  async token(ticker) {
159
329
  if (typeof ticker !== "string" || !TICKER_RE.test(ticker)) return null;
160
330
  const path = `/trade/api/cairnx/token/${ticker}`;
@@ -165,17 +335,19 @@ var NamesClient = class {
165
335
  if (e?.status === 404) return null;
166
336
  throw e;
167
337
  }
168
- const p = tokenProblem(t);
338
+ const p = tokenProblem(t, ticker);
169
339
  if (p) throw this.malformed(path, p);
170
340
  return t;
171
341
  }
172
- /** Open offers (the market's display list). */
173
- offers() {
174
- return this.list(`/trade/api/cairnx/offers`);
342
+ /** Offers with one status, open ones by default (the market's display list). `{ status: "all" }` returns every
343
+ * offer the server holds, filled, cancelled and expired ones included. */
344
+ offers(opts = {}) {
345
+ return this.byStatus(`/trade/api/cairnx/offers`, opts.status ?? "open");
175
346
  }
176
- /** Open bids. */
177
- bids() {
178
- return this.list(`/trade/api/cairnx/bids`);
347
+ /** Bids with one status, open ones by default. `{ status: "all" }` returns every bid the server holds, done,
348
+ * cancelled and expired ones included. */
349
+ bids(opts = {}) {
350
+ return this.byStatus(`/trade/api/cairnx/bids`, opts.status ?? "open");
179
351
  }
180
352
  /** The full canonical CairnX state (large; prefer the scoped reads above). */
181
353
  state() {
@@ -348,10 +520,10 @@ async function preverifyOffer(opts) {
348
520
  return { ok: false, trust: "verified", reason: "the served offer is missing seller (the rebate recipient) - pass the resolver's full offer object, or omit servedOffer", ...base };
349
521
  if (String(so.seller).toLowerCase() !== seller)
350
522
  return { ok: false, trust: "verified", reason: "the served seller doesn't match the offer's on-chain author (a lying resolver may be redirecting your payment)", ...base };
351
- if (bindOfferTerms(opts.servedOffer, terms, { give: true, wantType: true }))
352
- return { ok: false, trust: "verified", reason: "the served terms don't match the offer's on-chain record (fee, rebate, partial sizing, the give, or the want type - a lying resolver could mis-size or re-route the fill, redirecting or burning your payment)", ...base };
353
523
  if (isTokenWant(offerRec.want) && (String(so?.want?.ticker) !== String(offerRec.want.ticker) || String(so?.want?.amount) !== String(offerRec.want.amount)))
354
524
  return { ok: false, trust: "verified", reason: "the served want ticker/amount don't match the offer's on-chain record (a lying resolver could bait-and-switch the token price)", ...base };
525
+ if (bindOfferTerms(opts.servedOffer, terms, { give: true, wantType: true }))
526
+ return { ok: false, trust: "verified", reason: "the served terms don't match the offer's on-chain record (fee, rebate, partial sizing, the give, or the want type - a lying resolver could mis-size or re-route the fill, redirecting or burning your payment)", ...base };
355
527
  }
356
528
  if (sumsMismatch) return { ok: false, trust: "verified", reason: sumsMismatch, ...base };
357
529
  return { ok: true, trust: "verified", ...base };
@@ -379,7 +551,6 @@ var Cairn = class {
379
551
  chain;
380
552
  index;
381
553
  content;
382
- registry;
383
554
  /** .csd names + CairnX market READS (server-trusted display reads; see names.ts trust note). */
384
555
  names;
385
556
  wallet;
@@ -403,7 +574,6 @@ var Cairn = class {
403
574
  this.cairnHttp = new Http({ baseUrl: cairn, fetch, timeoutMs });
404
575
  this._cairnBase = cairn;
405
576
  const indexerHttp = new Http({ baseUrl: indexer, fetch, timeoutMs });
406
- const swarmHttp = config.baseUrls?.swarm ? new Http({ baseUrl: config.baseUrls.swarm.replace(/\/+$/, ""), fetch, timeoutMs }) : void 0;
407
577
  this._spvCp = config.spvCheckpoint ?? DEFAULT_SPV_CHECKPOINT;
408
578
  this.chain = new Chain({ rpcUrl: rpc, fetch, timeoutMs });
409
579
  this.wallet = config.wallet;
@@ -412,8 +582,7 @@ var Cairn = class {
412
582
  WebSocketImpl: config.WebSocketImpl,
413
583
  headerMerkleAt: (h) => this.verifiedHeaderMerkleAt(h)
414
584
  });
415
- this.content = new ContentClient({ swarm: swarmHttp, indexer: indexerHttp, cairn: this.cairnHttp });
416
- this.registry = new RegistryClient(indexerHttp);
585
+ this.content = new ContentClient({ cairn: this.cairnHttp });
417
586
  this.names = new NamesClient(this.cairnHttp);
418
587
  }
419
588
  /**
@@ -621,7 +790,6 @@ export {
621
790
  IndexerClient,
622
791
  NamesClient,
623
792
  NotInstalledError,
624
- RegistryClient,
625
793
  SDK_VERSION,
626
794
  SubmitInFlightError,
627
795
  UnsupportedMethodError,
package/dist/indexer.cjs CHANGED
@@ -93,18 +93,6 @@ var IndexerClient = class {
93
93
  attestations(id) {
94
94
  return this.http.getJson(`/proposal/${encodeURIComponent(id)}/attestations`);
95
95
  }
96
- registryPeers() {
97
- return this.http.getJson("/registry/peers");
98
- }
99
- registryGateways() {
100
- return this.http.getJson("/registry/gateways");
101
- }
102
- identity(handle) {
103
- return this.http.getJson(`/identity/${encodeURIComponent(handle)}`);
104
- }
105
- reverseIdentity(addr) {
106
- return this.http.getJson(`/address/${encodeURIComponent(addr)}/identity`);
107
- }
108
96
  // ---- trust-minimized inclusion ----------------------------------------
109
97
  /**
110
98
  * Verify a tx is included in a block by folding its merkle branch to the root
@@ -68,10 +68,6 @@ declare class IndexerClient {
68
68
  domainProposals(d: string): Promise<unknown[]>;
69
69
  proposal(id: string): Promise<unknown>;
70
70
  attestations(id: string): Promise<unknown[]>;
71
- registryPeers(): Promise<unknown[]>;
72
- registryGateways(): Promise<unknown[]>;
73
- identity(handle: string): Promise<unknown>;
74
- reverseIdentity(addr: string): Promise<unknown>;
75
71
  /**
76
72
  * Verify a tx is included in a block by folding its merkle branch to the root
77
73
  * with csd-codec.verifyMerkleProof. If `headerMerkleAt` was provided, the
package/dist/indexer.d.ts CHANGED
@@ -68,10 +68,6 @@ declare class IndexerClient {
68
68
  domainProposals(d: string): Promise<unknown[]>;
69
69
  proposal(id: string): Promise<unknown>;
70
70
  attestations(id: string): Promise<unknown[]>;
71
- registryPeers(): Promise<unknown[]>;
72
- registryGateways(): Promise<unknown[]>;
73
- identity(handle: string): Promise<unknown>;
74
- reverseIdentity(addr: string): Promise<unknown>;
75
71
  /**
76
72
  * Verify a tx is included in a block by folding its merkle branch to the root
77
73
  * with csd-codec.verifyMerkleProof. If `headerMerkleAt` was provided, the
package/dist/indexer.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  IndexerClient
3
- } from "./chunk-K5MGEYEU.js";
3
+ } from "./chunk-CI7YODPP.js";
4
4
  export {
5
5
  IndexerClient
6
6
  };
package/dist/react.cjs CHANGED
@@ -26,7 +26,7 @@ __export(react_exports, {
26
26
  module.exports = __toCommonJS(react_exports);
27
27
 
28
28
  // src/errors.ts
29
- var SDK_VERSION = "0.6.0";
29
+ var SDK_VERSION = "0.8.0";
30
30
  var DOCS_BASE = "https://cairn-substrate.com/docs/sdk";
31
31
  var CairnError = class extends Error {
32
32
  /** Stable machine code for programmatic branching. */
package/dist/react.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  CairnController
3
- } from "./chunk-MLNW2RQB.js";
4
- import "./chunk-BMH2MACB.js";
5
- import "./chunk-2A4AJBO5.js";
3
+ } from "./chunk-JXBO4LV6.js";
4
+ import "./chunk-WWO3FXHG.js";
5
+ import "./chunk-UAPWZZQK.js";
6
6
 
7
7
  // src/react.ts
8
8
  function createCairnHooks(React, controllerOrOpts) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@inversealtruism/cairn-sdk",
3
- "version": "0.6.0",
4
- "description": "The Compute Substrate dApp kit: one cohesive toolkit to connect the Cairn Wallet, read the chain, the indexer and .csd names, verify self-certifying content, and resolve registries. Composes the published csd-* primitives.",
3
+ "version": "0.8.0",
4
+ "description": "The Compute Substrate dApp kit: one cohesive toolkit to connect the Cairn Wallet, read the chain, the indexer and .csd names, verify self-certifying content, and resolve .csd names. Composes the published csd-* primitives.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",
@@ -27,11 +27,6 @@
27
27
  "import": "./dist/content.js",
28
28
  "require": "./dist/content.cjs"
29
29
  },
30
- "./registry": {
31
- "types": "./dist/registry.d.ts",
32
- "import": "./dist/registry.js",
33
- "require": "./dist/registry.cjs"
34
- },
35
30
  "./chain": {
36
31
  "types": "./dist/chain.d.ts",
37
32
  "import": "./dist/chain.js",
@@ -54,21 +49,22 @@
54
49
  "README.md"
55
50
  ],
56
51
  "dependencies": {
57
- "@inversealtruism/cairnx-core": "0.2.0",
58
- "@inversealtruism/csd-client": "0.1.18",
52
+ "@inversealtruism/cairnx-core": "0.2.2",
53
+ "@inversealtruism/csd-client": "0.1.19",
59
54
  "@inversealtruism/csd-codec": "0.1.18",
60
- "@inversealtruism/csd-crypto": "0.1.18",
61
- "@inversealtruism/csd-light": "0.1.23",
62
- "@inversealtruism/csd-registry": "0.1.20",
63
- "@inversealtruism/csd-tx": "0.1.21"
55
+ "@inversealtruism/csd-crypto": "0.1.20",
56
+ "@inversealtruism/csd-light": "0.1.25",
57
+ "@inversealtruism/csd-tx": "0.1.23"
64
58
  },
65
59
  "devDependencies": {
66
- "@inversealtruism/csd-siwc": "0.1.19",
67
- "esbuild": "^0.27.0",
68
- "playwright-core": "^1.49.0",
69
- "tsup": "^8.5.1",
70
- "tsx": "^4.19.2",
71
- "typescript": "^5.6.0"
60
+ "@biomejs/biome": "2.5.15",
61
+ "@inversealtruism/csd-siwc": "0.1.21",
62
+ "@types/node": "22.19.20",
63
+ "esbuild": "0.28.2",
64
+ "playwright-core": "1.60.0",
65
+ "tsup": "8.5.1",
66
+ "tsx": "4.22.4",
67
+ "typescript": "5.9.3"
72
68
  },
73
69
  "sideEffects": false,
74
70
  "license": "MIT",
@@ -90,14 +86,15 @@
90
86
  "blockchain"
91
87
  ],
92
88
  "scripts": {
93
- "build": "tsup src/index.ts src/connect.ts src/indexer.ts src/content.ts src/registry.ts src/chain.ts src/controller.ts src/react.ts --format esm,cjs --dts --clean",
89
+ "build": "tsup src/index.ts src/connect.ts src/indexer.ts src/content.ts src/chain.ts src/controller.ts src/react.ts --format esm,cjs --dts --clean",
90
+ "typecheck": "tsc -p tsconfig.typecheck.json",
91
+ "lint": "biome lint --max-diagnostics=none .",
92
+ "check:dashes-paths": "node scripts/check-dashes-paths.mjs",
94
93
  "test": "node test/run.mjs",
95
- "test:live": "node examples/read-only.mjs",
94
+ "test:live": "node examples/read-only.mjs && node test/e2e/e2e-read.mjs",
95
+ "test:live:wallet": "xvfb-run -a node test/e2e/e2e-wallet-connect.mjs",
96
96
  "build:example": "node scripts/build-example.mjs",
97
97
  "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
98
- "test:e2e:read": "node test/e2e/e2e-read.mjs",
99
- "test:e2e:wallet": "xvfb-run -a node test/e2e/e2e-wallet-connect.mjs",
100
- "test:e2e": "node test/e2e/e2e-read.mjs && xvfb-run -a node test/e2e/e2e-wallet-connect.mjs",
101
- "test:all": "pnpm test && pnpm test:e2e"
98
+ "test:all": "pnpm test && pnpm test:live && pnpm test:live:wallet"
102
99
  }
103
100
  }