@inversealtruism/cairn-sdk 0.1.4 → 0.2.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.cjs CHANGED
@@ -31,6 +31,7 @@ __export(index_exports, {
31
31
  Http: () => Http,
32
32
  HttpError: () => HttpError,
33
33
  IndexerClient: () => IndexerClient,
34
+ NamesClient: () => NamesClient,
34
35
  NotInstalledError: () => NotInstalledError,
35
36
  RegistryClient: () => RegistryClient,
36
37
  SDK_VERSION: () => SDK_VERSION,
@@ -49,7 +50,7 @@ __export(index_exports, {
49
50
  module.exports = __toCommonJS(index_exports);
50
51
 
51
52
  // src/errors.ts
52
- var SDK_VERSION = "0.1.4";
53
+ var SDK_VERSION = "0.2.0";
53
54
  var DOCS_BASE = "https://cairn-substrate.com/docs/sdk";
54
55
  var CairnError = class extends Error {
55
56
  /** Stable machine code for programmatic branching. */
@@ -124,7 +125,12 @@ var ContentVerificationError = class extends CairnError {
124
125
  this.expected = expected;
125
126
  }
126
127
  };
127
- function mapProviderError(error) {
128
+ var NATIVE_CODES = /* @__PURE__ */ new Set(["ACCOUNT_CHANGED", "FIRST_PARTY_ONLY", "RATE_LIMITED", "APPROVAL_CLOSED", "FORBIDDEN", "INTERNAL"]);
129
+ function mapProviderError(error, code) {
130
+ if (code === "USER_REJECTED" || code === "APPROVAL_CLOSED") return new UserRejectedError(error);
131
+ if (code === "WALLET_LOCKED") return new WalletLockedError(error);
132
+ if (code === "UNSUPPORTED_METHOD" || code === "UNKNOWN_KIND") return new UnsupportedMethodError(error);
133
+ if (code && NATIVE_CODES.has(code)) return new CairnError(error || code, { code });
128
134
  const e = String(error || "").toLowerCase();
129
135
  if (e.includes("rejected by user")) return new UserRejectedError(error);
130
136
  if (e.includes("wallet locked")) return new WalletLockedError(error);
@@ -179,6 +185,7 @@ var Http = class {
179
185
  timeoutMs;
180
186
  maxBytes;
181
187
  headers;
188
+ retries;
182
189
  constructor(opts) {
183
190
  this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
184
191
  const f = opts.fetch ?? globalThis.fetch;
@@ -187,6 +194,7 @@ var Http = class {
187
194
  this.timeoutMs = opts.timeoutMs ?? 15e3;
188
195
  this.maxBytes = opts.maxBytes ?? DEFAULT_MAX_BYTES;
189
196
  this.headers = opts.headers ?? {};
197
+ this.retries = Math.min(10, Math.max(0, Math.floor(opts.retries ?? 0)));
190
198
  }
191
199
  /** Build an absolute URL from a path + optional query params. */
192
200
  url(path, query) {
@@ -223,15 +231,38 @@ var Http = class {
223
231
  clearTimeout(timer);
224
232
  }
225
233
  }
234
+ // A malformed 2xx body must surface as a TYPED HttpError, not a leaked SyntaxError (B10: dApp
235
+ // code branches on `instanceof CairnError`; a raw parse error escaped that contract).
236
+ parseJson(res, text, url) {
237
+ try {
238
+ return JSON.parse(text);
239
+ } catch (e) {
240
+ throw new HttpError(res.status, url, `invalid JSON body: ${text.slice(0, 120)}`);
241
+ }
242
+ }
226
243
  async getJson(path, query) {
227
- const res = await this.raw("GET", path, { query });
228
- if (!res.ok) throw new HttpError(res.status, this.url(path, query), await safeText(res));
229
- return JSON.parse(new TextDecoder().decode(await readCapped(res, this.maxBytes)));
244
+ const url = this.url(path, query);
245
+ for (let attempt = 0; ; attempt++) {
246
+ try {
247
+ const res = await this.raw("GET", path, { query });
248
+ if (!res.ok) {
249
+ const err = new HttpError(res.status, url, await safeText(res));
250
+ if (!(res.status >= 500 && attempt < this.retries)) throw err;
251
+ } else {
252
+ return this.parseJson(res, new TextDecoder().decode(await readCapped(res, this.maxBytes)), url);
253
+ }
254
+ } catch (e) {
255
+ if (e instanceof HttpError && e.status < 500) throw e;
256
+ if (attempt >= this.retries) throw e;
257
+ }
258
+ await new Promise((r) => setTimeout(r, Math.floor(Math.random() * Math.min(4e3, 250 * 2 ** attempt))));
259
+ }
230
260
  }
231
261
  async postJson(path, body, headers) {
262
+ const url = this.url(path);
232
263
  const res = await this.raw("POST", path, { body, headers });
233
- if (!res.ok) throw new HttpError(res.status, this.url(path), await safeText(res));
234
- return JSON.parse(new TextDecoder().decode(await readCapped(res, this.maxBytes)));
264
+ if (!res.ok) throw new HttpError(res.status, url, await safeText(res));
265
+ return this.parseJson(res, new TextDecoder().decode(await readCapped(res, this.maxBytes)), url);
235
266
  }
236
267
  /** GET raw bytes (for content retrieval). Returns null on 404. */
237
268
  async getBytes(path) {
@@ -690,7 +721,7 @@ var IndexerClient = class {
690
721
  handlers.onError?.(err);
691
722
  }
692
723
  if (closed) return;
693
- await new Promise((r) => setTimeout(r, 2e3));
724
+ await new Promise((r) => setTimeout(r, 1e3 + Math.floor(Math.random() * 2e3)));
694
725
  }
695
726
  };
696
727
  void run();
@@ -840,6 +871,96 @@ var RegistryClient = class {
840
871
  }
841
872
  };
842
873
 
874
+ // src/names.ts
875
+ var import_cairnx_core = require("@inversealtruism/cairnx-core");
876
+ var nameOk = (n) => typeof n === "string" && import_cairnx_core.NAME_RE.test(n) && !import_cairnx_core.RESERVED_NAMES.has(n);
877
+ var NamesClient = class {
878
+ constructor(http) {
879
+ this.http = http;
880
+ }
881
+ http;
882
+ /** Resolve a .csd name for DISPLAY (server-trusted; see the module trust note). null = unknown/invalid name. */
883
+ async resolve(name) {
884
+ if (!nameOk(name)) return null;
885
+ try {
886
+ return await this.http.getJson(`/trade/api/cairnx/resolve/${name}`);
887
+ } catch (e) {
888
+ if (e?.status === 404) return null;
889
+ throw e;
890
+ }
891
+ }
892
+ /** Full detail for one name (lease, lock, resting offer, recapture). null = not registered/invalid. */
893
+ async name(name) {
894
+ if (!nameOk(name)) return null;
895
+ try {
896
+ return await this.http.getJson(`/trade/api/cairnx/name/${name}`);
897
+ } catch (e) {
898
+ if (e?.status === 404) return null;
899
+ throw e;
900
+ }
901
+ }
902
+ /** The event history of one name (registrations, transfers, sets, renewals). null = invalid name. */
903
+ async nameHistory(name) {
904
+ if (!nameOk(name)) return null;
905
+ try {
906
+ return await this.http.getJson(`/trade/api/cairnx/name-history/${name}`);
907
+ } catch (e) {
908
+ if (e?.status === 404) return null;
909
+ throw e;
910
+ }
911
+ }
912
+ /** Reverse lookup: an address's chosen primary .csd name (null name = none set). */
913
+ async primary(addr) {
914
+ if (typeof addr !== "string" || !/^0x[0-9a-fA-F]{40}$/.test(addr)) return null;
915
+ try {
916
+ return await this.http.getJson(`/trade/api/cairnx/primary/${addr.toLowerCase()}`);
917
+ } catch (e) {
918
+ if (e?.status === 404) return null;
919
+ throw e;
920
+ }
921
+ }
922
+ /** All names an address owns (plus its primary), as served by `/cairnx/address/:addr`. */
923
+ async namesOf(addr) {
924
+ if (typeof addr !== "string" || !/^0x[0-9a-fA-F]{40}$/.test(addr)) return null;
925
+ try {
926
+ return await this.http.getJson(`/trade/api/cairnx/address/${addr.toLowerCase()}`);
927
+ } catch (e) {
928
+ if (e?.status === 404) return null;
929
+ throw e;
930
+ }
931
+ }
932
+ /** All registered names (display list; short-edge-cached server-side). */
933
+ names() {
934
+ return this.http.getJson(`/trade/api/cairnx/names`);
935
+ }
936
+ /** All deployed tokens. */
937
+ tokens() {
938
+ return this.http.getJson(`/trade/api/cairnx/tokens`);
939
+ }
940
+ /** One token by ticker. null = unknown/invalid ticker. */
941
+ async token(ticker) {
942
+ if (typeof ticker !== "string" || !/^[A-Z][A-Z0-9]{2,11}$/.test(ticker)) return null;
943
+ try {
944
+ return await this.http.getJson(`/trade/api/cairnx/token/${ticker}`);
945
+ } catch (e) {
946
+ if (e?.status === 404) return null;
947
+ throw e;
948
+ }
949
+ }
950
+ /** Open offers (the market's display list). */
951
+ offers() {
952
+ return this.http.getJson(`/trade/api/cairnx/offers`);
953
+ }
954
+ /** Open bids. */
955
+ bids() {
956
+ return this.http.getJson(`/trade/api/cairnx/bids`);
957
+ }
958
+ /** The full canonical CairnX state (large; prefer the scoped reads above). */
959
+ state() {
960
+ return this.http.getJson(`/trade/api/cairnx/state`);
961
+ }
962
+ };
963
+
843
964
  // src/connect.ts
844
965
  function discoverProviders(opts = {}) {
845
966
  const timeoutMs = opts.timeoutMs ?? 1e3;
@@ -908,7 +1029,7 @@ function isInstalled() {
908
1029
  }
909
1030
  function unwrap(reply) {
910
1031
  if (reply && reply.ok) return reply.result;
911
- throw mapProviderError(reply?.error ?? "Unknown wallet error");
1032
+ throw mapProviderError(reply?.error ?? "Unknown wallet error", reply?.code);
912
1033
  }
913
1034
  var WalletConnection = class {
914
1035
  provider;
@@ -942,6 +1063,9 @@ var WalletConnection = class {
942
1063
  * Passwordless sign-in: a signature over a login nonce (always prompts; structurally cannot sign a tx).
943
1064
  */
944
1065
  signIn() {
1066
+ if (typeof this.provider.signIn !== "function") {
1067
+ return Promise.reject(new UnsupportedMethodError("this wallet does not expose signIn()"));
1068
+ }
945
1069
  return Promise.resolve(this.provider.signIn()).then(unwrap);
946
1070
  }
947
1071
  /**
@@ -975,6 +1099,9 @@ var WalletConnection = class {
975
1099
  }
976
1100
  /** Atomic fill (CairnX DvP): pay + attest in ONE tx. Always prompts with clear-signing. */
977
1101
  fillOffer(params) {
1102
+ if (typeof this.provider.fillOffer !== "function") {
1103
+ return Promise.reject(new UnsupportedMethodError("this wallet predates fillOffer() \u2014 ask the user to update the Cairn Wallet"));
1104
+ }
978
1105
  return Promise.resolve(this.provider.fillOffer(params)).then(unwrap);
979
1106
  }
980
1107
  /** This origin's current permission grant (EIP-2255-style). Silent; [] if none / unsupported. */
@@ -1129,7 +1256,7 @@ var CairnController = class {
1129
1256
  };
1130
1257
 
1131
1258
  // src/index.ts
1132
- var DEFAULT_SPV_CHECKPOINT = { height: 31310, hash: "0x000000000000138bd3eee4b8d2fbacb8d5433ac3040ddbf1c45a5e3e0cc9e814" };
1259
+ var DEFAULT_SPV_CHECKPOINT = { height: 38142, hash: "0x00000000000140f023cc0ee1457a40833f2fcb4de44291b9d373e50f17b97232" };
1133
1260
  var DEFAULT_CAIRN = "https://cairn-substrate.com";
1134
1261
  var Cairn = class {
1135
1262
  config;
@@ -1137,6 +1264,8 @@ var Cairn = class {
1137
1264
  index;
1138
1265
  content;
1139
1266
  registry;
1267
+ /** .csd names + CairnX market READS (server-trusted display reads; see names.ts trust note). */
1268
+ names;
1140
1269
  board;
1141
1270
  wallet;
1142
1271
  cairnHttp;
@@ -1165,6 +1294,7 @@ var Cairn = class {
1165
1294
  });
1166
1295
  this.content = new ContentClient({ swarm: swarmHttp, indexer: indexerHttp, cairn: this.cairnHttp });
1167
1296
  this.registry = new RegistryClient({ baseUrl: indexer, fetch });
1297
+ this.names = new NamesClient(this.cairnHttp);
1168
1298
  }
1169
1299
  /**
1170
1300
  * PoW-VERIFIED header merkle at a height (audit M3 — the no-PoW half). Lazily seeds a light
@@ -1221,6 +1351,7 @@ var Cairn = class {
1221
1351
  Http,
1222
1352
  HttpError,
1223
1353
  IndexerClient,
1354
+ NamesClient,
1224
1355
  NotInstalledError,
1225
1356
  RegistryClient,
1226
1357
  SDK_VERSION,
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FetchLike } from './http-CQsNL8w9.cjs';
2
- export { H as Http, a as HttpOptions } from './http-CQsNL8w9.cjs';
1
+ import { H as Http, F as FetchLike } from './http-C9C4L4hz.cjs';
2
+ export { a as HttpOptions } from './http-C9C4L4hz.cjs';
3
3
  import { Chain } from './chain.cjs';
4
4
  import { BoardClient } from './board.cjs';
5
5
  export { BoardItemContent, BoardWindow, ProposeInput, ProposeResult, RankedItem, SupportInput } from './board.cjs';
@@ -18,9 +18,95 @@ import '@inversealtruism/csd-crypto';
18
18
  import '@inversealtruism/csd-light';
19
19
  import '@inversealtruism/csd-registry';
20
20
 
21
+ /** `/cairnx/resolve/:name` — the display-path name→address resolution. */
22
+ interface NameResolution {
23
+ ok: boolean;
24
+ name: string;
25
+ /** Resolved recipient address (owner, or the nset target). ABSENT/undefined when not resolvable. */
26
+ addr?: string;
27
+ /** How the address was derived (e.g. "owner", "nset"). */
28
+ via?: string;
29
+ lapsed?: boolean;
30
+ owner?: string;
31
+ tipHeight?: number;
32
+ }
33
+ /** `/cairnx/name/:name` — full name detail (lease, lock, resting offer, recapture window). */
34
+ interface NameDetail {
35
+ name: string;
36
+ owner: string;
37
+ claimId: string;
38
+ height: number;
39
+ effectiveHeight: number;
40
+ locked: boolean;
41
+ paidThroughEpoch: number;
42
+ offer: unknown | null;
43
+ recapture: unknown | null;
44
+ tipHeight: number;
45
+ tipEpoch: number;
46
+ /** v2.5+: a revealed-but-unfinalized registration (no lease yet; not actionable). */
47
+ pending?: boolean;
48
+ lease: {
49
+ leased: boolean;
50
+ paidThroughEpoch: number;
51
+ graceEndEpoch: number;
52
+ epochsLeft: number;
53
+ graceEpochsLeft: number;
54
+ inGrace: boolean;
55
+ lapsed: boolean;
56
+ } | null;
57
+ }
58
+ /** One row of `/cairnx/tokens`. Amounts are DECIMAL STRINGS of base units (may exceed 2^53). */
59
+ interface TokenInfo {
60
+ ticker: string;
61
+ deployId: string;
62
+ deployer: string;
63
+ name?: string;
64
+ decimals: number;
65
+ supply: string;
66
+ minted: string;
67
+ mint?: string;
68
+ mintLimit?: string;
69
+ height: number;
70
+ }
71
+ interface PrimaryName {
72
+ ok: boolean;
73
+ address: string;
74
+ name?: string | null;
75
+ }
76
+ /**
77
+ * Read client for the CairnX convention (names + token market) over a Cairn front door.
78
+ * Construct via the main `Cairn` class (`cairn.names`); all methods are read-only.
79
+ */
80
+ declare class NamesClient {
81
+ private readonly http;
82
+ constructor(http: Http);
83
+ /** Resolve a .csd name for DISPLAY (server-trusted; see the module trust note). null = unknown/invalid name. */
84
+ resolve(name: string): Promise<NameResolution | null>;
85
+ /** Full detail for one name (lease, lock, resting offer, recapture). null = not registered/invalid. */
86
+ name(name: string): Promise<NameDetail | null>;
87
+ /** The event history of one name (registrations, transfers, sets, renewals). null = invalid name. */
88
+ nameHistory(name: string): Promise<unknown[] | null>;
89
+ /** Reverse lookup: an address's chosen primary .csd name (null name = none set). */
90
+ primary(addr: string): Promise<PrimaryName | null>;
91
+ /** All names an address owns (plus its primary), as served by `/cairnx/address/:addr`. */
92
+ namesOf(addr: string): Promise<unknown | null>;
93
+ /** All registered names (display list; short-edge-cached server-side). */
94
+ names(): Promise<unknown[]>;
95
+ /** All deployed tokens. */
96
+ tokens(): Promise<TokenInfo[]>;
97
+ /** One token by ticker. null = unknown/invalid ticker. */
98
+ token(ticker: string): Promise<TokenInfo | null>;
99
+ /** Open offers (the market's display list). */
100
+ offers(): Promise<unknown[]>;
101
+ /** Open bids. */
102
+ bids(): Promise<unknown[]>;
103
+ /** The full canonical CairnX state (large; prefer the scoped reads above). */
104
+ state(): Promise<unknown>;
105
+ }
106
+
21
107
  /** Stable machine-readable error codes (branch on these, not the message text). */
22
- type CairnErrorCode = "NOT_INSTALLED" | "USER_REJECTED" | "WALLET_LOCKED" | "UNSUPPORTED_METHOD" | "HTTP_ERROR" | "CONTENT_VERIFICATION" | "UNKNOWN";
23
- declare const SDK_VERSION = "0.1.4";
108
+ type CairnErrorCode = "NOT_INSTALLED" | "USER_REJECTED" | "WALLET_LOCKED" | "UNSUPPORTED_METHOD" | "HTTP_ERROR" | "CONTENT_VERIFICATION" | "ACCOUNT_CHANGED" | "FIRST_PARTY_ONLY" | "RATE_LIMITED" | "APPROVAL_CLOSED" | "FORBIDDEN" | "INTERNAL" | "UNKNOWN";
109
+ declare const SDK_VERSION = "0.2.0";
24
110
  interface CairnErrorOptions {
25
111
  code?: CairnErrorCode;
26
112
  docsPath?: string;
@@ -34,7 +120,7 @@ declare class CairnError extends Error {
34
120
  /** Relative docs path (under the SDK docs base), if any. */
35
121
  readonly docsPath?: string;
36
122
  /** The cairn-sdk version that produced this error. */
37
- readonly version = "0.1.4";
123
+ readonly version = "0.2.0";
38
124
  constructor(shortMessage: string, opts?: CairnErrorOptions);
39
125
  /**
40
126
  * Walk the `cause` chain. With a predicate, returns the FIRST matching error (or null). Without one,
@@ -70,11 +156,7 @@ declare class ContentVerificationError extends CairnError {
70
156
  expected: string;
71
157
  constructor(expected: string);
72
158
  }
73
- /**
74
- * Map a provider error string (from the wallet's `{ ok:false, error }`) onto a typed error. The
75
- * wallet's strings are stable: "rejected by user", "wallet locked", "unsupported dApp method: …".
76
- */
77
- declare function mapProviderError(error: string): CairnError;
159
+ declare function mapProviderError(error: string, code?: string): CairnError;
78
160
  /** Convenience: the stable code of any error (or "UNKNOWN" for a non-CairnError). */
79
161
  declare function errorCode(err: unknown): CairnErrorCode;
80
162
 
@@ -132,6 +214,8 @@ declare class Cairn {
132
214
  readonly index: IndexerClient;
133
215
  readonly content: ContentClient;
134
216
  readonly registry: RegistryClient;
217
+ /** .csd names + CairnX market READS (server-trusted display reads; see names.ts trust note). */
218
+ readonly names: NamesClient;
135
219
  board: BoardClient;
136
220
  wallet?: WalletConnection;
137
221
  private readonly cairnHttp;
@@ -159,4 +243,4 @@ declare class Cairn {
159
243
  get connected(): boolean;
160
244
  }
161
245
 
162
- export { BoardClient, Cairn, type CairnBaseUrls, type CairnConfig, CairnError, type CairnErrorCode, type CairnErrorOptions, Chain, ContentClient, ContentVerificationError, DEFAULT_SPV_CHECKPOINT, DetectOptions, FetchLike, HttpError, IndexerClient, NotInstalledError, RegistryClient, SDK_VERSION, UnsupportedMethodError, UserRejectedError, WalletConnection, WalletLockedError, errorCode, mapProviderError };
246
+ export { BoardClient, Cairn, type CairnBaseUrls, type CairnConfig, CairnError, type CairnErrorCode, type CairnErrorOptions, Chain, ContentClient, ContentVerificationError, DEFAULT_SPV_CHECKPOINT, DetectOptions, FetchLike, Http, HttpError, IndexerClient, type NameDetail, type NameResolution, NamesClient, NotInstalledError, type PrimaryName, RegistryClient, SDK_VERSION, type TokenInfo, UnsupportedMethodError, UserRejectedError, WalletConnection, WalletLockedError, errorCode, mapProviderError };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FetchLike } from './http-CQsNL8w9.js';
2
- export { H as Http, a as HttpOptions } from './http-CQsNL8w9.js';
1
+ import { H as Http, F as FetchLike } from './http-C9C4L4hz.js';
2
+ export { a as HttpOptions } from './http-C9C4L4hz.js';
3
3
  import { Chain } from './chain.js';
4
4
  import { BoardClient } from './board.js';
5
5
  export { BoardItemContent, BoardWindow, ProposeInput, ProposeResult, RankedItem, SupportInput } from './board.js';
@@ -18,9 +18,95 @@ import '@inversealtruism/csd-crypto';
18
18
  import '@inversealtruism/csd-light';
19
19
  import '@inversealtruism/csd-registry';
20
20
 
21
+ /** `/cairnx/resolve/:name` — the display-path name→address resolution. */
22
+ interface NameResolution {
23
+ ok: boolean;
24
+ name: string;
25
+ /** Resolved recipient address (owner, or the nset target). ABSENT/undefined when not resolvable. */
26
+ addr?: string;
27
+ /** How the address was derived (e.g. "owner", "nset"). */
28
+ via?: string;
29
+ lapsed?: boolean;
30
+ owner?: string;
31
+ tipHeight?: number;
32
+ }
33
+ /** `/cairnx/name/:name` — full name detail (lease, lock, resting offer, recapture window). */
34
+ interface NameDetail {
35
+ name: string;
36
+ owner: string;
37
+ claimId: string;
38
+ height: number;
39
+ effectiveHeight: number;
40
+ locked: boolean;
41
+ paidThroughEpoch: number;
42
+ offer: unknown | null;
43
+ recapture: unknown | null;
44
+ tipHeight: number;
45
+ tipEpoch: number;
46
+ /** v2.5+: a revealed-but-unfinalized registration (no lease yet; not actionable). */
47
+ pending?: boolean;
48
+ lease: {
49
+ leased: boolean;
50
+ paidThroughEpoch: number;
51
+ graceEndEpoch: number;
52
+ epochsLeft: number;
53
+ graceEpochsLeft: number;
54
+ inGrace: boolean;
55
+ lapsed: boolean;
56
+ } | null;
57
+ }
58
+ /** One row of `/cairnx/tokens`. Amounts are DECIMAL STRINGS of base units (may exceed 2^53). */
59
+ interface TokenInfo {
60
+ ticker: string;
61
+ deployId: string;
62
+ deployer: string;
63
+ name?: string;
64
+ decimals: number;
65
+ supply: string;
66
+ minted: string;
67
+ mint?: string;
68
+ mintLimit?: string;
69
+ height: number;
70
+ }
71
+ interface PrimaryName {
72
+ ok: boolean;
73
+ address: string;
74
+ name?: string | null;
75
+ }
76
+ /**
77
+ * Read client for the CairnX convention (names + token market) over a Cairn front door.
78
+ * Construct via the main `Cairn` class (`cairn.names`); all methods are read-only.
79
+ */
80
+ declare class NamesClient {
81
+ private readonly http;
82
+ constructor(http: Http);
83
+ /** Resolve a .csd name for DISPLAY (server-trusted; see the module trust note). null = unknown/invalid name. */
84
+ resolve(name: string): Promise<NameResolution | null>;
85
+ /** Full detail for one name (lease, lock, resting offer, recapture). null = not registered/invalid. */
86
+ name(name: string): Promise<NameDetail | null>;
87
+ /** The event history of one name (registrations, transfers, sets, renewals). null = invalid name. */
88
+ nameHistory(name: string): Promise<unknown[] | null>;
89
+ /** Reverse lookup: an address's chosen primary .csd name (null name = none set). */
90
+ primary(addr: string): Promise<PrimaryName | null>;
91
+ /** All names an address owns (plus its primary), as served by `/cairnx/address/:addr`. */
92
+ namesOf(addr: string): Promise<unknown | null>;
93
+ /** All registered names (display list; short-edge-cached server-side). */
94
+ names(): Promise<unknown[]>;
95
+ /** All deployed tokens. */
96
+ tokens(): Promise<TokenInfo[]>;
97
+ /** One token by ticker. null = unknown/invalid ticker. */
98
+ token(ticker: string): Promise<TokenInfo | null>;
99
+ /** Open offers (the market's display list). */
100
+ offers(): Promise<unknown[]>;
101
+ /** Open bids. */
102
+ bids(): Promise<unknown[]>;
103
+ /** The full canonical CairnX state (large; prefer the scoped reads above). */
104
+ state(): Promise<unknown>;
105
+ }
106
+
21
107
  /** Stable machine-readable error codes (branch on these, not the message text). */
22
- type CairnErrorCode = "NOT_INSTALLED" | "USER_REJECTED" | "WALLET_LOCKED" | "UNSUPPORTED_METHOD" | "HTTP_ERROR" | "CONTENT_VERIFICATION" | "UNKNOWN";
23
- declare const SDK_VERSION = "0.1.4";
108
+ type CairnErrorCode = "NOT_INSTALLED" | "USER_REJECTED" | "WALLET_LOCKED" | "UNSUPPORTED_METHOD" | "HTTP_ERROR" | "CONTENT_VERIFICATION" | "ACCOUNT_CHANGED" | "FIRST_PARTY_ONLY" | "RATE_LIMITED" | "APPROVAL_CLOSED" | "FORBIDDEN" | "INTERNAL" | "UNKNOWN";
109
+ declare const SDK_VERSION = "0.2.0";
24
110
  interface CairnErrorOptions {
25
111
  code?: CairnErrorCode;
26
112
  docsPath?: string;
@@ -34,7 +120,7 @@ declare class CairnError extends Error {
34
120
  /** Relative docs path (under the SDK docs base), if any. */
35
121
  readonly docsPath?: string;
36
122
  /** The cairn-sdk version that produced this error. */
37
- readonly version = "0.1.4";
123
+ readonly version = "0.2.0";
38
124
  constructor(shortMessage: string, opts?: CairnErrorOptions);
39
125
  /**
40
126
  * Walk the `cause` chain. With a predicate, returns the FIRST matching error (or null). Without one,
@@ -70,11 +156,7 @@ declare class ContentVerificationError extends CairnError {
70
156
  expected: string;
71
157
  constructor(expected: string);
72
158
  }
73
- /**
74
- * Map a provider error string (from the wallet's `{ ok:false, error }`) onto a typed error. The
75
- * wallet's strings are stable: "rejected by user", "wallet locked", "unsupported dApp method: …".
76
- */
77
- declare function mapProviderError(error: string): CairnError;
159
+ declare function mapProviderError(error: string, code?: string): CairnError;
78
160
  /** Convenience: the stable code of any error (or "UNKNOWN" for a non-CairnError). */
79
161
  declare function errorCode(err: unknown): CairnErrorCode;
80
162
 
@@ -132,6 +214,8 @@ declare class Cairn {
132
214
  readonly index: IndexerClient;
133
215
  readonly content: ContentClient;
134
216
  readonly registry: RegistryClient;
217
+ /** .csd names + CairnX market READS (server-trusted display reads; see names.ts trust note). */
218
+ readonly names: NamesClient;
135
219
  board: BoardClient;
136
220
  wallet?: WalletConnection;
137
221
  private readonly cairnHttp;
@@ -159,4 +243,4 @@ declare class Cairn {
159
243
  get connected(): boolean;
160
244
  }
161
245
 
162
- export { BoardClient, Cairn, type CairnBaseUrls, type CairnConfig, CairnError, type CairnErrorCode, type CairnErrorOptions, Chain, ContentClient, ContentVerificationError, DEFAULT_SPV_CHECKPOINT, DetectOptions, FetchLike, HttpError, IndexerClient, NotInstalledError, RegistryClient, SDK_VERSION, UnsupportedMethodError, UserRejectedError, WalletConnection, WalletLockedError, errorCode, mapProviderError };
246
+ export { BoardClient, Cairn, type CairnBaseUrls, type CairnConfig, CairnError, type CairnErrorCode, type CairnErrorOptions, Chain, ContentClient, ContentVerificationError, DEFAULT_SPV_CHECKPOINT, DetectOptions, FetchLike, Http, HttpError, IndexerClient, type NameDetail, type NameResolution, NamesClient, NotInstalledError, type PrimaryName, RegistryClient, SDK_VERSION, type TokenInfo, UnsupportedMethodError, UserRejectedError, WalletConnection, WalletLockedError, errorCode, mapProviderError };