@inversealtruism/cairn-sdk 0.1.2 → 0.1.3
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/board.cjs +33 -2
- package/dist/board.js +2 -2
- package/dist/chain.cjs +29 -0
- package/dist/chain.d.cts +23 -2
- package/dist/chain.d.ts +23 -2
- package/dist/chain.js +5 -1
- package/dist/{chunk-6VWLWF7R.js → chunk-5KAUQH72.js} +31 -2
- package/dist/{chunk-OGP2W7DL.js → chunk-645CYBVN.js} +1 -1
- package/dist/chunk-G4OZKZSJ.js +213 -0
- package/dist/{chunk-BZVJVL4Q.js → chunk-OSXS26RA.js} +1 -1
- package/dist/chunk-UMGWVOOT.js +99 -0
- package/dist/chunk-ZAE2BIH5.js +78 -0
- package/dist/connect.cjs +145 -18
- package/dist/connect.d.cts +134 -2
- package/dist/connect.d.ts +134 -2
- package/dist/connect.js +4 -2
- package/dist/content.cjs +34 -3
- package/dist/content.js +2 -2
- package/dist/controller.cjs +337 -0
- package/dist/controller.d.cts +36 -0
- package/dist/controller.d.ts +36 -0
- package/dist/controller.js +8 -0
- package/dist/index.cjs +256 -22
- package/dist/index.d.cts +33 -4
- package/dist/index.d.ts +33 -4
- package/dist/index.js +27 -15
- package/dist/react.cjs +353 -0
- package/dist/react.d.cts +30 -0
- package/dist/react.d.ts +30 -0
- package/dist/react.js +23 -0
- package/package.json +31 -27
- package/dist/chunk-PHMU3CG5.js +0 -63
- package/dist/chunk-SMAPCKVG.js +0 -118
package/dist/index.cjs
CHANGED
|
@@ -22,6 +22,7 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
BoardClient: () => BoardClient,
|
|
24
24
|
Cairn: () => Cairn,
|
|
25
|
+
CairnController: () => CairnController,
|
|
25
26
|
CairnError: () => CairnError,
|
|
26
27
|
Chain: () => Chain,
|
|
27
28
|
ContentClient: () => ContentClient,
|
|
@@ -31,42 +32,77 @@ __export(index_exports, {
|
|
|
31
32
|
IndexerClient: () => IndexerClient,
|
|
32
33
|
NotInstalledError: () => NotInstalledError,
|
|
33
34
|
RegistryClient: () => RegistryClient,
|
|
35
|
+
SDK_VERSION: () => SDK_VERSION,
|
|
34
36
|
UnsupportedMethodError: () => UnsupportedMethodError,
|
|
35
37
|
UserRejectedError: () => UserRejectedError,
|
|
36
38
|
WalletConnection: () => WalletConnection,
|
|
37
39
|
WalletLockedError: () => WalletLockedError,
|
|
38
40
|
connect: () => connect,
|
|
39
41
|
detectProvider: () => detectProvider,
|
|
42
|
+
discoverProviders: () => discoverProviders,
|
|
43
|
+
errorCode: () => errorCode,
|
|
40
44
|
getWallet: () => getWallet,
|
|
41
|
-
isInstalled: () => isInstalled
|
|
45
|
+
isInstalled: () => isInstalled,
|
|
46
|
+
mapProviderError: () => mapProviderError
|
|
42
47
|
});
|
|
43
48
|
module.exports = __toCommonJS(index_exports);
|
|
44
49
|
|
|
45
50
|
// src/errors.ts
|
|
51
|
+
var SDK_VERSION = "0.1.2";
|
|
52
|
+
var DOCS_BASE = "https://cairn-substrate.com/docs/sdk";
|
|
46
53
|
var CairnError = class extends Error {
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
/** Stable machine code for programmatic branching. */
|
|
55
|
+
code;
|
|
56
|
+
/** The human message without the appended docs/version footer. */
|
|
57
|
+
shortMessage;
|
|
58
|
+
/** Relative docs path (under the SDK docs base), if any. */
|
|
59
|
+
docsPath;
|
|
60
|
+
/** The cairn-sdk version that produced this error. */
|
|
61
|
+
version = SDK_VERSION;
|
|
62
|
+
constructor(shortMessage, opts = {}) {
|
|
63
|
+
const docs = opts.docsPath;
|
|
64
|
+
super(
|
|
65
|
+
[shortMessage, docs ? `Docs: ${DOCS_BASE}${docs}` : "", `Version: cairn-sdk@${SDK_VERSION}`].filter(Boolean).join("\n"),
|
|
66
|
+
{ cause: opts.cause }
|
|
67
|
+
);
|
|
49
68
|
this.name = new.target.name;
|
|
69
|
+
this.code = opts.code ?? "UNKNOWN";
|
|
70
|
+
this.shortMessage = shortMessage;
|
|
71
|
+
this.docsPath = docs;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Walk the `cause` chain. With a predicate, returns the FIRST matching error (or null). Without one,
|
|
75
|
+
* returns the DEEPEST cause (the root). Mirrors viem's `BaseError.walk()`.
|
|
76
|
+
*/
|
|
77
|
+
walk(fn) {
|
|
78
|
+
let current = this;
|
|
79
|
+
let last = this;
|
|
80
|
+
while (current != null) {
|
|
81
|
+
if (fn && fn(current)) return current;
|
|
82
|
+
last = current;
|
|
83
|
+
current = current?.cause;
|
|
84
|
+
}
|
|
85
|
+
return fn ? null : last;
|
|
50
86
|
}
|
|
51
87
|
};
|
|
52
88
|
var NotInstalledError = class extends CairnError {
|
|
53
89
|
constructor(message = "Cairn Wallet not detected. Install it from cairn-substrate.com.") {
|
|
54
|
-
super(message);
|
|
90
|
+
super(message, { code: "NOT_INSTALLED", docsPath: "/install" });
|
|
55
91
|
}
|
|
56
92
|
};
|
|
57
93
|
var UserRejectedError = class extends CairnError {
|
|
58
94
|
constructor(message = "Request rejected by user.") {
|
|
59
|
-
super(message);
|
|
95
|
+
super(message, { code: "USER_REJECTED", docsPath: "/errors#user-rejected" });
|
|
60
96
|
}
|
|
61
97
|
};
|
|
62
98
|
var WalletLockedError = class extends CairnError {
|
|
63
99
|
constructor(message = "Wallet is locked.") {
|
|
64
|
-
super(message);
|
|
100
|
+
super(message, { code: "WALLET_LOCKED", docsPath: "/errors#wallet-locked" });
|
|
65
101
|
}
|
|
66
102
|
};
|
|
67
103
|
var UnsupportedMethodError = class extends CairnError {
|
|
68
104
|
constructor(message = "Method not supported by the wallet.") {
|
|
69
|
-
super(message);
|
|
105
|
+
super(message, { code: "UNSUPPORTED_METHOD", docsPath: "/errors#unsupported-method" });
|
|
70
106
|
}
|
|
71
107
|
};
|
|
72
108
|
var HttpError = class extends CairnError {
|
|
@@ -74,7 +110,7 @@ var HttpError = class extends CairnError {
|
|
|
74
110
|
url;
|
|
75
111
|
body;
|
|
76
112
|
constructor(status, url, body) {
|
|
77
|
-
super(`HTTP ${status} for ${url}${body ? `: ${String(body).slice(0, 200)}` : ""}
|
|
113
|
+
super(`HTTP ${status} for ${url}${body ? `: ${String(body).slice(0, 200)}` : ""}`, { code: "HTTP_ERROR" });
|
|
78
114
|
this.status = status;
|
|
79
115
|
this.url = url;
|
|
80
116
|
this.body = body;
|
|
@@ -83,7 +119,7 @@ var HttpError = class extends CairnError {
|
|
|
83
119
|
var ContentVerificationError = class extends CairnError {
|
|
84
120
|
expected;
|
|
85
121
|
constructor(expected) {
|
|
86
|
-
super(`Content does not match its payload hash ${expected} \u2014 bytes were tampered with in transit
|
|
122
|
+
super(`Content does not match its payload hash ${expected} \u2014 bytes were tampered with in transit.`, { code: "CONTENT_VERIFICATION", docsPath: "/content#verification" });
|
|
87
123
|
this.expected = expected;
|
|
88
124
|
}
|
|
89
125
|
};
|
|
@@ -91,9 +127,12 @@ function mapProviderError(error) {
|
|
|
91
127
|
const e = String(error || "").toLowerCase();
|
|
92
128
|
if (e.includes("rejected by user")) return new UserRejectedError(error);
|
|
93
129
|
if (e.includes("wallet locked")) return new WalletLockedError(error);
|
|
94
|
-
if (e.includes("unsupported dapp method")) return new UnsupportedMethodError(error);
|
|
130
|
+
if (e.includes("unsupported dapp method") || e.includes("predates") || e.includes("too old")) return new UnsupportedMethodError(error);
|
|
95
131
|
return new CairnError(error || "Unknown wallet error");
|
|
96
132
|
}
|
|
133
|
+
function errorCode(err) {
|
|
134
|
+
return err instanceof CairnError ? err.code : "UNKNOWN";
|
|
135
|
+
}
|
|
97
136
|
|
|
98
137
|
// src/http.ts
|
|
99
138
|
var Http = class {
|
|
@@ -175,6 +214,8 @@ var import_csd_crypto = require("@inversealtruism/csd-crypto");
|
|
|
175
214
|
var import_csd_light = require("@inversealtruism/csd-light");
|
|
176
215
|
var import_csd_client2 = require("@inversealtruism/csd-client");
|
|
177
216
|
var import_csd_light2 = require("@inversealtruism/csd-light");
|
|
217
|
+
var import_csd_tx2 = require("@inversealtruism/csd-tx");
|
|
218
|
+
var import_csd_crypto2 = require("@inversealtruism/csd-crypto");
|
|
178
219
|
var Chain = class {
|
|
179
220
|
client;
|
|
180
221
|
opts;
|
|
@@ -195,6 +236,29 @@ var Chain = class {
|
|
|
195
236
|
submit(nodeJsonTx) {
|
|
196
237
|
return this.client.submit(nodeJsonTx);
|
|
197
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Build + sign (+ optionally broadcast) a transfer with INPUT-VALUE VERIFICATION (the H2-safe send).
|
|
241
|
+
* Fetches the signer's UTXOs, selects, then re-verifies each selected input's REAL value against the
|
|
242
|
+
* chain (`verifyInputValues` recomputes each source tx's txid, so a lying RPC can't under-report) and
|
|
243
|
+
* computes change from the VERIFIED total — closing the UTXO-VALUE-1 implicit-fee-burn. Fail-closed:
|
|
244
|
+
* if any source can't be verified it signs nothing. Prefer this over the pure `buildSend`. Pass
|
|
245
|
+
* `broadcast:false` to get the signed tx back without submitting.
|
|
246
|
+
*/
|
|
247
|
+
async send(p) {
|
|
248
|
+
const from = (0, import_csd_crypto2.addrFromPriv)(p.priv);
|
|
249
|
+
const u = await this.client.utxos(from);
|
|
250
|
+
const built = await (0, import_csd_tx2.buildSendVerified)({
|
|
251
|
+
outputs: p.outputs,
|
|
252
|
+
fee: p.fee,
|
|
253
|
+
utxos: u.utxos,
|
|
254
|
+
priv: p.priv,
|
|
255
|
+
maxFee: p.maxFee,
|
|
256
|
+
verify: (inputs) => (0, import_csd_client2.verifyInputValues)(this.client, inputs)
|
|
257
|
+
});
|
|
258
|
+
if (!built.ok || p.broadcast === false) return built;
|
|
259
|
+
const submitResult = await this.client.submit(built.nodeJson);
|
|
260
|
+
return { ...built, submitResult };
|
|
261
|
+
}
|
|
198
262
|
/** A verifying light client over the same RPC (built once, reused). */
|
|
199
263
|
light() {
|
|
200
264
|
if (!this._light) {
|
|
@@ -692,6 +756,26 @@ var RegistryClient = class {
|
|
|
692
756
|
};
|
|
693
757
|
|
|
694
758
|
// src/connect.ts
|
|
759
|
+
function discoverProviders(opts = {}) {
|
|
760
|
+
const timeoutMs = opts.timeoutMs ?? 1e3;
|
|
761
|
+
return new Promise((resolve) => {
|
|
762
|
+
if (typeof window === "undefined") {
|
|
763
|
+
resolve([]);
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
const found = /* @__PURE__ */ new Map();
|
|
767
|
+
const onAnnounce = (ev) => {
|
|
768
|
+
const d = ev?.detail;
|
|
769
|
+
if (d?.info?.uuid && d?.provider?.isCairn) found.set(d.info.uuid, d);
|
|
770
|
+
};
|
|
771
|
+
window.addEventListener("csd:announceProvider", onAnnounce);
|
|
772
|
+
window.dispatchEvent(new CustomEvent("csd:requestProvider"));
|
|
773
|
+
setTimeout(() => {
|
|
774
|
+
window.removeEventListener("csd:announceProvider", onAnnounce);
|
|
775
|
+
resolve([...found.values()]);
|
|
776
|
+
}, timeoutMs);
|
|
777
|
+
});
|
|
778
|
+
}
|
|
695
779
|
function detectProvider(opts = {}) {
|
|
696
780
|
const timeoutMs = opts.timeoutMs ?? 3e3;
|
|
697
781
|
return new Promise((resolve, reject) => {
|
|
@@ -699,18 +783,19 @@ function detectProvider(opts = {}) {
|
|
|
699
783
|
reject(new NotInstalledError("Not running in a browser \u2014 `window.cairn` is unavailable."));
|
|
700
784
|
return;
|
|
701
785
|
}
|
|
702
|
-
if (window.cairn?.isCairn) {
|
|
703
|
-
resolve(window.cairn);
|
|
704
|
-
return;
|
|
705
|
-
}
|
|
706
786
|
let done = false;
|
|
707
|
-
const
|
|
787
|
+
const finish = (p) => {
|
|
708
788
|
if (done) return;
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
789
|
+
done = true;
|
|
790
|
+
cleanup();
|
|
791
|
+
resolve(p);
|
|
792
|
+
};
|
|
793
|
+
const onInit = () => {
|
|
794
|
+
if (!done && window.cairn?.isCairn) finish(window.cairn);
|
|
795
|
+
};
|
|
796
|
+
const onAnnounce = (ev) => {
|
|
797
|
+
const p = ev?.detail?.provider;
|
|
798
|
+
if (p?.isCairn) finish(p);
|
|
714
799
|
};
|
|
715
800
|
const timer = setTimeout(() => {
|
|
716
801
|
if (done) return;
|
|
@@ -721,8 +806,15 @@ function detectProvider(opts = {}) {
|
|
|
721
806
|
const cleanup = () => {
|
|
722
807
|
clearTimeout(timer);
|
|
723
808
|
window.removeEventListener("cairn#initialized", onInit);
|
|
809
|
+
window.removeEventListener("csd:announceProvider", onAnnounce);
|
|
724
810
|
};
|
|
725
811
|
window.addEventListener("cairn#initialized", onInit);
|
|
812
|
+
window.addEventListener("csd:announceProvider", onAnnounce);
|
|
813
|
+
if (window.cairn?.isCairn) {
|
|
814
|
+
finish(window.cairn);
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
window.dispatchEvent(new CustomEvent("csd:requestProvider"));
|
|
726
818
|
onInit();
|
|
727
819
|
});
|
|
728
820
|
}
|
|
@@ -759,10 +851,76 @@ var WalletConnection = class {
|
|
|
759
851
|
this._addr = addr;
|
|
760
852
|
return addr;
|
|
761
853
|
}
|
|
762
|
-
/**
|
|
854
|
+
/**
|
|
855
|
+
* @deprecated First-party-only legacy login (it authenticates against the wallet's own configured
|
|
856
|
+
* server and is rejected from third-party origins). Use {@link signInWithCsd} for any site.
|
|
857
|
+
* Passwordless sign-in: a signature over a login nonce (always prompts; structurally cannot sign a tx).
|
|
858
|
+
*/
|
|
763
859
|
signIn() {
|
|
764
860
|
return Promise.resolve(this.provider.signIn()).then(unwrap);
|
|
765
861
|
}
|
|
862
|
+
/**
|
|
863
|
+
* Audience-bound "Sign in with CSD" (SIWC) — the secure, replay-resistant third-party login.
|
|
864
|
+
* The wallet binds the REAL requesting origin + your single-use server `nonce` into the signed
|
|
865
|
+
* message and returns the artifact; it never mints a session. VERIFY the result SERVER-SIDE with
|
|
866
|
+
* `verifySiwc` from `@inversealtruism/csd-siwc` (domain/nonce/chain/time/signature/account), then
|
|
867
|
+
* issue your OWN session. The signature is proof-of-control, NOT a bearer token. Always prompts.
|
|
868
|
+
*/
|
|
869
|
+
signInWithCsd(params) {
|
|
870
|
+
if (!params || typeof params.nonce !== "string" || !params.nonce) {
|
|
871
|
+
return Promise.reject(new UnsupportedMethodError("signInWithCsd requires a server-issued { nonce }"));
|
|
872
|
+
}
|
|
873
|
+
if (typeof this.provider.signInWithCsd !== "function") {
|
|
874
|
+
return Promise.reject(new UnsupportedMethodError("this wallet predates Sign-in-with-CSD \u2014 ask the user to update the Cairn Wallet"));
|
|
875
|
+
}
|
|
876
|
+
return Promise.resolve(this.provider.signInWithCsd(params)).then(unwrap);
|
|
877
|
+
}
|
|
878
|
+
/** True if this wallet supports audience-bound SIWC (safe to call `signInWithCsd`). */
|
|
879
|
+
get supportsSiwc() {
|
|
880
|
+
return typeof this.provider.signInWithCsd === "function";
|
|
881
|
+
}
|
|
882
|
+
/** Feature/capability detection. Returns null if the wallet predates `getCapabilities`. */
|
|
883
|
+
async getCapabilities() {
|
|
884
|
+
if (typeof this.provider.getCapabilities !== "function") return null;
|
|
885
|
+
try {
|
|
886
|
+
return await this.provider.getCapabilities();
|
|
887
|
+
} catch {
|
|
888
|
+
return null;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
/** Atomic fill (CairnX DvP): pay + attest in ONE tx. Always prompts with clear-signing. */
|
|
892
|
+
fillOffer(params) {
|
|
893
|
+
return Promise.resolve(this.provider.fillOffer(params)).then(unwrap);
|
|
894
|
+
}
|
|
895
|
+
/** This origin's current permission grant (EIP-2255-style). Silent; [] if none / unsupported. */
|
|
896
|
+
async getPermissions() {
|
|
897
|
+
if (typeof this.provider.getPermissions !== "function") return [];
|
|
898
|
+
return unwrap(await this.provider.getPermissions());
|
|
899
|
+
}
|
|
900
|
+
/** Explicitly request permission to see the address (prompts, like connect). */
|
|
901
|
+
requestPermissions() {
|
|
902
|
+
if (typeof this.provider.requestPermissions !== "function") {
|
|
903
|
+
return Promise.reject(new UnsupportedMethodError("this wallet predates requestPermissions \u2014 use connect()"));
|
|
904
|
+
}
|
|
905
|
+
return Promise.resolve(this.provider.requestPermissions()).then(unwrap);
|
|
906
|
+
}
|
|
907
|
+
/** Revoke THIS origin's own access (silent). Returns { revoked }. Safe no-op on older wallets. */
|
|
908
|
+
async revokePermissions() {
|
|
909
|
+
if (typeof this.provider.revokePermissions !== "function") return { revoked: false };
|
|
910
|
+
return unwrap(await this.provider.revokePermissions());
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Subscribe to provider events. `accountsChanged` fires with `[]` when this site loses access
|
|
914
|
+
* (wallet lock / account switch / revoke) — re-call connect() to (re)share; `disconnect` likewise.
|
|
915
|
+
* No-op if the wallet predates events. Use the SAME handler reference with off() to unsubscribe.
|
|
916
|
+
*/
|
|
917
|
+
on(event, handler) {
|
|
918
|
+
this.provider.on?.(event, handler);
|
|
919
|
+
}
|
|
920
|
+
/** Remove a previously-added event handler (must be the same reference passed to on()). */
|
|
921
|
+
off(event, handler) {
|
|
922
|
+
this.provider.removeListener?.(event, handler);
|
|
923
|
+
}
|
|
766
924
|
/** Send CSD (always prompts with clear-signing; wallet picks inputs + returns change to itself). */
|
|
767
925
|
send(params) {
|
|
768
926
|
return Promise.resolve(this.provider.send(params)).then(unwrap);
|
|
@@ -796,6 +954,77 @@ async function connect(opts = {}) {
|
|
|
796
954
|
return { wallet, address };
|
|
797
955
|
}
|
|
798
956
|
|
|
957
|
+
// src/controller.ts
|
|
958
|
+
var DISCONNECTED = Object.freeze({ status: "disconnected", account: null, error: null });
|
|
959
|
+
var CairnController = class {
|
|
960
|
+
state = DISCONNECTED;
|
|
961
|
+
conn = null;
|
|
962
|
+
listeners = /* @__PURE__ */ new Set();
|
|
963
|
+
getWalletFn;
|
|
964
|
+
detectOpts;
|
|
965
|
+
constructor(opts = {}) {
|
|
966
|
+
const { getWallet: gw, ...detect } = opts;
|
|
967
|
+
this.getWalletFn = gw ?? getWallet;
|
|
968
|
+
this.detectOpts = detect;
|
|
969
|
+
}
|
|
970
|
+
/** useSyncExternalStore-compatible. Returns an unsubscribe fn. */
|
|
971
|
+
subscribe = (cb) => {
|
|
972
|
+
this.listeners.add(cb);
|
|
973
|
+
return () => {
|
|
974
|
+
this.listeners.delete(cb);
|
|
975
|
+
};
|
|
976
|
+
};
|
|
977
|
+
/** useSyncExternalStore-compatible snapshot — stable reference until the state actually changes. */
|
|
978
|
+
getSnapshot = () => this.state;
|
|
979
|
+
/** The underlying WalletConnection (for advanced use: send/propose/permissions/…). Null until connect(). */
|
|
980
|
+
get connection() {
|
|
981
|
+
return this.conn;
|
|
982
|
+
}
|
|
983
|
+
setState(patch) {
|
|
984
|
+
const next = { ...this.state, ...patch };
|
|
985
|
+
if (next.status === this.state.status && next.account === this.state.account && next.error === this.state.error) return;
|
|
986
|
+
this.state = Object.freeze(next);
|
|
987
|
+
for (const l of [...this.listeners]) l();
|
|
988
|
+
}
|
|
989
|
+
onAccounts = (accounts) => {
|
|
990
|
+
if (!Array.isArray(accounts) || accounts.length === 0) this.setState({ status: "disconnected", account: null });
|
|
991
|
+
else this.setState({ status: "connected", account: String(accounts[0]), error: null });
|
|
992
|
+
};
|
|
993
|
+
onDisconnect = () => {
|
|
994
|
+
this.setState({ status: "disconnected", account: null });
|
|
995
|
+
};
|
|
996
|
+
/** Detect + connect (prompts the user the first time per origin). Resolves the connected address. */
|
|
997
|
+
connect = async () => {
|
|
998
|
+
this.setState({ status: "connecting", error: null });
|
|
999
|
+
try {
|
|
1000
|
+
if (!this.conn) {
|
|
1001
|
+
this.conn = await this.getWalletFn(this.detectOpts);
|
|
1002
|
+
this.conn.on("accountsChanged", this.onAccounts);
|
|
1003
|
+
this.conn.on("disconnect", this.onDisconnect);
|
|
1004
|
+
}
|
|
1005
|
+
const addr = await this.conn.connect();
|
|
1006
|
+
this.setState({ status: "connected", account: addr, error: null });
|
|
1007
|
+
return addr;
|
|
1008
|
+
} catch (e) {
|
|
1009
|
+
this.setState({ status: "disconnected", account: null, error: e?.message ?? String(e) });
|
|
1010
|
+
throw e;
|
|
1011
|
+
}
|
|
1012
|
+
};
|
|
1013
|
+
/** Forget the connection locally AND revoke this origin's wallet-side permission (best-effort). */
|
|
1014
|
+
disconnect = async () => {
|
|
1015
|
+
try {
|
|
1016
|
+
await this.conn?.revokePermissions();
|
|
1017
|
+
} catch {
|
|
1018
|
+
}
|
|
1019
|
+
this.setState({ status: "disconnected", account: null, error: null });
|
|
1020
|
+
};
|
|
1021
|
+
/** Audience-bound sign-in (must connect() first). Returns the signed artifact to verify server-side. */
|
|
1022
|
+
signInWithCsd = (params) => {
|
|
1023
|
+
if (!this.conn) return Promise.reject(new Error("call connect() before signInWithCsd()"));
|
|
1024
|
+
return this.conn.signInWithCsd(params);
|
|
1025
|
+
};
|
|
1026
|
+
};
|
|
1027
|
+
|
|
799
1028
|
// src/index.ts
|
|
800
1029
|
var DEFAULT_SPV_CHECKPOINT = { height: 31310, hash: "0x000000000000138bd3eee4b8d2fbacb8d5433ac3040ddbf1c45a5e3e0cc9e814" };
|
|
801
1030
|
var DEFAULT_CAIRN = "https://cairn-substrate.com";
|
|
@@ -880,6 +1109,7 @@ var Cairn = class {
|
|
|
880
1109
|
0 && (module.exports = {
|
|
881
1110
|
BoardClient,
|
|
882
1111
|
Cairn,
|
|
1112
|
+
CairnController,
|
|
883
1113
|
CairnError,
|
|
884
1114
|
Chain,
|
|
885
1115
|
ContentClient,
|
|
@@ -889,12 +1119,16 @@ var Cairn = class {
|
|
|
889
1119
|
IndexerClient,
|
|
890
1120
|
NotInstalledError,
|
|
891
1121
|
RegistryClient,
|
|
1122
|
+
SDK_VERSION,
|
|
892
1123
|
UnsupportedMethodError,
|
|
893
1124
|
UserRejectedError,
|
|
894
1125
|
WalletConnection,
|
|
895
1126
|
WalletLockedError,
|
|
896
1127
|
connect,
|
|
897
1128
|
detectProvider,
|
|
1129
|
+
discoverProviders,
|
|
1130
|
+
errorCode,
|
|
898
1131
|
getWallet,
|
|
899
|
-
isInstalled
|
|
1132
|
+
isInstalled,
|
|
1133
|
+
mapProviderError
|
|
900
1134
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -9,7 +9,8 @@ import { ContentClient } from './content.cjs';
|
|
|
9
9
|
export { ContentClientOptions, PreparedContent } from './content.cjs';
|
|
10
10
|
import { RegistryClient } from './registry.cjs';
|
|
11
11
|
import { WalletConnection, DetectOptions } from './connect.cjs';
|
|
12
|
-
export { AttestParams, CairnProvider, ConnectResult, ProposeParams, SealClaimParams, SendParams, SignInResult, TxResult, connect, detectProvider, getWallet, isInstalled } from './connect.cjs';
|
|
12
|
+
export { AttestParams, CairnProvider, ConnectResult, FillParams, ProposeParams, ProviderDetail, ProviderInfo, SealClaimParams, SendParams, SignInResult, SiwcParams, SiwcResult, TxResult, WalletCapabilities, WalletPermission, connect, detectProvider, discoverProviders, getWallet, isInstalled } from './connect.cjs';
|
|
13
|
+
export { CairnController, CairnControllerOptions, CairnState } from './controller.cjs';
|
|
13
14
|
import '@inversealtruism/csd-client';
|
|
14
15
|
import '@inversealtruism/csd-tx';
|
|
15
16
|
import '@inversealtruism/csd-codec';
|
|
@@ -17,8 +18,29 @@ import '@inversealtruism/csd-crypto';
|
|
|
17
18
|
import '@inversealtruism/csd-light';
|
|
18
19
|
import '@inversealtruism/csd-registry';
|
|
19
20
|
|
|
21
|
+
/** 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.2";
|
|
24
|
+
interface CairnErrorOptions {
|
|
25
|
+
code?: CairnErrorCode;
|
|
26
|
+
docsPath?: string;
|
|
27
|
+
cause?: unknown;
|
|
28
|
+
}
|
|
20
29
|
declare class CairnError extends Error {
|
|
21
|
-
|
|
30
|
+
/** Stable machine code for programmatic branching. */
|
|
31
|
+
readonly code: CairnErrorCode;
|
|
32
|
+
/** The human message without the appended docs/version footer. */
|
|
33
|
+
readonly shortMessage: string;
|
|
34
|
+
/** Relative docs path (under the SDK docs base), if any. */
|
|
35
|
+
readonly docsPath?: string;
|
|
36
|
+
/** The cairn-sdk version that produced this error. */
|
|
37
|
+
readonly version = "0.1.2";
|
|
38
|
+
constructor(shortMessage: string, opts?: CairnErrorOptions);
|
|
39
|
+
/**
|
|
40
|
+
* Walk the `cause` chain. With a predicate, returns the FIRST matching error (or null). Without one,
|
|
41
|
+
* returns the DEEPEST cause (the root). Mirrors viem's `BaseError.walk()`.
|
|
42
|
+
*/
|
|
43
|
+
walk(fn?: (err: unknown) => boolean): unknown;
|
|
22
44
|
}
|
|
23
45
|
/** The Cairn Wallet extension is not installed (no `window.cairn` appeared). */
|
|
24
46
|
declare class NotInstalledError extends CairnError {
|
|
@@ -32,7 +54,7 @@ declare class UserRejectedError extends CairnError {
|
|
|
32
54
|
declare class WalletLockedError extends CairnError {
|
|
33
55
|
constructor(message?: string);
|
|
34
56
|
}
|
|
35
|
-
/** The method is not exposed to dApps by the wallet boundary. */
|
|
57
|
+
/** The method is not exposed to dApps by the wallet boundary (or the wallet is too old for it). */
|
|
36
58
|
declare class UnsupportedMethodError extends CairnError {
|
|
37
59
|
constructor(message?: string);
|
|
38
60
|
}
|
|
@@ -48,6 +70,13 @@ declare class ContentVerificationError extends CairnError {
|
|
|
48
70
|
expected: string;
|
|
49
71
|
constructor(expected: string);
|
|
50
72
|
}
|
|
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;
|
|
78
|
+
/** Convenience: the stable code of any error (or "UNKNOWN" for a non-CairnError). */
|
|
79
|
+
declare function errorCode(err: unknown): CairnErrorCode;
|
|
51
80
|
|
|
52
81
|
interface CairnBaseUrls {
|
|
53
82
|
/** Cairn board server (board + /api/rpc proxy + /content origin). Default https://cairn-substrate.com */
|
|
@@ -126,4 +155,4 @@ declare class Cairn {
|
|
|
126
155
|
get connected(): boolean;
|
|
127
156
|
}
|
|
128
157
|
|
|
129
|
-
export { BoardClient, Cairn, type CairnBaseUrls, type CairnConfig, CairnError, Chain, ContentClient, ContentVerificationError, DetectOptions, FetchLike, HttpError, IndexerClient, NotInstalledError, RegistryClient, UnsupportedMethodError, UserRejectedError, WalletConnection, WalletLockedError };
|
|
158
|
+
export { BoardClient, Cairn, type CairnBaseUrls, type CairnConfig, CairnError, type CairnErrorCode, type CairnErrorOptions, Chain, ContentClient, ContentVerificationError, DetectOptions, FetchLike, HttpError, IndexerClient, NotInstalledError, RegistryClient, SDK_VERSION, UnsupportedMethodError, UserRejectedError, WalletConnection, WalletLockedError, errorCode, mapProviderError };
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,8 @@ import { ContentClient } from './content.js';
|
|
|
9
9
|
export { ContentClientOptions, PreparedContent } from './content.js';
|
|
10
10
|
import { RegistryClient } from './registry.js';
|
|
11
11
|
import { WalletConnection, DetectOptions } from './connect.js';
|
|
12
|
-
export { AttestParams, CairnProvider, ConnectResult, ProposeParams, SealClaimParams, SendParams, SignInResult, TxResult, connect, detectProvider, getWallet, isInstalled } from './connect.js';
|
|
12
|
+
export { AttestParams, CairnProvider, ConnectResult, FillParams, ProposeParams, ProviderDetail, ProviderInfo, SealClaimParams, SendParams, SignInResult, SiwcParams, SiwcResult, TxResult, WalletCapabilities, WalletPermission, connect, detectProvider, discoverProviders, getWallet, isInstalled } from './connect.js';
|
|
13
|
+
export { CairnController, CairnControllerOptions, CairnState } from './controller.js';
|
|
13
14
|
import '@inversealtruism/csd-client';
|
|
14
15
|
import '@inversealtruism/csd-tx';
|
|
15
16
|
import '@inversealtruism/csd-codec';
|
|
@@ -17,8 +18,29 @@ import '@inversealtruism/csd-crypto';
|
|
|
17
18
|
import '@inversealtruism/csd-light';
|
|
18
19
|
import '@inversealtruism/csd-registry';
|
|
19
20
|
|
|
21
|
+
/** 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.2";
|
|
24
|
+
interface CairnErrorOptions {
|
|
25
|
+
code?: CairnErrorCode;
|
|
26
|
+
docsPath?: string;
|
|
27
|
+
cause?: unknown;
|
|
28
|
+
}
|
|
20
29
|
declare class CairnError extends Error {
|
|
21
|
-
|
|
30
|
+
/** Stable machine code for programmatic branching. */
|
|
31
|
+
readonly code: CairnErrorCode;
|
|
32
|
+
/** The human message without the appended docs/version footer. */
|
|
33
|
+
readonly shortMessage: string;
|
|
34
|
+
/** Relative docs path (under the SDK docs base), if any. */
|
|
35
|
+
readonly docsPath?: string;
|
|
36
|
+
/** The cairn-sdk version that produced this error. */
|
|
37
|
+
readonly version = "0.1.2";
|
|
38
|
+
constructor(shortMessage: string, opts?: CairnErrorOptions);
|
|
39
|
+
/**
|
|
40
|
+
* Walk the `cause` chain. With a predicate, returns the FIRST matching error (or null). Without one,
|
|
41
|
+
* returns the DEEPEST cause (the root). Mirrors viem's `BaseError.walk()`.
|
|
42
|
+
*/
|
|
43
|
+
walk(fn?: (err: unknown) => boolean): unknown;
|
|
22
44
|
}
|
|
23
45
|
/** The Cairn Wallet extension is not installed (no `window.cairn` appeared). */
|
|
24
46
|
declare class NotInstalledError extends CairnError {
|
|
@@ -32,7 +54,7 @@ declare class UserRejectedError extends CairnError {
|
|
|
32
54
|
declare class WalletLockedError extends CairnError {
|
|
33
55
|
constructor(message?: string);
|
|
34
56
|
}
|
|
35
|
-
/** The method is not exposed to dApps by the wallet boundary. */
|
|
57
|
+
/** The method is not exposed to dApps by the wallet boundary (or the wallet is too old for it). */
|
|
36
58
|
declare class UnsupportedMethodError extends CairnError {
|
|
37
59
|
constructor(message?: string);
|
|
38
60
|
}
|
|
@@ -48,6 +70,13 @@ declare class ContentVerificationError extends CairnError {
|
|
|
48
70
|
expected: string;
|
|
49
71
|
constructor(expected: string);
|
|
50
72
|
}
|
|
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;
|
|
78
|
+
/** Convenience: the stable code of any error (or "UNKNOWN" for a non-CairnError). */
|
|
79
|
+
declare function errorCode(err: unknown): CairnErrorCode;
|
|
51
80
|
|
|
52
81
|
interface CairnBaseUrls {
|
|
53
82
|
/** Cairn board server (board + /api/rpc proxy + /content origin). Default https://cairn-substrate.com */
|
|
@@ -126,4 +155,4 @@ declare class Cairn {
|
|
|
126
155
|
get connected(): boolean;
|
|
127
156
|
}
|
|
128
157
|
|
|
129
|
-
export { BoardClient, Cairn, type CairnBaseUrls, type CairnConfig, CairnError, Chain, ContentClient, ContentVerificationError, DetectOptions, FetchLike, HttpError, IndexerClient, NotInstalledError, RegistryClient, UnsupportedMethodError, UserRejectedError, WalletConnection, WalletLockedError };
|
|
158
|
+
export { BoardClient, Cairn, type CairnBaseUrls, type CairnConfig, CairnError, type CairnErrorCode, type CairnErrorOptions, Chain, ContentClient, ContentVerificationError, DetectOptions, FetchLike, HttpError, IndexerClient, NotInstalledError, RegistryClient, SDK_VERSION, UnsupportedMethodError, UserRejectedError, WalletConnection, WalletLockedError, errorCode, mapProviderError };
|
package/dist/index.js
CHANGED
|
@@ -1,35 +1,42 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RegistryClient
|
|
3
|
+
} from "./chunk-G7FABIF4.js";
|
|
1
4
|
import {
|
|
2
5
|
BoardClient
|
|
3
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-645CYBVN.js";
|
|
4
7
|
import {
|
|
5
8
|
Chain,
|
|
6
9
|
LightClient
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5KAUQH72.js";
|
|
11
|
+
import {
|
|
12
|
+
ContentClient
|
|
13
|
+
} from "./chunk-OSXS26RA.js";
|
|
14
|
+
import {
|
|
15
|
+
IndexerClient
|
|
16
|
+
} from "./chunk-FNBE2FPE.js";
|
|
17
|
+
import {
|
|
18
|
+
CairnController
|
|
19
|
+
} from "./chunk-ZAE2BIH5.js";
|
|
8
20
|
import {
|
|
9
21
|
WalletConnection,
|
|
10
22
|
connect,
|
|
11
23
|
detectProvider,
|
|
24
|
+
discoverProviders,
|
|
12
25
|
getWallet,
|
|
13
26
|
isInstalled
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import {
|
|
16
|
-
ContentClient
|
|
17
|
-
} from "./chunk-BZVJVL4Q.js";
|
|
27
|
+
} from "./chunk-G4OZKZSJ.js";
|
|
18
28
|
import {
|
|
19
29
|
CairnError,
|
|
20
30
|
ContentVerificationError,
|
|
21
31
|
HttpError,
|
|
22
32
|
NotInstalledError,
|
|
33
|
+
SDK_VERSION,
|
|
23
34
|
UnsupportedMethodError,
|
|
24
35
|
UserRejectedError,
|
|
25
|
-
WalletLockedError
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
} from "./chunk-FNBE2FPE.js";
|
|
30
|
-
import {
|
|
31
|
-
RegistryClient
|
|
32
|
-
} from "./chunk-G7FABIF4.js";
|
|
36
|
+
WalletLockedError,
|
|
37
|
+
errorCode,
|
|
38
|
+
mapProviderError
|
|
39
|
+
} from "./chunk-UMGWVOOT.js";
|
|
33
40
|
|
|
34
41
|
// src/http.ts
|
|
35
42
|
var Http = class {
|
|
@@ -186,6 +193,7 @@ var Cairn = class {
|
|
|
186
193
|
export {
|
|
187
194
|
BoardClient,
|
|
188
195
|
Cairn,
|
|
196
|
+
CairnController,
|
|
189
197
|
CairnError,
|
|
190
198
|
Chain,
|
|
191
199
|
ContentClient,
|
|
@@ -195,12 +203,16 @@ export {
|
|
|
195
203
|
IndexerClient,
|
|
196
204
|
NotInstalledError,
|
|
197
205
|
RegistryClient,
|
|
206
|
+
SDK_VERSION,
|
|
198
207
|
UnsupportedMethodError,
|
|
199
208
|
UserRejectedError,
|
|
200
209
|
WalletConnection,
|
|
201
210
|
WalletLockedError,
|
|
202
211
|
connect,
|
|
203
212
|
detectProvider,
|
|
213
|
+
discoverProviders,
|
|
214
|
+
errorCode,
|
|
204
215
|
getWallet,
|
|
205
|
-
isInstalled
|
|
216
|
+
isInstalled,
|
|
217
|
+
mapProviderError
|
|
206
218
|
};
|