@satoshai/kit 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/README.md +193 -16
- package/dist/index.cjs +227 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +446 -7
- package/dist/index.d.ts +446 -7
- package/dist/index.js +223 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6,6 +6,79 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
6
6
|
var transactions = require('@stacks/transactions');
|
|
7
7
|
var bnsV2Sdk = require('bns-v2-sdk');
|
|
8
8
|
|
|
9
|
+
// src/errors.ts
|
|
10
|
+
var BaseError = class extends Error {
|
|
11
|
+
name = "StacksKitError";
|
|
12
|
+
/** Short, human-readable error summary without details or cause chain. */
|
|
13
|
+
shortMessage;
|
|
14
|
+
constructor(shortMessage, options) {
|
|
15
|
+
const message = [
|
|
16
|
+
shortMessage,
|
|
17
|
+
options?.details && `Details: ${options.details}`
|
|
18
|
+
].filter(Boolean).join("\n\n");
|
|
19
|
+
super(message, options?.cause ? { cause: options.cause } : void 0);
|
|
20
|
+
this.shortMessage = shortMessage;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Walk the error cause chain. If `fn` is provided, returns the first error
|
|
24
|
+
* where `fn` returns `true`; otherwise returns the root cause.
|
|
25
|
+
*/
|
|
26
|
+
walk(fn) {
|
|
27
|
+
return walk(this, fn);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
function walk(err, fn) {
|
|
31
|
+
if (fn?.(err)) return err;
|
|
32
|
+
if (err && typeof err === "object" && "cause" in err) {
|
|
33
|
+
return walk(err.cause, fn);
|
|
34
|
+
}
|
|
35
|
+
return err;
|
|
36
|
+
}
|
|
37
|
+
var WalletNotConnectedError = class extends BaseError {
|
|
38
|
+
name = "WalletNotConnectedError";
|
|
39
|
+
constructor() {
|
|
40
|
+
super("Wallet is not connected");
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var WalletNotFoundError = class extends BaseError {
|
|
44
|
+
name = "WalletNotFoundError";
|
|
45
|
+
/** The wallet ID that was not found. */
|
|
46
|
+
wallet;
|
|
47
|
+
constructor({ wallet }) {
|
|
48
|
+
super(`${wallet} wallet not found`, {
|
|
49
|
+
details: "The wallet extension may not be installed."
|
|
50
|
+
});
|
|
51
|
+
this.wallet = wallet;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
var UnsupportedMethodError = class extends BaseError {
|
|
55
|
+
name = "UnsupportedMethodError";
|
|
56
|
+
/** The SIP-030 method name that is not supported. */
|
|
57
|
+
method;
|
|
58
|
+
/** The wallet that does not support the method. */
|
|
59
|
+
wallet;
|
|
60
|
+
constructor({ method, wallet }) {
|
|
61
|
+
super(`${method} is not supported by ${wallet} wallet`);
|
|
62
|
+
this.method = method;
|
|
63
|
+
this.wallet = wallet;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var WalletRequestError = class extends BaseError {
|
|
67
|
+
name = "WalletRequestError";
|
|
68
|
+
/** The SIP-030 method name that failed. */
|
|
69
|
+
method;
|
|
70
|
+
/** The wallet that returned the error. */
|
|
71
|
+
wallet;
|
|
72
|
+
constructor({ method, wallet, cause }) {
|
|
73
|
+
super(`${wallet} wallet request failed`, {
|
|
74
|
+
cause,
|
|
75
|
+
details: cause.message
|
|
76
|
+
});
|
|
77
|
+
this.method = method;
|
|
78
|
+
this.wallet = wallet;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
9
82
|
// src/constants/stacks-provider-mapping.ts
|
|
10
83
|
var STACKS_TO_STACKS_CONNECT_PROVIDERS = {
|
|
11
84
|
xverse: "XverseProviders.BitcoinProvider",
|
|
@@ -151,6 +224,102 @@ var extractStacksAddress = (typedProvider, addresses) => {
|
|
|
151
224
|
`No valid Stacks address found for ${typedProvider} wallet`
|
|
152
225
|
);
|
|
153
226
|
};
|
|
227
|
+
|
|
228
|
+
// src/hooks/use-wallet-connect/use-wallet-connect.helpers.ts
|
|
229
|
+
var getWcUniversalProvider = () => window.WalletConnectProvider?.connector?.provider ?? null;
|
|
230
|
+
var extractStacksAddress2 = (accounts) => {
|
|
231
|
+
for (const entry of accounts) {
|
|
232
|
+
if (typeof entry === "object" && entry !== null && "address" in entry) {
|
|
233
|
+
return entry.address;
|
|
234
|
+
}
|
|
235
|
+
if (typeof entry === "string") {
|
|
236
|
+
if (entry.startsWith("S")) return entry;
|
|
237
|
+
if (entry.startsWith("stacks:")) return entry.split(":")[2] ?? null;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return null;
|
|
241
|
+
};
|
|
242
|
+
var PING_TIMEOUT_MS = 1e4;
|
|
243
|
+
var pingSession = async () => {
|
|
244
|
+
const wcProvider = getWcUniversalProvider();
|
|
245
|
+
const client = wcProvider?.client;
|
|
246
|
+
const session = wcProvider?.session;
|
|
247
|
+
if (!client || !session) return false;
|
|
248
|
+
try {
|
|
249
|
+
await Promise.race([
|
|
250
|
+
client.ping({ topic: session.topic }),
|
|
251
|
+
new Promise(
|
|
252
|
+
(_, reject) => setTimeout(() => reject(new Error("Ping timeout")), PING_TIMEOUT_MS)
|
|
253
|
+
)
|
|
254
|
+
]);
|
|
255
|
+
return true;
|
|
256
|
+
} catch {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
// src/hooks/use-wallet-connect/use-wallet-connect.ts
|
|
262
|
+
var useWalletConnect = ({
|
|
263
|
+
address,
|
|
264
|
+
provider,
|
|
265
|
+
onAddressChange,
|
|
266
|
+
onDisconnect
|
|
267
|
+
}) => {
|
|
268
|
+
react.useEffect(() => {
|
|
269
|
+
if (provider !== "wallet-connect" || !address) return;
|
|
270
|
+
let cancelled = false;
|
|
271
|
+
const validateSession = async () => {
|
|
272
|
+
const alive = await pingSession();
|
|
273
|
+
if (cancelled) return;
|
|
274
|
+
if (!alive) {
|
|
275
|
+
const wcProvider = getWcUniversalProvider();
|
|
276
|
+
try {
|
|
277
|
+
await wcProvider?.disconnect();
|
|
278
|
+
} catch {
|
|
279
|
+
}
|
|
280
|
+
connect.clearSelectedProviderId();
|
|
281
|
+
onDisconnect();
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
void validateSession();
|
|
285
|
+
return () => {
|
|
286
|
+
cancelled = true;
|
|
287
|
+
};
|
|
288
|
+
}, [provider, address, onDisconnect]);
|
|
289
|
+
react.useEffect(() => {
|
|
290
|
+
if (provider !== "wallet-connect" || !address) return;
|
|
291
|
+
const wcProvider = getWcUniversalProvider();
|
|
292
|
+
if (!wcProvider) return;
|
|
293
|
+
const handleDisconnect = () => {
|
|
294
|
+
connect.clearSelectedProviderId();
|
|
295
|
+
onDisconnect();
|
|
296
|
+
};
|
|
297
|
+
const handleAccountsChanged = (...args) => {
|
|
298
|
+
const accounts = args[0];
|
|
299
|
+
const newAddress = extractStacksAddress2(accounts);
|
|
300
|
+
if (newAddress && newAddress !== address) {
|
|
301
|
+
onAddressChange(newAddress);
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
wcProvider.on("disconnect", handleDisconnect);
|
|
305
|
+
wcProvider.on("accountsChanged", handleAccountsChanged);
|
|
306
|
+
wcProvider.on("stx_accountChange", handleAccountsChanged);
|
|
307
|
+
wcProvider.on("stx_accountsChanged", handleAccountsChanged);
|
|
308
|
+
return () => {
|
|
309
|
+
try {
|
|
310
|
+
wcProvider.off("disconnect", handleDisconnect);
|
|
311
|
+
wcProvider.off("accountsChanged", handleAccountsChanged);
|
|
312
|
+
wcProvider.off("stx_accountChange", handleAccountsChanged);
|
|
313
|
+
wcProvider.off("stx_accountsChanged", handleAccountsChanged);
|
|
314
|
+
} catch (error) {
|
|
315
|
+
console.error(
|
|
316
|
+
"Failed to remove WalletConnect listeners:",
|
|
317
|
+
error
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
}, [address, provider, onAddressChange, onDisconnect]);
|
|
322
|
+
};
|
|
154
323
|
var getXverseProductInfo = async () => await window.XverseProviders?.StacksProvider?.getProductInfo?.() ?? null;
|
|
155
324
|
var shouldSupportAccountChange = (version) => version !== void 0 && version !== "1.0.0";
|
|
156
325
|
var waitForXverseProvider = async (maxAttempts = 10, initialDelay = 200) => {
|
|
@@ -529,6 +698,18 @@ var StacksWalletProvider = ({
|
|
|
529
698
|
onAddressChange: handleAddressChange,
|
|
530
699
|
connect: connect$1
|
|
531
700
|
});
|
|
701
|
+
const handleWcDisconnect = react.useCallback(() => {
|
|
702
|
+
localStorage.removeItem(LOCAL_STORAGE_STACKS);
|
|
703
|
+
setAddress(void 0);
|
|
704
|
+
setProvider(void 0);
|
|
705
|
+
onDisconnect?.();
|
|
706
|
+
}, [onDisconnect]);
|
|
707
|
+
useWalletConnect({
|
|
708
|
+
address,
|
|
709
|
+
provider,
|
|
710
|
+
onAddressChange: handleAddressChange,
|
|
711
|
+
onDisconnect: handleWcDisconnect
|
|
712
|
+
});
|
|
532
713
|
const { installed } = getStacksWallets();
|
|
533
714
|
const configured = wallets ?? [...SUPPORTED_STACKS_WALLETS];
|
|
534
715
|
const walletInfos = configured.map((w) => ({
|
|
@@ -685,7 +866,7 @@ var useSignMessage = () => {
|
|
|
685
866
|
const signMessageAsync = react.useCallback(
|
|
686
867
|
async (variables) => {
|
|
687
868
|
if (!isConnected) {
|
|
688
|
-
throw new
|
|
869
|
+
throw new WalletNotConnectedError();
|
|
689
870
|
}
|
|
690
871
|
setStatus("pending");
|
|
691
872
|
setError(null);
|
|
@@ -694,7 +875,7 @@ var useSignMessage = () => {
|
|
|
694
875
|
let result;
|
|
695
876
|
if (provider === "okx") {
|
|
696
877
|
if (!window.okxwallet) {
|
|
697
|
-
throw new
|
|
878
|
+
throw new WalletNotFoundError({ wallet: "OKX" });
|
|
698
879
|
}
|
|
699
880
|
result = await window.okxwallet.stacks.signMessage({
|
|
700
881
|
message: variables.message
|
|
@@ -711,7 +892,11 @@ var useSignMessage = () => {
|
|
|
711
892
|
setStatus("success");
|
|
712
893
|
return result;
|
|
713
894
|
} catch (err) {
|
|
714
|
-
const error2 = err instanceof
|
|
895
|
+
const error2 = err instanceof BaseError ? err : new WalletRequestError({
|
|
896
|
+
method: "stx_signMessage",
|
|
897
|
+
wallet: provider ?? "unknown",
|
|
898
|
+
cause: err instanceof Error ? err : new Error(String(err))
|
|
899
|
+
});
|
|
715
900
|
setError(error2);
|
|
716
901
|
setStatus("error");
|
|
717
902
|
throw error2;
|
|
@@ -762,12 +947,13 @@ var useSignStructuredMessage = () => {
|
|
|
762
947
|
const signStructuredMessageAsync = react.useCallback(
|
|
763
948
|
async (variables) => {
|
|
764
949
|
if (!isConnected) {
|
|
765
|
-
throw new
|
|
950
|
+
throw new WalletNotConnectedError();
|
|
766
951
|
}
|
|
767
952
|
if (provider === "okx") {
|
|
768
|
-
throw new
|
|
769
|
-
|
|
770
|
-
|
|
953
|
+
throw new UnsupportedMethodError({
|
|
954
|
+
method: "stx_signStructuredMessage",
|
|
955
|
+
wallet: "OKX"
|
|
956
|
+
});
|
|
771
957
|
}
|
|
772
958
|
setStatus("pending");
|
|
773
959
|
setError(null);
|
|
@@ -781,7 +967,11 @@ var useSignStructuredMessage = () => {
|
|
|
781
967
|
setStatus("success");
|
|
782
968
|
return result;
|
|
783
969
|
} catch (err) {
|
|
784
|
-
const error2 = err instanceof
|
|
970
|
+
const error2 = err instanceof BaseError ? err : new WalletRequestError({
|
|
971
|
+
method: "stx_signStructuredMessage",
|
|
972
|
+
wallet: provider ?? "unknown",
|
|
973
|
+
cause: err instanceof Error ? err : new Error(String(err))
|
|
974
|
+
});
|
|
785
975
|
setError(error2);
|
|
786
976
|
setStatus("error");
|
|
787
977
|
throw error2;
|
|
@@ -837,12 +1027,13 @@ var useSignTransaction = () => {
|
|
|
837
1027
|
const signTransactionAsync = react.useCallback(
|
|
838
1028
|
async (variables) => {
|
|
839
1029
|
if (!isConnected) {
|
|
840
|
-
throw new
|
|
1030
|
+
throw new WalletNotConnectedError();
|
|
841
1031
|
}
|
|
842
1032
|
if (provider === "okx") {
|
|
843
|
-
throw new
|
|
844
|
-
|
|
845
|
-
|
|
1033
|
+
throw new UnsupportedMethodError({
|
|
1034
|
+
method: "stx_signTransaction",
|
|
1035
|
+
wallet: "OKX"
|
|
1036
|
+
});
|
|
846
1037
|
}
|
|
847
1038
|
setStatus("pending");
|
|
848
1039
|
setError(null);
|
|
@@ -858,7 +1049,11 @@ var useSignTransaction = () => {
|
|
|
858
1049
|
setStatus("success");
|
|
859
1050
|
return result;
|
|
860
1051
|
} catch (err) {
|
|
861
|
-
const error2 = err instanceof
|
|
1052
|
+
const error2 = err instanceof BaseError ? err : new WalletRequestError({
|
|
1053
|
+
method: "stx_signTransaction",
|
|
1054
|
+
wallet: provider ?? "unknown",
|
|
1055
|
+
cause: err instanceof Error ? err : new Error(String(err))
|
|
1056
|
+
});
|
|
862
1057
|
setError(error2);
|
|
863
1058
|
setStatus("error");
|
|
864
1059
|
throw error2;
|
|
@@ -920,7 +1115,7 @@ var useTransferSTX = () => {
|
|
|
920
1115
|
const transferSTXAsync = react.useCallback(
|
|
921
1116
|
async (variables) => {
|
|
922
1117
|
if (!isConnected || !address) {
|
|
923
|
-
throw new
|
|
1118
|
+
throw new WalletNotConnectedError();
|
|
924
1119
|
}
|
|
925
1120
|
setStatus("pending");
|
|
926
1121
|
setError(null);
|
|
@@ -928,7 +1123,7 @@ var useTransferSTX = () => {
|
|
|
928
1123
|
try {
|
|
929
1124
|
if (provider === "okx") {
|
|
930
1125
|
if (!window.okxwallet) {
|
|
931
|
-
throw new
|
|
1126
|
+
throw new WalletNotFoundError({ wallet: "OKX" });
|
|
932
1127
|
}
|
|
933
1128
|
const response2 = await window.okxwallet.stacks.signTransaction({
|
|
934
1129
|
txType: "token_transfer",
|
|
@@ -963,7 +1158,11 @@ var useTransferSTX = () => {
|
|
|
963
1158
|
setStatus("success");
|
|
964
1159
|
return response.txid;
|
|
965
1160
|
} catch (err) {
|
|
966
|
-
const error2 = err instanceof
|
|
1161
|
+
const error2 = err instanceof BaseError ? err : new WalletRequestError({
|
|
1162
|
+
method: "stx_transferStx",
|
|
1163
|
+
wallet: provider ?? "unknown",
|
|
1164
|
+
cause: err instanceof Error ? err : new Error(String(err))
|
|
1165
|
+
});
|
|
967
1166
|
setError(error2);
|
|
968
1167
|
setStatus("error");
|
|
969
1168
|
throw error2;
|
|
@@ -1151,7 +1350,7 @@ var useWriteContract = () => {
|
|
|
1151
1350
|
const writeContractAsync = react.useCallback(
|
|
1152
1351
|
async (variables) => {
|
|
1153
1352
|
if (!isConnected || !address) {
|
|
1154
|
-
throw new
|
|
1353
|
+
throw new WalletNotConnectedError();
|
|
1155
1354
|
}
|
|
1156
1355
|
setStatus("pending");
|
|
1157
1356
|
setError(null);
|
|
@@ -1160,7 +1359,7 @@ var useWriteContract = () => {
|
|
|
1160
1359
|
try {
|
|
1161
1360
|
if (provider === "okx") {
|
|
1162
1361
|
if (!window.okxwallet) {
|
|
1163
|
-
throw new
|
|
1362
|
+
throw new WalletNotFoundError({ wallet: "OKX" });
|
|
1164
1363
|
}
|
|
1165
1364
|
const response2 = await window.okxwallet.stacks.signTransaction({
|
|
1166
1365
|
contractAddress: variables.address,
|
|
@@ -1195,7 +1394,11 @@ var useWriteContract = () => {
|
|
|
1195
1394
|
setStatus("success");
|
|
1196
1395
|
return response.txid;
|
|
1197
1396
|
} catch (err) {
|
|
1198
|
-
const error2 = err instanceof
|
|
1397
|
+
const error2 = err instanceof BaseError ? err : new WalletRequestError({
|
|
1398
|
+
method: "stx_callContract",
|
|
1399
|
+
wallet: provider ?? "unknown",
|
|
1400
|
+
cause: err instanceof Error ? err : new Error(String(err))
|
|
1401
|
+
});
|
|
1199
1402
|
setError(error2);
|
|
1200
1403
|
setStatus("error");
|
|
1201
1404
|
throw error2;
|
|
@@ -1280,8 +1483,13 @@ function createContractConfig(config) {
|
|
|
1280
1483
|
return config;
|
|
1281
1484
|
}
|
|
1282
1485
|
|
|
1486
|
+
exports.BaseError = BaseError;
|
|
1283
1487
|
exports.SUPPORTED_STACKS_WALLETS = SUPPORTED_STACKS_WALLETS;
|
|
1284
1488
|
exports.StacksWalletProvider = StacksWalletProvider;
|
|
1489
|
+
exports.UnsupportedMethodError = UnsupportedMethodError;
|
|
1490
|
+
exports.WalletNotConnectedError = WalletNotConnectedError;
|
|
1491
|
+
exports.WalletNotFoundError = WalletNotFoundError;
|
|
1492
|
+
exports.WalletRequestError = WalletRequestError;
|
|
1285
1493
|
exports.createContractConfig = createContractConfig;
|
|
1286
1494
|
exports.getLocalStorageWallet = getLocalStorageWallet;
|
|
1287
1495
|
exports.getNetworkFromAddress = getNetworkFromAddress;
|