@satoshai/kit 0.3.1 → 0.4.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/README.md +44 -15
- package/dist/index.cjs +157 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -4
- package/dist/index.d.ts +9 -4
- package/dist/index.js +158 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ pnpm add @satoshai/kit @stacks/transactions react react-dom
|
|
|
23
23
|
## Quick Start
|
|
24
24
|
|
|
25
25
|
```tsx
|
|
26
|
-
import { StacksWalletProvider, useConnect,
|
|
26
|
+
import { StacksWalletProvider, useConnect, useAddress, useDisconnect } from '@satoshai/kit';
|
|
27
27
|
|
|
28
28
|
function App() {
|
|
29
29
|
return (
|
|
@@ -35,7 +35,6 @@ function App() {
|
|
|
35
35
|
|
|
36
36
|
function Wallet() {
|
|
37
37
|
const { connect, reset, isPending } = useConnect();
|
|
38
|
-
const { wallets } = useWallets();
|
|
39
38
|
const { address, isConnected } = useAddress();
|
|
40
39
|
const { disconnect } = useDisconnect();
|
|
41
40
|
|
|
@@ -51,11 +50,7 @@ function Wallet() {
|
|
|
51
50
|
return (
|
|
52
51
|
<div>
|
|
53
52
|
{isPending && <button onClick={reset}>Cancel</button>}
|
|
54
|
-
{
|
|
55
|
-
<button key={id} onClick={() => connect(id)} disabled={!available || isPending}>
|
|
56
|
-
{id}
|
|
57
|
-
</button>
|
|
58
|
-
))}
|
|
53
|
+
<button onClick={() => connect()} disabled={isPending}>Connect Wallet</button>
|
|
59
54
|
</div>
|
|
60
55
|
);
|
|
61
56
|
}
|
|
@@ -70,6 +65,7 @@ Wrap your app to provide wallet context to all hooks.
|
|
|
70
65
|
```tsx
|
|
71
66
|
<StacksWalletProvider
|
|
72
67
|
wallets={['xverse', 'leather', 'wallet-connect']} // optional — defaults to all supported
|
|
68
|
+
connectModal={true} // optional — defaults to true
|
|
73
69
|
walletConnect={{ projectId: '...' }} // optional — enables WalletConnect
|
|
74
70
|
onConnect={(provider, address) => {}} // optional
|
|
75
71
|
onAddressChange={(newAddress) => {}} // optional — Xverse account switching
|
|
@@ -83,11 +79,38 @@ Wrap your app to provide wallet context to all hooks.
|
|
|
83
79
|
|
|
84
80
|
> **Important:** Define `wallets` and `walletConnect` outside of your component (or memoize them) so they remain referentially stable across renders. These values are treated as static configuration.
|
|
85
81
|
|
|
82
|
+
#### `connectModal` (default: `true`)
|
|
83
|
+
|
|
84
|
+
Controls whether `connect()` with no arguments shows `@stacks/connect`'s built-in wallet selection modal.
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
// Default — modal handles wallet selection
|
|
88
|
+
<StacksWalletProvider>
|
|
89
|
+
<App /> {/* connect() opens the modal */}
|
|
90
|
+
</StacksWalletProvider>
|
|
91
|
+
|
|
92
|
+
// Headless — manage wallet selection yourself (wagmi-style)
|
|
93
|
+
<StacksWalletProvider connectModal={false}>
|
|
94
|
+
<App /> {/* connect('xverse') only, connect() with no args is a no-op */}
|
|
95
|
+
</StacksWalletProvider>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
When `connectModal` is enabled:
|
|
99
|
+
- `connect()` with no args opens the `@stacks/connect` modal
|
|
100
|
+
- `connect('xverse')` with an explicit provider still bypasses the modal
|
|
101
|
+
- The `wallets` prop controls which wallets appear in the modal
|
|
102
|
+
- All 6 wallets are supported in the modal
|
|
103
|
+
- After the user picks a wallet, the kit automatically maps it back and sets state
|
|
104
|
+
|
|
86
105
|
### `useConnect()`
|
|
87
106
|
|
|
88
107
|
```ts
|
|
89
108
|
const { connect, reset, isPending } = useConnect();
|
|
90
109
|
|
|
110
|
+
// Open the @stacks/connect modal (when connectModal is enabled, the default)
|
|
111
|
+
await connect();
|
|
112
|
+
|
|
113
|
+
// Or connect to a specific wallet directly
|
|
91
114
|
await connect('xverse');
|
|
92
115
|
await connect('leather', {
|
|
93
116
|
onSuccess: (address, provider) => {},
|
|
@@ -102,16 +125,20 @@ reset();
|
|
|
102
125
|
|
|
103
126
|
### `useWallets()`
|
|
104
127
|
|
|
105
|
-
Returns all configured wallets with their availability status.
|
|
128
|
+
Returns all configured wallets with their name, icon, download link, and availability status. Metadata is sourced from `@stacks/connect`.
|
|
106
129
|
|
|
107
130
|
```ts
|
|
108
131
|
const { wallets } = useWallets();
|
|
109
|
-
// [{ id: 'xverse',
|
|
110
|
-
|
|
111
|
-
{wallets.map(({ id, available }) => (
|
|
112
|
-
<
|
|
113
|
-
{id}
|
|
114
|
-
|
|
132
|
+
// [{ id: 'xverse', name: 'Xverse Wallet', icon: 'data:image/svg+xml;...', webUrl: 'https://xverse.app', available: true }, ...]
|
|
133
|
+
|
|
134
|
+
{wallets.map(({ id, name, icon, webUrl, available }) => (
|
|
135
|
+
<div key={id}>
|
|
136
|
+
<button onClick={() => connect(id)} disabled={!available}>
|
|
137
|
+
{icon && <img src={icon} alt={name} width={20} height={20} />}
|
|
138
|
+
{name}
|
|
139
|
+
</button>
|
|
140
|
+
{!available && webUrl && <a href={webUrl} target="_blank">Install</a>}
|
|
141
|
+
</div>
|
|
115
142
|
))}
|
|
116
143
|
```
|
|
117
144
|
|
|
@@ -194,14 +221,16 @@ const { supported, installed } = getStacksWallets();
|
|
|
194
221
|
|
|
195
222
|
## Supported Wallets
|
|
196
223
|
|
|
224
|
+
All 6 wallets work with both headless (`connect('xverse')`) and modal (`connect()`) modes.
|
|
225
|
+
|
|
197
226
|
| Wallet | ID |
|
|
198
227
|
|---|---|
|
|
199
228
|
| Xverse | `xverse` |
|
|
200
229
|
| Leather | `leather` |
|
|
201
|
-
| OKX | `okx` |
|
|
202
230
|
| Asigna | `asigna` |
|
|
203
231
|
| Fordefi | `fordefi` |
|
|
204
232
|
| WalletConnect | `wallet-connect` |
|
|
233
|
+
| OKX | `okx` |
|
|
205
234
|
|
|
206
235
|
## Peer Dependencies
|
|
207
236
|
|
package/dist/index.cjs
CHANGED
|
@@ -10,10 +10,17 @@ var bnsV2Sdk = require('bns-v2-sdk');
|
|
|
10
10
|
var STACKS_TO_STACKS_CONNECT_PROVIDERS = {
|
|
11
11
|
xverse: "XverseProviders.BitcoinProvider",
|
|
12
12
|
leather: "LeatherProvider",
|
|
13
|
+
okx: "OkxStacksProvider",
|
|
13
14
|
asigna: "AsignaProvider",
|
|
14
15
|
fordefi: "FordefiProviders.UtxoProvider",
|
|
15
16
|
"wallet-connect": "WalletConnectProvider"
|
|
16
17
|
};
|
|
18
|
+
var STACKS_CONNECT_TO_STACKS_PROVIDERS = Object.fromEntries(
|
|
19
|
+
Object.entries(STACKS_TO_STACKS_CONNECT_PROVIDERS).map(([kit, connect]) => [
|
|
20
|
+
connect,
|
|
21
|
+
kit
|
|
22
|
+
])
|
|
23
|
+
);
|
|
17
24
|
|
|
18
25
|
// src/constants/storage-keys.ts
|
|
19
26
|
var LOCAL_STORAGE_STACKS = "@satoshai/kit";
|
|
@@ -22,10 +29,10 @@ var LOCAL_STORAGE_STACKS = "@satoshai/kit";
|
|
|
22
29
|
var SUPPORTED_STACKS_WALLETS = [
|
|
23
30
|
"xverse",
|
|
24
31
|
"leather",
|
|
25
|
-
"okx",
|
|
26
32
|
"asigna",
|
|
27
33
|
"fordefi",
|
|
28
|
-
"wallet-connect"
|
|
34
|
+
"wallet-connect",
|
|
35
|
+
"okx"
|
|
29
36
|
];
|
|
30
37
|
|
|
31
38
|
// src/utils/get-stacks-wallets.ts
|
|
@@ -37,7 +44,7 @@ var getStacksWallets = () => {
|
|
|
37
44
|
return { supported, installed };
|
|
38
45
|
};
|
|
39
46
|
var checkIfStacksProviderIsInstalled = (wallet) => {
|
|
40
|
-
if (typeof window === "undefined") return
|
|
47
|
+
if (typeof window === "undefined") return wallet === "wallet-connect";
|
|
41
48
|
switch (wallet) {
|
|
42
49
|
case "xverse":
|
|
43
50
|
return !!window.XverseProviders;
|
|
@@ -92,6 +99,38 @@ var getOKXStacksAddress = async () => {
|
|
|
92
99
|
provider: "okx"
|
|
93
100
|
};
|
|
94
101
|
};
|
|
102
|
+
var OKX_PROVIDER_META = {
|
|
103
|
+
id: "OkxStacksProvider",
|
|
104
|
+
name: "OKX Wallet",
|
|
105
|
+
icon: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiICAgICB4bWxuczp4b2RtPSJodHRwOi8vd3d3LmNvcmVsLmNvbS9jb3JlbGRyYXcvb2RtLzIwMDMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMjUwMCAyNTAwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAwIDI1MDA7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KICAgIC5zdDB7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7fQogICAgLnN0MXtmaWxsOiNGRkZGRkY7fQo8L3N0eWxlPgo8ZyBpZD0iTGF5ZXJfeDAwMjBfMSI+CiAgICA8ZyBpZD0iXzIxODczODEzMjM4NTYiPgogICAgICAgIDxyZWN0IHk9IjAiIGNsYXNzPSJzdDAiIHdpZHRoPSIyNTAwIiBoZWlnaHQ9IjI1MDAiPjwvcmVjdD4KICAgICAgICA8Zz4KICAgICAgICAgICAgPHBhdGggY2xhc3M9InN0MSIgZD0iTTE0NjMsMTAxNWgtNDA0Yy0xNywwLTMxLDE0LTMxLDMxdjQwNGMwLDE3LDE0LDMxLDMxLDMxaDQwNGMxNywwLDMxLTE0LDMxLTMxdi00MDQgICAgIEMxNDk0LDEwMjksMTQ4MCwxMDE1LDE0NjMsMTAxNXoiPjwvcGF0aD4KICAgICAgICAgICAgPHBhdGggY2xhc3M9InN0MSIgZD0iTTk5Niw1NDlINTkyYy0xNywwLTMxLDE0LTMxLDMxdjQwNGMwLDE3LDE0LDMxLDMxLDMxaDQwNGMxNywwLDMxLTE0LDMxLTMxVjU4MEMxMDI3LDU2MywxMDEzLDU0OSw5OTYsNTQ5eiI+PC9wYXRoPgogICAgICAgICAgICA8cGF0aCBjbGFzcz0ic3QxIiBkPSJNMTkzMCw1NDloLTQwNGMtMTcsMC0zMSwxNC0zMSwzMXY0MDRjMCwxNywxNCwzMSwzMSwzMWg0MDRjMTcsMCwzMS0xNCwzMS0zMVY1ODAgICAgIEMxOTYxLDU2MywxOTQ3LDU0OSwxOTMwLDU0OXoiPjwvcGF0aD4KICAgICAgICAgICAgPHBhdGggY2xhc3M9InN0MSIgZD0iTTk5NiwxNDgySDU5MmMtMTcsMC0zMSwxNC0zMSwzMXY0MDRjMCwxNywxNCwzMSwzMSwzMWg0MDRjMTcsMCwzMS0xNCwzMS0zMXYtNDA0ICAgICBDMTAyNywxNDk2LDEwMTMsMTQ4Miw5OTYsMTQ4MnoiPjwvcGF0aD4KICAgICAgICAgICAgPHBhdGggY2xhc3M9InN0MSIgZD0iTTE5MzAsMTQ4MmgtNDA0Yy0xNywwLTMxLDE0LTMxLDMxdjQwNGMwLDE3LDE0LDMxLDMxLDMxaDQwNGMxNywwLDMxLTE0LDMxLTMxdi00MDQgICAgIEMxOTYxLDE0OTYsMTk0NywxNDgyLDE5MzAsMTQ4MnoiPjwvcGF0aD4KICAgICAgICA8L2c+CiAgICA8L2c+CjwvZz4KPC9zdmc+",
|
|
106
|
+
webUrl: "https://www.okx.com/"
|
|
107
|
+
};
|
|
108
|
+
var registerOkxProvider = () => {
|
|
109
|
+
if (typeof window === "undefined") return;
|
|
110
|
+
if (!window.OkxStacksProvider) {
|
|
111
|
+
window.OkxStacksProvider = {
|
|
112
|
+
request: async (method) => {
|
|
113
|
+
if (method === "getAddresses") {
|
|
114
|
+
const data = await getOKXStacksAddress();
|
|
115
|
+
return {
|
|
116
|
+
result: {
|
|
117
|
+
addresses: [
|
|
118
|
+
{ address: data.address, symbol: "STX" }
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
throw new Error(
|
|
124
|
+
`OKX adapter: unsupported method "${method}". Use connect('okx') for direct OKX SDK access.`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
var unregisterOkxProvider = () => {
|
|
131
|
+
if (typeof window === "undefined") return;
|
|
132
|
+
delete window.OkxStacksProvider;
|
|
133
|
+
};
|
|
95
134
|
var extractStacksAddress = (typedProvider, addresses) => {
|
|
96
135
|
if (!addresses.length) {
|
|
97
136
|
throw new Error(`No addresses provided for ${typedProvider} wallet`);
|
|
@@ -223,12 +262,21 @@ var getLocalStorageWallet = () => {
|
|
|
223
262
|
return null;
|
|
224
263
|
}
|
|
225
264
|
};
|
|
265
|
+
var PROVIDER_META_BY_KIT_ID = Object.fromEntries(
|
|
266
|
+
[...connect.DEFAULT_PROVIDERS, connect.WALLET_CONNECT_PROVIDER, OKX_PROVIDER_META].map(
|
|
267
|
+
(p) => [
|
|
268
|
+
STACKS_CONNECT_TO_STACKS_PROVIDERS[p.id],
|
|
269
|
+
{ name: p.name, icon: p.icon ?? "", webUrl: p.webUrl ?? "" }
|
|
270
|
+
]
|
|
271
|
+
)
|
|
272
|
+
);
|
|
226
273
|
var StacksWalletContext = react.createContext(
|
|
227
274
|
void 0
|
|
228
275
|
);
|
|
229
276
|
var StacksWalletProvider = ({
|
|
230
277
|
children,
|
|
231
278
|
wallets,
|
|
279
|
+
connectModal = true,
|
|
232
280
|
walletConnect,
|
|
233
281
|
onConnect,
|
|
234
282
|
onAddressChange,
|
|
@@ -238,15 +286,23 @@ var StacksWalletProvider = ({
|
|
|
238
286
|
const [provider, setProvider] = react.useState();
|
|
239
287
|
const [isConnecting, setIsConnecting] = react.useState(false);
|
|
240
288
|
const connectGenRef = react.useRef(0);
|
|
289
|
+
const wasConnectedRef = react.useRef(false);
|
|
241
290
|
const wcInitRef = react.useRef(null);
|
|
291
|
+
const walletConnectRef = react.useRef(walletConnect);
|
|
292
|
+
walletConnectRef.current = walletConnect;
|
|
242
293
|
const walletsKey = wallets?.join(",");
|
|
294
|
+
if (wallets?.includes("wallet-connect") && !walletConnect?.projectId) {
|
|
295
|
+
throw new Error(
|
|
296
|
+
'StacksWalletProvider: "wallet-connect" is listed in wallets but no walletConnect.projectId was provided.'
|
|
297
|
+
);
|
|
298
|
+
}
|
|
243
299
|
react.useEffect(() => {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
);
|
|
300
|
+
const okxConfigured = !wallets || wallets.includes("okx");
|
|
301
|
+
if (connectModal && okxConfigured) {
|
|
302
|
+
registerOkxProvider();
|
|
303
|
+
return () => unregisterOkxProvider();
|
|
248
304
|
}
|
|
249
|
-
}, [
|
|
305
|
+
}, [connectModal, walletsKey]);
|
|
250
306
|
react.useEffect(() => {
|
|
251
307
|
const loadPersistedWallet = async () => {
|
|
252
308
|
const persisted = getLocalStorageWallet();
|
|
@@ -286,6 +342,65 @@ var StacksWalletProvider = ({
|
|
|
286
342
|
}, [walletConnect?.projectId]);
|
|
287
343
|
const connect$1 = react.useCallback(
|
|
288
344
|
async (providerId, options) => {
|
|
345
|
+
if (connectModal && !providerId) {
|
|
346
|
+
const gen2 = ++connectGenRef.current;
|
|
347
|
+
setIsConnecting(true);
|
|
348
|
+
try {
|
|
349
|
+
connect.clearSelectedProviderId();
|
|
350
|
+
const requestOptions = {
|
|
351
|
+
forceWalletSelect: true,
|
|
352
|
+
// OKX at the end so it appears last among installed wallets
|
|
353
|
+
defaultProviders: [
|
|
354
|
+
...connect.DEFAULT_PROVIDERS,
|
|
355
|
+
OKX_PROVIDER_META
|
|
356
|
+
]
|
|
357
|
+
};
|
|
358
|
+
if (wallets) {
|
|
359
|
+
requestOptions.approvedProviderIds = wallets.map(
|
|
360
|
+
(w) => STACKS_TO_STACKS_CONNECT_PROVIDERS[w]
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
const wc2 = walletConnectRef.current;
|
|
364
|
+
if (wc2?.projectId) {
|
|
365
|
+
requestOptions.walletConnect = buildWalletConnectConfig(
|
|
366
|
+
wc2.projectId,
|
|
367
|
+
wc2.metadata,
|
|
368
|
+
wc2.chains
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
const data = await connect.request(
|
|
372
|
+
requestOptions,
|
|
373
|
+
"getAddresses",
|
|
374
|
+
{}
|
|
375
|
+
);
|
|
376
|
+
if (connectGenRef.current !== gen2) return;
|
|
377
|
+
const selectedId = connect.getSelectedProviderId();
|
|
378
|
+
const resolvedProvider = selectedId ? STACKS_CONNECT_TO_STACKS_PROVIDERS[selectedId] : void 0;
|
|
379
|
+
if (!resolvedProvider) {
|
|
380
|
+
throw new Error(
|
|
381
|
+
`Unknown provider returned from @stacks/connect modal: ${selectedId ?? "none"}`
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
const extractedAddress = extractStacksAddress(
|
|
385
|
+
resolvedProvider,
|
|
386
|
+
data.addresses
|
|
387
|
+
);
|
|
388
|
+
setAddress(extractedAddress);
|
|
389
|
+
setProvider(resolvedProvider);
|
|
390
|
+
options?.onSuccess?.(extractedAddress, resolvedProvider);
|
|
391
|
+
} catch (error) {
|
|
392
|
+
if (connectGenRef.current !== gen2) return;
|
|
393
|
+
console.error("Failed to connect wallet:", error);
|
|
394
|
+
connect.getSelectedProvider()?.disconnect?.();
|
|
395
|
+
connect.clearSelectedProviderId();
|
|
396
|
+
options?.onError?.(error);
|
|
397
|
+
} finally {
|
|
398
|
+
if (connectGenRef.current === gen2) {
|
|
399
|
+
setIsConnecting(false);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
289
404
|
const typedProvider = SUPPORTED_STACKS_WALLETS.find(
|
|
290
405
|
(wallet) => wallet === providerId
|
|
291
406
|
);
|
|
@@ -305,7 +420,8 @@ var StacksWalletProvider = ({
|
|
|
305
420
|
options?.onError?.(error);
|
|
306
421
|
return;
|
|
307
422
|
}
|
|
308
|
-
|
|
423
|
+
const wc = walletConnectRef.current;
|
|
424
|
+
if (typedProvider === "wallet-connect" && !wc?.projectId) {
|
|
309
425
|
const error = new Error(
|
|
310
426
|
"WalletConnect requires a project ID. Please provide walletConnect.projectId to the StacksWalletProvider."
|
|
311
427
|
);
|
|
@@ -327,10 +443,10 @@ var StacksWalletProvider = ({
|
|
|
327
443
|
connect.setSelectedProviderId(
|
|
328
444
|
STACKS_TO_STACKS_CONNECT_PROVIDERS[typedProvider]
|
|
329
445
|
);
|
|
330
|
-
const wcConfig = typedProvider === "wallet-connect" &&
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
446
|
+
const wcConfig = typedProvider === "wallet-connect" && wc ? buildWalletConnectConfig(
|
|
447
|
+
wc.projectId,
|
|
448
|
+
wc.metadata,
|
|
449
|
+
wc.chains
|
|
334
450
|
) : void 0;
|
|
335
451
|
if (wcConfig) {
|
|
336
452
|
if (wcInitRef.current) await wcInitRef.current;
|
|
@@ -367,7 +483,7 @@ var StacksWalletProvider = ({
|
|
|
367
483
|
}
|
|
368
484
|
}
|
|
369
485
|
},
|
|
370
|
-
[
|
|
486
|
+
[connectModal, walletsKey]
|
|
371
487
|
);
|
|
372
488
|
const reset = react.useCallback(() => {
|
|
373
489
|
connectGenRef.current++;
|
|
@@ -394,24 +510,35 @@ var StacksWalletProvider = ({
|
|
|
394
510
|
);
|
|
395
511
|
}, [address, provider]);
|
|
396
512
|
react.useEffect(() => {
|
|
397
|
-
|
|
398
|
-
|
|
513
|
+
const isConnected = !!address && !!provider;
|
|
514
|
+
if (isConnected && !wasConnectedRef.current) {
|
|
515
|
+
onConnect?.(provider, address);
|
|
516
|
+
}
|
|
517
|
+
wasConnectedRef.current = isConnected;
|
|
399
518
|
}, [address, provider, onConnect]);
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
provider,
|
|
403
|
-
onAddressChange: (newAddress) => {
|
|
519
|
+
const handleAddressChange = react.useCallback(
|
|
520
|
+
(newAddress) => {
|
|
404
521
|
setAddress(newAddress);
|
|
405
522
|
onAddressChange?.(newAddress);
|
|
406
523
|
},
|
|
524
|
+
[onAddressChange]
|
|
525
|
+
);
|
|
526
|
+
useXverse({
|
|
527
|
+
address,
|
|
528
|
+
provider,
|
|
529
|
+
onAddressChange: handleAddressChange,
|
|
407
530
|
connect: connect$1
|
|
408
531
|
});
|
|
409
532
|
const { installed } = getStacksWallets();
|
|
410
533
|
const configured = wallets ?? [...SUPPORTED_STACKS_WALLETS];
|
|
411
534
|
const walletInfos = configured.map((w) => ({
|
|
412
535
|
id: w,
|
|
536
|
+
name: PROVIDER_META_BY_KIT_ID[w]?.name ?? w,
|
|
537
|
+
icon: PROVIDER_META_BY_KIT_ID[w]?.icon ?? "",
|
|
538
|
+
webUrl: PROVIDER_META_BY_KIT_ID[w]?.webUrl ?? "",
|
|
413
539
|
available: w === "wallet-connect" ? !!walletConnect?.projectId : installed.includes(w)
|
|
414
540
|
}));
|
|
541
|
+
const walletInfosKey = walletInfos.map((w) => `${w.id}:${w.available}`).join(",");
|
|
415
542
|
const value = react.useMemo(() => {
|
|
416
543
|
const walletState = isConnecting ? { status: "connecting", address: void 0, provider: void 0 } : address && provider ? { status: "connected", address, provider } : {
|
|
417
544
|
status: "disconnected",
|
|
@@ -425,7 +552,7 @@ var StacksWalletProvider = ({
|
|
|
425
552
|
reset,
|
|
426
553
|
wallets: walletInfos
|
|
427
554
|
};
|
|
428
|
-
}, [address, provider, isConnecting, connect$1, disconnect, reset,
|
|
555
|
+
}, [address, provider, isConnecting, connect$1, disconnect, reset, walletInfosKey]);
|
|
429
556
|
return /* @__PURE__ */ jsxRuntime.jsx(StacksWalletContext.Provider, { value, children });
|
|
430
557
|
};
|
|
431
558
|
var useStacksWalletContext = () => {
|
|
@@ -741,20 +868,28 @@ var useBnsName = (address) => {
|
|
|
741
868
|
setIsLoading(false);
|
|
742
869
|
return;
|
|
743
870
|
}
|
|
871
|
+
let cancelled = false;
|
|
744
872
|
const fetchBnsName = async () => {
|
|
745
873
|
setIsLoading(true);
|
|
746
874
|
try {
|
|
747
875
|
const network = getNetworkFromAddress(address);
|
|
748
876
|
const result = await bnsV2Sdk.getPrimaryName({ address, network });
|
|
877
|
+
if (cancelled) return;
|
|
749
878
|
const fullName = result ? `${result.name}.${result.namespace}` : null;
|
|
750
879
|
setBnsName(fullName);
|
|
751
880
|
} catch {
|
|
881
|
+
if (cancelled) return;
|
|
752
882
|
setBnsName(null);
|
|
753
883
|
} finally {
|
|
754
|
-
|
|
884
|
+
if (!cancelled) {
|
|
885
|
+
setIsLoading(false);
|
|
886
|
+
}
|
|
755
887
|
}
|
|
756
888
|
};
|
|
757
889
|
void fetchBnsName();
|
|
890
|
+
return () => {
|
|
891
|
+
cancelled = true;
|
|
892
|
+
};
|
|
758
893
|
}, [address]);
|
|
759
894
|
return { bnsName, isLoading };
|
|
760
895
|
};
|