@satoshai/kit 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ import { getPrimaryName } from 'bns-v2-sdk';
7
7
  // src/errors.ts
8
8
  var BaseError = class extends Error {
9
9
  name = "StacksKitError";
10
+ /** Short, human-readable error summary without details or cause chain. */
10
11
  shortMessage;
11
12
  constructor(shortMessage, options) {
12
13
  const message = [
@@ -16,6 +17,10 @@ var BaseError = class extends Error {
16
17
  super(message, options?.cause ? { cause: options.cause } : void 0);
17
18
  this.shortMessage = shortMessage;
18
19
  }
20
+ /**
21
+ * Walk the error cause chain. If `fn` is provided, returns the first error
22
+ * where `fn` returns `true`; otherwise returns the root cause.
23
+ */
19
24
  walk(fn) {
20
25
  return walk(this, fn);
21
26
  }
@@ -35,6 +40,7 @@ var WalletNotConnectedError = class extends BaseError {
35
40
  };
36
41
  var WalletNotFoundError = class extends BaseError {
37
42
  name = "WalletNotFoundError";
43
+ /** The wallet ID that was not found. */
38
44
  wallet;
39
45
  constructor({ wallet }) {
40
46
  super(`${wallet} wallet not found`, {
@@ -45,7 +51,9 @@ var WalletNotFoundError = class extends BaseError {
45
51
  };
46
52
  var UnsupportedMethodError = class extends BaseError {
47
53
  name = "UnsupportedMethodError";
54
+ /** The SIP-030 method name that is not supported. */
48
55
  method;
56
+ /** The wallet that does not support the method. */
49
57
  wallet;
50
58
  constructor({ method, wallet }) {
51
59
  super(`${method} is not supported by ${wallet} wallet`);
@@ -55,7 +63,9 @@ var UnsupportedMethodError = class extends BaseError {
55
63
  };
56
64
  var WalletRequestError = class extends BaseError {
57
65
  name = "WalletRequestError";
66
+ /** The SIP-030 method name that failed. */
58
67
  method;
68
+ /** The wallet that returned the error. */
59
69
  wallet;
60
70
  constructor({ method, wallet, cause }) {
61
71
  super(`${wallet} wallet request failed`, {
@@ -212,6 +222,102 @@ var extractStacksAddress = (typedProvider, addresses) => {
212
222
  `No valid Stacks address found for ${typedProvider} wallet`
213
223
  );
214
224
  };
225
+
226
+ // src/hooks/use-wallet-connect/use-wallet-connect.helpers.ts
227
+ var getWcUniversalProvider = () => window.WalletConnectProvider?.connector?.provider ?? null;
228
+ var extractStacksAddress2 = (accounts) => {
229
+ for (const entry of accounts) {
230
+ if (typeof entry === "object" && entry !== null && "address" in entry) {
231
+ return entry.address;
232
+ }
233
+ if (typeof entry === "string") {
234
+ if (entry.startsWith("S")) return entry;
235
+ if (entry.startsWith("stacks:")) return entry.split(":")[2] ?? null;
236
+ }
237
+ }
238
+ return null;
239
+ };
240
+ var PING_TIMEOUT_MS = 1e4;
241
+ var pingSession = async () => {
242
+ const wcProvider = getWcUniversalProvider();
243
+ const client = wcProvider?.client;
244
+ const session = wcProvider?.session;
245
+ if (!client || !session) return false;
246
+ try {
247
+ await Promise.race([
248
+ client.ping({ topic: session.topic }),
249
+ new Promise(
250
+ (_, reject) => setTimeout(() => reject(new Error("Ping timeout")), PING_TIMEOUT_MS)
251
+ )
252
+ ]);
253
+ return true;
254
+ } catch {
255
+ return false;
256
+ }
257
+ };
258
+
259
+ // src/hooks/use-wallet-connect/use-wallet-connect.ts
260
+ var useWalletConnect = ({
261
+ address,
262
+ provider,
263
+ onAddressChange,
264
+ onDisconnect
265
+ }) => {
266
+ useEffect(() => {
267
+ if (provider !== "wallet-connect" || !address) return;
268
+ let cancelled = false;
269
+ const validateSession = async () => {
270
+ const alive = await pingSession();
271
+ if (cancelled) return;
272
+ if (!alive) {
273
+ const wcProvider = getWcUniversalProvider();
274
+ try {
275
+ await wcProvider?.disconnect();
276
+ } catch {
277
+ }
278
+ clearSelectedProviderId();
279
+ onDisconnect();
280
+ }
281
+ };
282
+ void validateSession();
283
+ return () => {
284
+ cancelled = true;
285
+ };
286
+ }, [provider, address, onDisconnect]);
287
+ useEffect(() => {
288
+ if (provider !== "wallet-connect" || !address) return;
289
+ const wcProvider = getWcUniversalProvider();
290
+ if (!wcProvider) return;
291
+ const handleDisconnect = () => {
292
+ clearSelectedProviderId();
293
+ onDisconnect();
294
+ };
295
+ const handleAccountsChanged = (...args) => {
296
+ const accounts = args[0];
297
+ const newAddress = extractStacksAddress2(accounts);
298
+ if (newAddress && newAddress !== address) {
299
+ onAddressChange(newAddress);
300
+ }
301
+ };
302
+ wcProvider.on("disconnect", handleDisconnect);
303
+ wcProvider.on("accountsChanged", handleAccountsChanged);
304
+ wcProvider.on("stx_accountChange", handleAccountsChanged);
305
+ wcProvider.on("stx_accountsChanged", handleAccountsChanged);
306
+ return () => {
307
+ try {
308
+ wcProvider.off("disconnect", handleDisconnect);
309
+ wcProvider.off("accountsChanged", handleAccountsChanged);
310
+ wcProvider.off("stx_accountChange", handleAccountsChanged);
311
+ wcProvider.off("stx_accountsChanged", handleAccountsChanged);
312
+ } catch (error) {
313
+ console.error(
314
+ "Failed to remove WalletConnect listeners:",
315
+ error
316
+ );
317
+ }
318
+ };
319
+ }, [address, provider, onAddressChange, onDisconnect]);
320
+ };
215
321
  var getXverseProductInfo = async () => await window.XverseProviders?.StacksProvider?.getProductInfo?.() ?? null;
216
322
  var shouldSupportAccountChange = (version) => version !== void 0 && version !== "1.0.0";
217
323
  var waitForXverseProvider = async (maxAttempts = 10, initialDelay = 200) => {
@@ -590,6 +696,18 @@ var StacksWalletProvider = ({
590
696
  onAddressChange: handleAddressChange,
591
697
  connect
592
698
  });
699
+ const handleWcDisconnect = useCallback(() => {
700
+ localStorage.removeItem(LOCAL_STORAGE_STACKS);
701
+ setAddress(void 0);
702
+ setProvider(void 0);
703
+ onDisconnect?.();
704
+ }, [onDisconnect]);
705
+ useWalletConnect({
706
+ address,
707
+ provider,
708
+ onAddressChange: handleAddressChange,
709
+ onDisconnect: handleWcDisconnect
710
+ });
593
711
  const { installed } = getStacksWallets();
594
712
  const configured = wallets ?? [...SUPPORTED_STACKS_WALLETS];
595
713
  const walletInfos = configured.map((w) => ({