@satoshai/kit 0.1.1 → 0.3.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/LICENSE +21 -0
- package/README.md +40 -11
- package/dist/index.cjs +204 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -3
- package/dist/index.d.ts +37 -3
- package/dist/index.js +205 -47
- package/dist/index.js.map +1 -1
- package/package.json +25 -15
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WalletConnect, setSelectedProviderId, request, getSelectedProvider, clearSelectedProviderId } from '@stacks/connect';
|
|
2
|
-
import { createContext, useState, useEffect, useCallback, useMemo, useContext } from 'react';
|
|
2
|
+
import { createContext, useState, useRef, useEffect, useCallback, useMemo, useContext } from 'react';
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
import { PostConditionMode, postConditionToHex, cvToHex } from '@stacks/transactions';
|
|
5
5
|
import { getPrimaryName } from 'bns-v2-sdk';
|
|
@@ -160,15 +160,18 @@ var useXverse = ({
|
|
|
160
160
|
}, [provider]);
|
|
161
161
|
useEffect(() => {
|
|
162
162
|
if (provider !== "xverse" || !address || !isProviderReady) return;
|
|
163
|
+
let cancelled = false;
|
|
163
164
|
let removeListener;
|
|
164
165
|
const setupXverse = async () => {
|
|
165
166
|
try {
|
|
166
167
|
const productInfo = await getXverseProductInfo();
|
|
168
|
+
if (cancelled) return;
|
|
167
169
|
if (!shouldSupportAccountChange(productInfo?.version)) return;
|
|
168
170
|
const response = await getSelectedProvider()?.request(
|
|
169
171
|
"wallet_connect",
|
|
170
172
|
null
|
|
171
173
|
);
|
|
174
|
+
if (cancelled) return;
|
|
172
175
|
extractAndValidateStacksAddress(
|
|
173
176
|
response?.result?.addresses,
|
|
174
177
|
address,
|
|
@@ -192,6 +195,7 @@ var useXverse = ({
|
|
|
192
195
|
};
|
|
193
196
|
void setupXverse();
|
|
194
197
|
return () => {
|
|
198
|
+
cancelled = true;
|
|
195
199
|
if (!removeListener) return;
|
|
196
200
|
try {
|
|
197
201
|
removeListener();
|
|
@@ -222,6 +226,7 @@ var StacksWalletContext = createContext(
|
|
|
222
226
|
);
|
|
223
227
|
var StacksWalletProvider = ({
|
|
224
228
|
children,
|
|
229
|
+
wallets,
|
|
225
230
|
walletConnect,
|
|
226
231
|
onConnect,
|
|
227
232
|
onAddressChange,
|
|
@@ -230,6 +235,16 @@ var StacksWalletProvider = ({
|
|
|
230
235
|
const [address, setAddress] = useState();
|
|
231
236
|
const [provider, setProvider] = useState();
|
|
232
237
|
const [isConnecting, setIsConnecting] = useState(false);
|
|
238
|
+
const connectGenRef = useRef(0);
|
|
239
|
+
const wcInitRef = useRef(null);
|
|
240
|
+
const walletsKey = wallets?.join(",");
|
|
241
|
+
useEffect(() => {
|
|
242
|
+
if (wallets?.includes("wallet-connect") && !walletConnect?.projectId) {
|
|
243
|
+
throw new Error(
|
|
244
|
+
'StacksWalletProvider: "wallet-connect" is listed in wallets but no walletConnect.projectId was provided.'
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
}, [walletsKey, walletConnect?.projectId]);
|
|
233
248
|
useEffect(() => {
|
|
234
249
|
const loadPersistedWallet = async () => {
|
|
235
250
|
const persisted = getLocalStorageWallet();
|
|
@@ -242,6 +257,18 @@ var StacksWalletProvider = ({
|
|
|
242
257
|
setProvider(data.provider);
|
|
243
258
|
return;
|
|
244
259
|
}
|
|
260
|
+
if (persisted.provider === "wallet-connect" && walletConnect?.projectId) {
|
|
261
|
+
const initPromise = WalletConnect.initializeProvider(
|
|
262
|
+
buildWalletConnectConfig(
|
|
263
|
+
walletConnect.projectId,
|
|
264
|
+
walletConnect.metadata,
|
|
265
|
+
walletConnect.chains
|
|
266
|
+
)
|
|
267
|
+
);
|
|
268
|
+
wcInitRef.current = initPromise;
|
|
269
|
+
await initPromise;
|
|
270
|
+
wcInitRef.current = null;
|
|
271
|
+
}
|
|
245
272
|
setAddress(persisted.address);
|
|
246
273
|
setProvider(persisted.provider);
|
|
247
274
|
setSelectedProviderId(
|
|
@@ -254,7 +281,7 @@ var StacksWalletProvider = ({
|
|
|
254
281
|
}
|
|
255
282
|
};
|
|
256
283
|
void loadPersistedWallet();
|
|
257
|
-
}, []);
|
|
284
|
+
}, [walletConnect?.projectId]);
|
|
258
285
|
const connect = useCallback(
|
|
259
286
|
async (providerId, options) => {
|
|
260
287
|
const typedProvider = SUPPORTED_STACKS_WALLETS.find(
|
|
@@ -284,10 +311,12 @@ var StacksWalletProvider = ({
|
|
|
284
311
|
options?.onError?.(error);
|
|
285
312
|
return;
|
|
286
313
|
}
|
|
314
|
+
const gen = ++connectGenRef.current;
|
|
287
315
|
setIsConnecting(true);
|
|
288
316
|
try {
|
|
289
317
|
if (typedProvider === "okx") {
|
|
290
318
|
const data2 = await getOKXStacksAddress();
|
|
319
|
+
if (connectGenRef.current !== gen) return;
|
|
291
320
|
setAddress(data2.address);
|
|
292
321
|
setProvider(data2.provider);
|
|
293
322
|
options?.onSuccess?.(data2.address, data2.provider);
|
|
@@ -296,17 +325,25 @@ var StacksWalletProvider = ({
|
|
|
296
325
|
setSelectedProviderId(
|
|
297
326
|
STACKS_TO_STACKS_CONNECT_PROVIDERS[typedProvider]
|
|
298
327
|
);
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
328
|
+
const wcConfig = typedProvider === "wallet-connect" && walletConnect ? buildWalletConnectConfig(
|
|
329
|
+
walletConnect.projectId,
|
|
330
|
+
walletConnect.metadata,
|
|
331
|
+
walletConnect.chains
|
|
332
|
+
) : void 0;
|
|
333
|
+
if (wcConfig) {
|
|
334
|
+
if (wcInitRef.current) await wcInitRef.current;
|
|
335
|
+
const initPromise = WalletConnect.initializeProvider(wcConfig);
|
|
336
|
+
wcInitRef.current = initPromise;
|
|
337
|
+
await initPromise;
|
|
338
|
+
wcInitRef.current = null;
|
|
339
|
+
}
|
|
340
|
+
if (connectGenRef.current !== gen) return;
|
|
341
|
+
const data = wcConfig ? await request(
|
|
342
|
+
{ walletConnect: wcConfig },
|
|
307
343
|
"getAddresses",
|
|
308
344
|
{}
|
|
309
345
|
) : await request("getAddresses");
|
|
346
|
+
if (connectGenRef.current !== gen) return;
|
|
310
347
|
const extractedAddress = extractStacksAddress(
|
|
311
348
|
typedProvider,
|
|
312
349
|
data.addresses
|
|
@@ -315,16 +352,26 @@ var StacksWalletProvider = ({
|
|
|
315
352
|
setProvider(typedProvider);
|
|
316
353
|
options?.onSuccess?.(extractedAddress, typedProvider);
|
|
317
354
|
} catch (error) {
|
|
355
|
+
if (connectGenRef.current !== gen) return;
|
|
318
356
|
console.error("Failed to connect wallet:", error);
|
|
319
|
-
|
|
320
|
-
|
|
357
|
+
if (typedProvider !== "okx") {
|
|
358
|
+
getSelectedProvider()?.disconnect?.();
|
|
359
|
+
clearSelectedProviderId();
|
|
360
|
+
}
|
|
321
361
|
options?.onError?.(error);
|
|
322
362
|
} finally {
|
|
323
|
-
|
|
363
|
+
if (connectGenRef.current === gen) {
|
|
364
|
+
setIsConnecting(false);
|
|
365
|
+
}
|
|
324
366
|
}
|
|
325
367
|
},
|
|
326
368
|
[walletConnect]
|
|
327
369
|
);
|
|
370
|
+
const reset = useCallback(() => {
|
|
371
|
+
connectGenRef.current++;
|
|
372
|
+
setIsConnecting(false);
|
|
373
|
+
clearSelectedProviderId();
|
|
374
|
+
}, []);
|
|
328
375
|
const disconnect = useCallback(
|
|
329
376
|
(callback) => {
|
|
330
377
|
localStorage.removeItem(LOCAL_STORAGE_STACKS);
|
|
@@ -357,6 +404,14 @@ var StacksWalletProvider = ({
|
|
|
357
404
|
},
|
|
358
405
|
connect
|
|
359
406
|
});
|
|
407
|
+
const walletInfos = useMemo(() => {
|
|
408
|
+
const { installed } = getStacksWallets();
|
|
409
|
+
const configured = wallets ?? [...SUPPORTED_STACKS_WALLETS];
|
|
410
|
+
return configured.map((w) => ({
|
|
411
|
+
id: w,
|
|
412
|
+
available: w === "wallet-connect" ? !!walletConnect?.projectId : installed.includes(w)
|
|
413
|
+
}));
|
|
414
|
+
}, [walletsKey, walletConnect?.projectId]);
|
|
360
415
|
const value = useMemo(() => {
|
|
361
416
|
const walletState = isConnecting ? { status: "connecting", address: void 0, provider: void 0 } : address && provider ? { status: "connected", address, provider } : {
|
|
362
417
|
status: "disconnected",
|
|
@@ -366,9 +421,11 @@ var StacksWalletProvider = ({
|
|
|
366
421
|
return {
|
|
367
422
|
...walletState,
|
|
368
423
|
connect,
|
|
369
|
-
disconnect
|
|
424
|
+
disconnect,
|
|
425
|
+
reset,
|
|
426
|
+
wallets: walletInfos
|
|
370
427
|
};
|
|
371
|
-
}, [address, provider, isConnecting, connect, disconnect]);
|
|
428
|
+
}, [address, provider, isConnecting, connect, disconnect, reset, walletInfos]);
|
|
372
429
|
return /* @__PURE__ */ jsx(StacksWalletContext.Provider, { value, children });
|
|
373
430
|
};
|
|
374
431
|
var useStacksWalletContext = () => {
|
|
@@ -402,37 +459,108 @@ var useAddress = () => {
|
|
|
402
459
|
}, [address, status, provider]);
|
|
403
460
|
};
|
|
404
461
|
var useConnect = () => {
|
|
405
|
-
const {
|
|
462
|
+
const {
|
|
463
|
+
connect: contextConnect,
|
|
464
|
+
reset: contextReset,
|
|
465
|
+
status: walletStatus
|
|
466
|
+
} = useStacksWalletContext();
|
|
467
|
+
const [error, setError] = useState(null);
|
|
468
|
+
const [mutationStatus, setMutationStatus] = useState("idle");
|
|
469
|
+
const connect = useCallback(
|
|
470
|
+
async (providerId, options) => {
|
|
471
|
+
setError(null);
|
|
472
|
+
setMutationStatus("pending");
|
|
473
|
+
let settled = false;
|
|
474
|
+
try {
|
|
475
|
+
await contextConnect(providerId, {
|
|
476
|
+
onSuccess: (address, provider) => {
|
|
477
|
+
settled = true;
|
|
478
|
+
setMutationStatus("success");
|
|
479
|
+
options?.onSuccess?.(address, provider);
|
|
480
|
+
},
|
|
481
|
+
onError: (err) => {
|
|
482
|
+
settled = true;
|
|
483
|
+
setError(err);
|
|
484
|
+
setMutationStatus("error");
|
|
485
|
+
options?.onError?.(err);
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
} finally {
|
|
489
|
+
if (!settled) {
|
|
490
|
+
setMutationStatus("idle");
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
},
|
|
494
|
+
[contextConnect]
|
|
495
|
+
);
|
|
496
|
+
const reset = useCallback(() => {
|
|
497
|
+
setError(null);
|
|
498
|
+
setMutationStatus("idle");
|
|
499
|
+
contextReset();
|
|
500
|
+
}, [contextReset]);
|
|
406
501
|
const value = useMemo(
|
|
407
502
|
() => ({
|
|
408
503
|
connect,
|
|
409
|
-
|
|
410
|
-
|
|
504
|
+
reset,
|
|
505
|
+
error,
|
|
506
|
+
isError: mutationStatus === "error",
|
|
507
|
+
isIdle: mutationStatus === "idle",
|
|
508
|
+
isPending: mutationStatus === "pending" || walletStatus === "connecting",
|
|
509
|
+
isSuccess: mutationStatus === "success",
|
|
510
|
+
status: mutationStatus
|
|
411
511
|
}),
|
|
412
|
-
[connect,
|
|
512
|
+
[connect, reset, error, mutationStatus, walletStatus]
|
|
413
513
|
);
|
|
414
514
|
return value;
|
|
415
515
|
};
|
|
416
516
|
var useDisconnect = () => {
|
|
417
|
-
const { disconnect } = useStacksWalletContext();
|
|
418
|
-
|
|
517
|
+
const { disconnect: contextDisconnect } = useStacksWalletContext();
|
|
518
|
+
const [error, setError] = useState(null);
|
|
519
|
+
const [mutationStatus, setMutationStatus] = useState("idle");
|
|
520
|
+
const disconnect = useCallback(
|
|
521
|
+
(callback) => {
|
|
522
|
+
setError(null);
|
|
523
|
+
try {
|
|
524
|
+
contextDisconnect(callback);
|
|
525
|
+
setMutationStatus("success");
|
|
526
|
+
} catch (err) {
|
|
527
|
+
const normalizedError = err instanceof Error ? err : new Error(String(err));
|
|
528
|
+
setError(normalizedError);
|
|
529
|
+
setMutationStatus("error");
|
|
530
|
+
}
|
|
531
|
+
},
|
|
532
|
+
[contextDisconnect]
|
|
533
|
+
);
|
|
534
|
+
const reset = useCallback(() => {
|
|
535
|
+
setError(null);
|
|
536
|
+
setMutationStatus("idle");
|
|
537
|
+
}, []);
|
|
538
|
+
const value = useMemo(
|
|
419
539
|
() => ({
|
|
420
|
-
disconnect
|
|
540
|
+
disconnect,
|
|
541
|
+
reset,
|
|
542
|
+
error,
|
|
543
|
+
isError: mutationStatus === "error",
|
|
544
|
+
isIdle: mutationStatus === "idle",
|
|
545
|
+
isPending: mutationStatus === "pending",
|
|
546
|
+
isSuccess: mutationStatus === "success",
|
|
547
|
+
status: mutationStatus
|
|
421
548
|
}),
|
|
422
|
-
[disconnect]
|
|
549
|
+
[disconnect, reset, error, mutationStatus]
|
|
423
550
|
);
|
|
551
|
+
return value;
|
|
424
552
|
};
|
|
425
553
|
var useSignMessage = () => {
|
|
426
554
|
const { isConnected, provider } = useAddress();
|
|
427
555
|
const [data, setData] = useState(void 0);
|
|
428
556
|
const [error, setError] = useState(null);
|
|
429
|
-
const [
|
|
557
|
+
const [status, setStatus] = useState("idle");
|
|
430
558
|
const signMessageAsync = useCallback(
|
|
431
559
|
async (variables) => {
|
|
432
560
|
if (!isConnected) {
|
|
433
561
|
throw new Error("Wallet is not connected");
|
|
434
562
|
}
|
|
435
|
-
|
|
563
|
+
setStatus("pending");
|
|
436
564
|
setError(null);
|
|
437
565
|
setData(void 0);
|
|
438
566
|
try {
|
|
@@ -453,12 +581,12 @@ var useSignMessage = () => {
|
|
|
453
581
|
});
|
|
454
582
|
}
|
|
455
583
|
setData(result);
|
|
456
|
-
|
|
584
|
+
setStatus("success");
|
|
457
585
|
return result;
|
|
458
586
|
} catch (err) {
|
|
459
587
|
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
460
588
|
setError(error2);
|
|
461
|
-
|
|
589
|
+
setStatus("error");
|
|
462
590
|
throw error2;
|
|
463
591
|
}
|
|
464
592
|
},
|
|
@@ -476,13 +604,26 @@ var useSignMessage = () => {
|
|
|
476
604
|
},
|
|
477
605
|
[signMessageAsync]
|
|
478
606
|
);
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
607
|
+
const reset = useCallback(() => {
|
|
608
|
+
setData(void 0);
|
|
609
|
+
setError(null);
|
|
610
|
+
setStatus("idle");
|
|
611
|
+
}, []);
|
|
612
|
+
return useMemo(
|
|
613
|
+
() => ({
|
|
614
|
+
signMessage,
|
|
615
|
+
signMessageAsync,
|
|
616
|
+
reset,
|
|
617
|
+
data,
|
|
618
|
+
error,
|
|
619
|
+
isError: status === "error",
|
|
620
|
+
isIdle: status === "idle",
|
|
621
|
+
isPending: status === "pending",
|
|
622
|
+
isSuccess: status === "success",
|
|
623
|
+
status
|
|
624
|
+
}),
|
|
625
|
+
[signMessage, signMessageAsync, reset, data, error, status]
|
|
626
|
+
);
|
|
486
627
|
};
|
|
487
628
|
|
|
488
629
|
// src/utils/get-network-from-address.ts
|
|
@@ -503,13 +644,13 @@ var useWriteContract = () => {
|
|
|
503
644
|
const { isConnected, address, provider } = useAddress();
|
|
504
645
|
const [data, setData] = useState(void 0);
|
|
505
646
|
const [error, setError] = useState(null);
|
|
506
|
-
const [
|
|
647
|
+
const [status, setStatus] = useState("idle");
|
|
507
648
|
const writeContractAsync = useCallback(
|
|
508
649
|
async (variables) => {
|
|
509
650
|
if (!isConnected || !address) {
|
|
510
651
|
throw new Error("Wallet is not connected");
|
|
511
652
|
}
|
|
512
|
-
|
|
653
|
+
setStatus("pending");
|
|
513
654
|
setError(null);
|
|
514
655
|
setData(void 0);
|
|
515
656
|
try {
|
|
@@ -531,7 +672,7 @@ var useWriteContract = () => {
|
|
|
531
672
|
anchorMode: 3
|
|
532
673
|
});
|
|
533
674
|
setData(response2.txHash);
|
|
534
|
-
|
|
675
|
+
setStatus("success");
|
|
535
676
|
return response2.txHash;
|
|
536
677
|
}
|
|
537
678
|
const response = await request("stx_callContract", {
|
|
@@ -547,12 +688,12 @@ var useWriteContract = () => {
|
|
|
547
688
|
throw new Error("No transaction ID returned");
|
|
548
689
|
}
|
|
549
690
|
setData(response.txid);
|
|
550
|
-
|
|
691
|
+
setStatus("success");
|
|
551
692
|
return response.txid;
|
|
552
693
|
} catch (err) {
|
|
553
694
|
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
554
695
|
setError(error2);
|
|
555
|
-
|
|
696
|
+
setStatus("error");
|
|
556
697
|
throw error2;
|
|
557
698
|
}
|
|
558
699
|
},
|
|
@@ -570,13 +711,26 @@ var useWriteContract = () => {
|
|
|
570
711
|
},
|
|
571
712
|
[writeContractAsync]
|
|
572
713
|
);
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
714
|
+
const reset = useCallback(() => {
|
|
715
|
+
setData(void 0);
|
|
716
|
+
setError(null);
|
|
717
|
+
setStatus("idle");
|
|
718
|
+
}, []);
|
|
719
|
+
return useMemo(
|
|
720
|
+
() => ({
|
|
721
|
+
writeContract,
|
|
722
|
+
writeContractAsync,
|
|
723
|
+
reset,
|
|
724
|
+
data,
|
|
725
|
+
error,
|
|
726
|
+
isError: status === "error",
|
|
727
|
+
isIdle: status === "idle",
|
|
728
|
+
isPending: status === "pending",
|
|
729
|
+
isSuccess: status === "success",
|
|
730
|
+
status
|
|
731
|
+
}),
|
|
732
|
+
[writeContract, writeContractAsync, reset, data, error, status]
|
|
733
|
+
);
|
|
580
734
|
};
|
|
581
735
|
var useBnsName = (address) => {
|
|
582
736
|
const [bnsName, setBnsName] = useState(null);
|
|
@@ -604,7 +758,11 @@ var useBnsName = (address) => {
|
|
|
604
758
|
}, [address]);
|
|
605
759
|
return { bnsName, isLoading };
|
|
606
760
|
};
|
|
761
|
+
var useWallets = () => {
|
|
762
|
+
const { wallets } = useStacksWalletContext();
|
|
763
|
+
return useMemo(() => ({ wallets }), [wallets]);
|
|
764
|
+
};
|
|
607
765
|
|
|
608
|
-
export { SUPPORTED_STACKS_WALLETS, StacksWalletProvider, getLocalStorageWallet, getNetworkFromAddress, getStacksWallets, useAddress, useBnsName, useConnect, useDisconnect, useSignMessage, useWriteContract };
|
|
766
|
+
export { SUPPORTED_STACKS_WALLETS, StacksWalletProvider, getLocalStorageWallet, getNetworkFromAddress, getStacksWallets, useAddress, useBnsName, useConnect, useDisconnect, useSignMessage, useWallets, useWriteContract };
|
|
609
767
|
//# sourceMappingURL=index.js.map
|
|
610
768
|
//# sourceMappingURL=index.js.map
|