@inversealtruism/cairn-sdk 0.1.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.
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/connect.ts
21
+ var connect_exports = {};
22
+ __export(connect_exports, {
23
+ WalletConnection: () => WalletConnection,
24
+ connect: () => connect,
25
+ detectProvider: () => detectProvider,
26
+ getWallet: () => getWallet,
27
+ isInstalled: () => isInstalled
28
+ });
29
+ module.exports = __toCommonJS(connect_exports);
30
+
31
+ // src/errors.ts
32
+ var CairnError = class extends Error {
33
+ constructor(message) {
34
+ super(message);
35
+ this.name = new.target.name;
36
+ }
37
+ };
38
+ var NotInstalledError = class extends CairnError {
39
+ constructor(message = "Cairn Wallet not detected. Install it from cairn-substrate.com.") {
40
+ super(message);
41
+ }
42
+ };
43
+ var UserRejectedError = class extends CairnError {
44
+ constructor(message = "Request rejected by user.") {
45
+ super(message);
46
+ }
47
+ };
48
+ var WalletLockedError = class extends CairnError {
49
+ constructor(message = "Wallet is locked.") {
50
+ super(message);
51
+ }
52
+ };
53
+ var UnsupportedMethodError = class extends CairnError {
54
+ constructor(message = "Method not supported by the wallet.") {
55
+ super(message);
56
+ }
57
+ };
58
+ function mapProviderError(error) {
59
+ const e = String(error || "").toLowerCase();
60
+ if (e.includes("rejected by user")) return new UserRejectedError(error);
61
+ if (e.includes("wallet locked")) return new WalletLockedError(error);
62
+ if (e.includes("unsupported dapp method")) return new UnsupportedMethodError(error);
63
+ return new CairnError(error || "Unknown wallet error");
64
+ }
65
+
66
+ // src/connect.ts
67
+ function detectProvider(opts = {}) {
68
+ const timeoutMs = opts.timeoutMs ?? 3e3;
69
+ return new Promise((resolve, reject) => {
70
+ if (typeof window === "undefined") {
71
+ reject(new NotInstalledError("Not running in a browser \u2014 `window.cairn` is unavailable."));
72
+ return;
73
+ }
74
+ if (window.cairn?.isCairn) {
75
+ resolve(window.cairn);
76
+ return;
77
+ }
78
+ let done = false;
79
+ const onInit = () => {
80
+ if (done) return;
81
+ if (window.cairn?.isCairn) {
82
+ done = true;
83
+ cleanup();
84
+ resolve(window.cairn);
85
+ }
86
+ };
87
+ const timer = setTimeout(() => {
88
+ if (done) return;
89
+ done = true;
90
+ cleanup();
91
+ reject(new NotInstalledError());
92
+ }, timeoutMs);
93
+ const cleanup = () => {
94
+ clearTimeout(timer);
95
+ window.removeEventListener("cairn#initialized", onInit);
96
+ };
97
+ window.addEventListener("cairn#initialized", onInit);
98
+ onInit();
99
+ });
100
+ }
101
+ function isInstalled() {
102
+ return typeof window !== "undefined" && !!window.cairn?.isCairn;
103
+ }
104
+ function unwrap(reply) {
105
+ if (reply && reply.ok) return reply.result;
106
+ throw mapProviderError(reply?.error ?? "Unknown wallet error");
107
+ }
108
+ var WalletConnection = class {
109
+ provider;
110
+ _addr = null;
111
+ constructor(provider) {
112
+ this.provider = provider;
113
+ }
114
+ /** The wallet's version string (e.g. "0.2.x"). */
115
+ get version() {
116
+ return this.provider.version;
117
+ }
118
+ /** The connected address, if `connect()`/`getAddress()` has resolved. */
119
+ get address() {
120
+ return this._addr;
121
+ }
122
+ /** Request connection. First time per origin prompts the user; afterwards may be silent. */
123
+ async connect() {
124
+ const { addr } = unwrap(await this.provider.connect());
125
+ this._addr = addr;
126
+ return addr;
127
+ }
128
+ /** Get the connected address (does not force a new connection prompt if already consented). */
129
+ async getAddress() {
130
+ const { addr } = unwrap(await this.provider.getAddress());
131
+ this._addr = addr;
132
+ return addr;
133
+ }
134
+ /** Passwordless sign-in: a signature over a login nonce (always prompts; structurally cannot sign a tx). */
135
+ signIn() {
136
+ return Promise.resolve(this.provider.signIn()).then(unwrap);
137
+ }
138
+ /** Send CSD (always prompts with clear-signing; wallet picks inputs + returns change to itself). */
139
+ send(params) {
140
+ return Promise.resolve(this.provider.send(params)).then(unwrap);
141
+ }
142
+ /** Low-level Propose (always prompts). Prefer `cairn.board.propose()` which computes the hash/uri/expiry. */
143
+ propose(params) {
144
+ return Promise.resolve(this.provider.propose(params)).then(unwrap);
145
+ }
146
+ /** Attest/support a proposal (always prompts). */
147
+ attest(params) {
148
+ return Promise.resolve(this.provider.attest(params)).then(unwrap);
149
+ }
150
+ /** Seal a commit-reveal claim (always prompts; salt stays inside the wallet). */
151
+ sealClaim(params) {
152
+ return Promise.resolve(this.provider.sealClaim(params)).then(unwrap);
153
+ }
154
+ /** Reveal a previously sealed claim by its sealing txid (always prompts). */
155
+ revealClaim(txid) {
156
+ if (typeof txid !== "string" || !txid) {
157
+ return Promise.reject(new UnsupportedMethodError("revealClaim requires the sealing txid"));
158
+ }
159
+ return Promise.resolve(this.provider.revealClaim(txid)).then(unwrap);
160
+ }
161
+ };
162
+ async function getWallet(opts = {}) {
163
+ return new WalletConnection(await detectProvider(opts));
164
+ }
165
+ async function connect(opts = {}) {
166
+ const wallet = await getWallet(opts);
167
+ const address = await wallet.connect();
168
+ return { wallet, address };
169
+ }
170
+ // Annotate the CommonJS export names for ESM import in node:
171
+ 0 && (module.exports = {
172
+ WalletConnection,
173
+ connect,
174
+ detectProvider,
175
+ getWallet,
176
+ isInstalled
177
+ });
@@ -0,0 +1,127 @@
1
+ /** Result of `connect()` / `getAddress()`. */
2
+ interface ConnectResult {
3
+ addr: string;
4
+ }
5
+ /** Generic on-chain submit result returned by signing methods (shape from the node/proxy). */
6
+ interface TxResult {
7
+ ok?: boolean;
8
+ txid?: string;
9
+ [k: string]: unknown;
10
+ }
11
+ /** Sign-in (passwordless auth) result — a signature over a login nonce, never a tx sighash. */
12
+ interface SignInResult {
13
+ addr?: string;
14
+ pub33?: string;
15
+ sig64?: string;
16
+ nonce?: string;
17
+ [k: string]: unknown;
18
+ }
19
+ /** Low-level Propose params (matches the wallet exactly). Prefer `cairn.board.propose()` for ergonomics. */
20
+ interface ProposeParams {
21
+ domain: string;
22
+ payloadHash: string;
23
+ uri: string;
24
+ expiresEpoch: number;
25
+ fee: number;
26
+ }
27
+ /** Attest (support) params. */
28
+ interface AttestParams {
29
+ proposalId: string;
30
+ score: number;
31
+ confidence: number;
32
+ fee: number;
33
+ }
34
+ /** Plain CSD transfer. The wallet always selects its own inputs and returns change to itself. */
35
+ type SendParams = {
36
+ to: string;
37
+ amount: number;
38
+ fee?: number;
39
+ } | {
40
+ outputs: {
41
+ to: string;
42
+ value: number;
43
+ }[];
44
+ fee?: number;
45
+ };
46
+ /** Commit-reveal sealed claim. The salt is generated inside the wallet and never leaves it. */
47
+ interface SealClaimParams {
48
+ domain?: string;
49
+ claim: string;
50
+ fee?: number;
51
+ }
52
+ /** The raw provider object the extension injects at `window.cairn`. */
53
+ interface CairnProvider {
54
+ isCairn: true;
55
+ version: string;
56
+ connect(): Promise<ProviderReply<ConnectResult>>;
57
+ getAddress(): Promise<ProviderReply<ConnectResult>>;
58
+ signIn(): Promise<ProviderReply<SignInResult>>;
59
+ propose(p: ProposeParams): Promise<ProviderReply<TxResult>>;
60
+ attest(p: AttestParams): Promise<ProviderReply<TxResult>>;
61
+ send(p: SendParams): Promise<ProviderReply<TxResult>>;
62
+ sealClaim(p: SealClaimParams): Promise<ProviderReply<TxResult>>;
63
+ revealClaim(txid: string): Promise<ProviderReply<TxResult>>;
64
+ }
65
+ /** Every provider call resolves to this discriminated reply (never rejects). */
66
+ type ProviderReply<T> = {
67
+ ok: true;
68
+ result: T;
69
+ } | {
70
+ ok: false;
71
+ error: string;
72
+ };
73
+ declare global {
74
+ interface Window {
75
+ cairn?: CairnProvider;
76
+ }
77
+ }
78
+ interface DetectOptions {
79
+ /** How long to wait for the provider to announce itself (ms, default 3000). */
80
+ timeoutMs?: number;
81
+ }
82
+ /**
83
+ * Resolve `window.cairn`, waiting for the wallet's `cairn#initialized` event if the
84
+ * content script hasn't injected yet. Throws `NotInstalledError` on timeout or
85
+ * outside a browser.
86
+ */
87
+ declare function detectProvider(opts?: DetectOptions): Promise<CairnProvider>;
88
+ /** True if the Cairn Wallet is already present (no waiting). */
89
+ declare function isInstalled(): boolean;
90
+ /**
91
+ * High-level, typed wallet handle. Construct via `connect()` or `new WalletConnection(provider)`.
92
+ * Methods throw `UserRejectedError` / `WalletLockedError` / `UnsupportedMethodError` on failure.
93
+ */
94
+ declare class WalletConnection {
95
+ readonly provider: CairnProvider;
96
+ private _addr;
97
+ constructor(provider: CairnProvider);
98
+ /** The wallet's version string (e.g. "0.2.x"). */
99
+ get version(): string;
100
+ /** The connected address, if `connect()`/`getAddress()` has resolved. */
101
+ get address(): string | null;
102
+ /** Request connection. First time per origin prompts the user; afterwards may be silent. */
103
+ connect(): Promise<string>;
104
+ /** Get the connected address (does not force a new connection prompt if already consented). */
105
+ getAddress(): Promise<string>;
106
+ /** Passwordless sign-in: a signature over a login nonce (always prompts; structurally cannot sign a tx). */
107
+ signIn(): Promise<SignInResult>;
108
+ /** Send CSD (always prompts with clear-signing; wallet picks inputs + returns change to itself). */
109
+ send(params: SendParams): Promise<TxResult>;
110
+ /** Low-level Propose (always prompts). Prefer `cairn.board.propose()` which computes the hash/uri/expiry. */
111
+ propose(params: ProposeParams): Promise<TxResult>;
112
+ /** Attest/support a proposal (always prompts). */
113
+ attest(params: AttestParams): Promise<TxResult>;
114
+ /** Seal a commit-reveal claim (always prompts; salt stays inside the wallet). */
115
+ sealClaim(params: SealClaimParams): Promise<TxResult>;
116
+ /** Reveal a previously sealed claim by its sealing txid (always prompts). */
117
+ revealClaim(txid: string): Promise<TxResult>;
118
+ }
119
+ /** Detect the wallet and return a ready `WalletConnection` (does not auto-call connect()). */
120
+ declare function getWallet(opts?: DetectOptions): Promise<WalletConnection>;
121
+ /** Detect + connect in one step; resolves to the connected address. */
122
+ declare function connect(opts?: DetectOptions): Promise<{
123
+ wallet: WalletConnection;
124
+ address: string;
125
+ }>;
126
+
127
+ export { type AttestParams, type CairnProvider, type ConnectResult, type DetectOptions, type ProposeParams, type ProviderReply, type SealClaimParams, type SendParams, type SignInResult, type TxResult, WalletConnection, connect, detectProvider, getWallet, isInstalled };
@@ -0,0 +1,127 @@
1
+ /** Result of `connect()` / `getAddress()`. */
2
+ interface ConnectResult {
3
+ addr: string;
4
+ }
5
+ /** Generic on-chain submit result returned by signing methods (shape from the node/proxy). */
6
+ interface TxResult {
7
+ ok?: boolean;
8
+ txid?: string;
9
+ [k: string]: unknown;
10
+ }
11
+ /** Sign-in (passwordless auth) result — a signature over a login nonce, never a tx sighash. */
12
+ interface SignInResult {
13
+ addr?: string;
14
+ pub33?: string;
15
+ sig64?: string;
16
+ nonce?: string;
17
+ [k: string]: unknown;
18
+ }
19
+ /** Low-level Propose params (matches the wallet exactly). Prefer `cairn.board.propose()` for ergonomics. */
20
+ interface ProposeParams {
21
+ domain: string;
22
+ payloadHash: string;
23
+ uri: string;
24
+ expiresEpoch: number;
25
+ fee: number;
26
+ }
27
+ /** Attest (support) params. */
28
+ interface AttestParams {
29
+ proposalId: string;
30
+ score: number;
31
+ confidence: number;
32
+ fee: number;
33
+ }
34
+ /** Plain CSD transfer. The wallet always selects its own inputs and returns change to itself. */
35
+ type SendParams = {
36
+ to: string;
37
+ amount: number;
38
+ fee?: number;
39
+ } | {
40
+ outputs: {
41
+ to: string;
42
+ value: number;
43
+ }[];
44
+ fee?: number;
45
+ };
46
+ /** Commit-reveal sealed claim. The salt is generated inside the wallet and never leaves it. */
47
+ interface SealClaimParams {
48
+ domain?: string;
49
+ claim: string;
50
+ fee?: number;
51
+ }
52
+ /** The raw provider object the extension injects at `window.cairn`. */
53
+ interface CairnProvider {
54
+ isCairn: true;
55
+ version: string;
56
+ connect(): Promise<ProviderReply<ConnectResult>>;
57
+ getAddress(): Promise<ProviderReply<ConnectResult>>;
58
+ signIn(): Promise<ProviderReply<SignInResult>>;
59
+ propose(p: ProposeParams): Promise<ProviderReply<TxResult>>;
60
+ attest(p: AttestParams): Promise<ProviderReply<TxResult>>;
61
+ send(p: SendParams): Promise<ProviderReply<TxResult>>;
62
+ sealClaim(p: SealClaimParams): Promise<ProviderReply<TxResult>>;
63
+ revealClaim(txid: string): Promise<ProviderReply<TxResult>>;
64
+ }
65
+ /** Every provider call resolves to this discriminated reply (never rejects). */
66
+ type ProviderReply<T> = {
67
+ ok: true;
68
+ result: T;
69
+ } | {
70
+ ok: false;
71
+ error: string;
72
+ };
73
+ declare global {
74
+ interface Window {
75
+ cairn?: CairnProvider;
76
+ }
77
+ }
78
+ interface DetectOptions {
79
+ /** How long to wait for the provider to announce itself (ms, default 3000). */
80
+ timeoutMs?: number;
81
+ }
82
+ /**
83
+ * Resolve `window.cairn`, waiting for the wallet's `cairn#initialized` event if the
84
+ * content script hasn't injected yet. Throws `NotInstalledError` on timeout or
85
+ * outside a browser.
86
+ */
87
+ declare function detectProvider(opts?: DetectOptions): Promise<CairnProvider>;
88
+ /** True if the Cairn Wallet is already present (no waiting). */
89
+ declare function isInstalled(): boolean;
90
+ /**
91
+ * High-level, typed wallet handle. Construct via `connect()` or `new WalletConnection(provider)`.
92
+ * Methods throw `UserRejectedError` / `WalletLockedError` / `UnsupportedMethodError` on failure.
93
+ */
94
+ declare class WalletConnection {
95
+ readonly provider: CairnProvider;
96
+ private _addr;
97
+ constructor(provider: CairnProvider);
98
+ /** The wallet's version string (e.g. "0.2.x"). */
99
+ get version(): string;
100
+ /** The connected address, if `connect()`/`getAddress()` has resolved. */
101
+ get address(): string | null;
102
+ /** Request connection. First time per origin prompts the user; afterwards may be silent. */
103
+ connect(): Promise<string>;
104
+ /** Get the connected address (does not force a new connection prompt if already consented). */
105
+ getAddress(): Promise<string>;
106
+ /** Passwordless sign-in: a signature over a login nonce (always prompts; structurally cannot sign a tx). */
107
+ signIn(): Promise<SignInResult>;
108
+ /** Send CSD (always prompts with clear-signing; wallet picks inputs + returns change to itself). */
109
+ send(params: SendParams): Promise<TxResult>;
110
+ /** Low-level Propose (always prompts). Prefer `cairn.board.propose()` which computes the hash/uri/expiry. */
111
+ propose(params: ProposeParams): Promise<TxResult>;
112
+ /** Attest/support a proposal (always prompts). */
113
+ attest(params: AttestParams): Promise<TxResult>;
114
+ /** Seal a commit-reveal claim (always prompts; salt stays inside the wallet). */
115
+ sealClaim(params: SealClaimParams): Promise<TxResult>;
116
+ /** Reveal a previously sealed claim by its sealing txid (always prompts). */
117
+ revealClaim(txid: string): Promise<TxResult>;
118
+ }
119
+ /** Detect the wallet and return a ready `WalletConnection` (does not auto-call connect()). */
120
+ declare function getWallet(opts?: DetectOptions): Promise<WalletConnection>;
121
+ /** Detect + connect in one step; resolves to the connected address. */
122
+ declare function connect(opts?: DetectOptions): Promise<{
123
+ wallet: WalletConnection;
124
+ address: string;
125
+ }>;
126
+
127
+ export { type AttestParams, type CairnProvider, type ConnectResult, type DetectOptions, type ProposeParams, type ProviderReply, type SealClaimParams, type SendParams, type SignInResult, type TxResult, WalletConnection, connect, detectProvider, getWallet, isInstalled };
@@ -0,0 +1,15 @@
1
+ import {
2
+ WalletConnection,
3
+ connect,
4
+ detectProvider,
5
+ getWallet,
6
+ isInstalled
7
+ } from "./chunk-SMAPCKVG.js";
8
+ import "./chunk-PHMU3CG5.js";
9
+ export {
10
+ WalletConnection,
11
+ connect,
12
+ detectProvider,
13
+ getWallet,
14
+ isInstalled
15
+ };
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/content.ts
21
+ var content_exports = {};
22
+ __export(content_exports, {
23
+ ContentClient: () => ContentClient
24
+ });
25
+ module.exports = __toCommonJS(content_exports);
26
+ var import_csd_codec = require("@inversealtruism/csd-codec");
27
+
28
+ // src/errors.ts
29
+ var CairnError = class extends Error {
30
+ constructor(message) {
31
+ super(message);
32
+ this.name = new.target.name;
33
+ }
34
+ };
35
+ var ContentVerificationError = class extends CairnError {
36
+ expected;
37
+ constructor(expected) {
38
+ super(`Content does not match its payload hash ${expected} \u2014 bytes were tampered with in transit.`);
39
+ this.expected = expected;
40
+ }
41
+ };
42
+
43
+ // src/content.ts
44
+ var ContentClient = class {
45
+ sources;
46
+ constructor(opts) {
47
+ this.sources = [];
48
+ if (opts.swarm) this.sources.push({ name: "swarm", http: opts.swarm, path: (h) => `/content/${h}` });
49
+ if (opts.indexer) this.sources.push({ name: "indexer", http: opts.indexer, path: (h) => `/content/${h}` });
50
+ if (opts.cairn) this.sources.push({ name: "cairn", http: opts.cairn, path: (h) => `/content/${h}` });
51
+ }
52
+ /**
53
+ * Compute the canonical hash + bytes for an object, ready to anchor on-chain.
54
+ * This is byte-identical to what the cairn server and wallet compute.
55
+ */
56
+ prepare(obj) {
57
+ const canonical = (0, import_csd_codec.canonicalJson)(obj);
58
+ return {
59
+ payloadHash: (0, import_csd_codec.payloadHash)(obj),
60
+ canonical,
61
+ bytes: new TextEncoder().encode(canonical)
62
+ };
63
+ }
64
+ /** Alias for `prepare()` — emphasises this does not itself publish (anchor via board.propose). */
65
+ put(obj) {
66
+ return this.prepare(obj);
67
+ }
68
+ /** Just the payload hash for an object. */
69
+ hash(obj) {
70
+ return (0, import_csd_codec.payloadHash)(obj);
71
+ }
72
+ /**
73
+ * Fetch content by hash and VERIFY it self-certifies (sha256(bytes) == hash).
74
+ * Tries each configured source in order. Returns raw bytes, or null if no
75
+ * source holds it. Throws ContentVerificationError if a source returns bytes
76
+ * that don't match the hash (tampering / wrong object).
77
+ */
78
+ async getBytes(hash) {
79
+ const h = normalizeHash(hash);
80
+ for (const src of this.sources) {
81
+ let got = null;
82
+ try {
83
+ got = await src.http.getBytes(src.path(h));
84
+ } catch {
85
+ continue;
86
+ }
87
+ if (!got) continue;
88
+ if (!(0, import_csd_codec.verifyContentBytes)(got.bytes, h)) {
89
+ throw new ContentVerificationError(h);
90
+ }
91
+ return got.bytes;
92
+ }
93
+ return null;
94
+ }
95
+ /** Fetch + verify + parse as UTF-8 JSON. Returns null if not found. */
96
+ async get(hash) {
97
+ const bytes = await this.getBytes(hash);
98
+ if (!bytes) return null;
99
+ return JSON.parse(new TextDecoder().decode(bytes));
100
+ }
101
+ /** Verify already-fetched bytes against a hash (no network). */
102
+ verify(bytes, hash) {
103
+ return (0, import_csd_codec.verifyContentBytes)(bytes, normalizeHash(hash));
104
+ }
105
+ };
106
+ function normalizeHash(hash) {
107
+ const h = hash.startsWith("0x") || hash.startsWith("0X") ? hash : `0x${hash}`;
108
+ return h.toLowerCase();
109
+ }
110
+ // Annotate the CommonJS export names for ESM import in node:
111
+ 0 && (module.exports = {
112
+ ContentClient
113
+ });
@@ -0,0 +1,44 @@
1
+ import { H as Http } from './http-D2CzfOsm.cjs';
2
+
3
+ interface ContentClientOptions {
4
+ /** Swarm gateway HTTP client (e.g. https://cairn-substrate.com/swarm). */
5
+ swarm?: Http;
6
+ /** Cairn origin HTTP client (serves /content as origin + fallback). */
7
+ cairn?: Http;
8
+ /** Indexer HTTP client (also joins the swarm gateway at /content). */
9
+ indexer?: Http;
10
+ }
11
+ interface PreparedContent {
12
+ /** The 0x-prefixed sha256 payload hash that goes on-chain. */
13
+ payloadHash: string;
14
+ /** The exact canonical JSON string that was hashed. */
15
+ canonical: string;
16
+ /** UTF-8 bytes of the canonical JSON (what the swarm stores / serves). */
17
+ bytes: Uint8Array;
18
+ }
19
+ declare class ContentClient {
20
+ private readonly sources;
21
+ constructor(opts: ContentClientOptions);
22
+ /**
23
+ * Compute the canonical hash + bytes for an object, ready to anchor on-chain.
24
+ * This is byte-identical to what the cairn server and wallet compute.
25
+ */
26
+ prepare(obj: unknown): PreparedContent;
27
+ /** Alias for `prepare()` — emphasises this does not itself publish (anchor via board.propose). */
28
+ put(obj: unknown): PreparedContent;
29
+ /** Just the payload hash for an object. */
30
+ hash(obj: unknown): string;
31
+ /**
32
+ * Fetch content by hash and VERIFY it self-certifies (sha256(bytes) == hash).
33
+ * Tries each configured source in order. Returns raw bytes, or null if no
34
+ * source holds it. Throws ContentVerificationError if a source returns bytes
35
+ * that don't match the hash (tampering / wrong object).
36
+ */
37
+ getBytes(hash: string): Promise<Uint8Array | null>;
38
+ /** Fetch + verify + parse as UTF-8 JSON. Returns null if not found. */
39
+ get<T = unknown>(hash: string): Promise<T | null>;
40
+ /** Verify already-fetched bytes against a hash (no network). */
41
+ verify(bytes: Uint8Array, hash: string): boolean;
42
+ }
43
+
44
+ export { ContentClient, type ContentClientOptions, type PreparedContent };
@@ -0,0 +1,44 @@
1
+ import { H as Http } from './http-D2CzfOsm.js';
2
+
3
+ interface ContentClientOptions {
4
+ /** Swarm gateway HTTP client (e.g. https://cairn-substrate.com/swarm). */
5
+ swarm?: Http;
6
+ /** Cairn origin HTTP client (serves /content as origin + fallback). */
7
+ cairn?: Http;
8
+ /** Indexer HTTP client (also joins the swarm gateway at /content). */
9
+ indexer?: Http;
10
+ }
11
+ interface PreparedContent {
12
+ /** The 0x-prefixed sha256 payload hash that goes on-chain. */
13
+ payloadHash: string;
14
+ /** The exact canonical JSON string that was hashed. */
15
+ canonical: string;
16
+ /** UTF-8 bytes of the canonical JSON (what the swarm stores / serves). */
17
+ bytes: Uint8Array;
18
+ }
19
+ declare class ContentClient {
20
+ private readonly sources;
21
+ constructor(opts: ContentClientOptions);
22
+ /**
23
+ * Compute the canonical hash + bytes for an object, ready to anchor on-chain.
24
+ * This is byte-identical to what the cairn server and wallet compute.
25
+ */
26
+ prepare(obj: unknown): PreparedContent;
27
+ /** Alias for `prepare()` — emphasises this does not itself publish (anchor via board.propose). */
28
+ put(obj: unknown): PreparedContent;
29
+ /** Just the payload hash for an object. */
30
+ hash(obj: unknown): string;
31
+ /**
32
+ * Fetch content by hash and VERIFY it self-certifies (sha256(bytes) == hash).
33
+ * Tries each configured source in order. Returns raw bytes, or null if no
34
+ * source holds it. Throws ContentVerificationError if a source returns bytes
35
+ * that don't match the hash (tampering / wrong object).
36
+ */
37
+ getBytes(hash: string): Promise<Uint8Array | null>;
38
+ /** Fetch + verify + parse as UTF-8 JSON. Returns null if not found. */
39
+ get<T = unknown>(hash: string): Promise<T | null>;
40
+ /** Verify already-fetched bytes against a hash (no network). */
41
+ verify(bytes: Uint8Array, hash: string): boolean;
42
+ }
43
+
44
+ export { ContentClient, type ContentClientOptions, type PreparedContent };
@@ -0,0 +1,7 @@
1
+ import {
2
+ ContentClient
3
+ } from "./chunk-BZVJVL4Q.js";
4
+ import "./chunk-PHMU3CG5.js";
5
+ export {
6
+ ContentClient
7
+ };
@@ -0,0 +1,30 @@
1
+ type FetchLike = typeof fetch;
2
+ interface HttpOptions {
3
+ /** Base URL with no trailing slash, e.g. "https://cairn-substrate.com". */
4
+ baseUrl: string;
5
+ /** Custom fetch (defaults to global fetch). */
6
+ fetch?: FetchLike;
7
+ /** Per-request timeout in ms (default 15000). */
8
+ timeoutMs?: number;
9
+ /** Extra headers sent on every request. */
10
+ headers?: Record<string, string>;
11
+ }
12
+ declare class Http {
13
+ readonly baseUrl: string;
14
+ private readonly _fetch;
15
+ private readonly timeoutMs;
16
+ private readonly headers;
17
+ constructor(opts: HttpOptions);
18
+ /** Build an absolute URL from a path + optional query params. */
19
+ url(path: string, query?: Record<string, string | number | boolean | undefined>): string;
20
+ private raw;
21
+ getJson<T = unknown>(path: string, query?: Record<string, string | number | boolean | undefined>): Promise<T>;
22
+ postJson<T = unknown>(path: string, body: unknown, headers?: Record<string, string>): Promise<T>;
23
+ /** GET raw bytes (for content retrieval). Returns null on 404. */
24
+ getBytes(path: string): Promise<{
25
+ bytes: Uint8Array;
26
+ headers: Headers;
27
+ } | null>;
28
+ }
29
+
30
+ export { type FetchLike as F, Http as H, type HttpOptions as a };