otx-btc-wallet-react 0.1.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 ADDED
@@ -0,0 +1,726 @@
1
+ # otx-btc-wallet-react
2
+
3
+ React provider and hooks for the `otx-btc-wallet` library. Provides a complete set of hooks for connecting wallets, signing messages, signing PSBTs, and sending Bitcoin.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add otx-btc-wallet-react otx-btc-wallet-core otx-btc-wallet-connectors
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ### 1. Setup Provider
14
+
15
+ Wrap your app with `BtcWalletProvider` and pass a config created with `createConfig()`:
16
+
17
+ ```tsx
18
+ import { createConfig } from 'otx-btc-wallet-core';
19
+ import { BtcWalletProvider } from 'otx-btc-wallet-react';
20
+ import { UnisatConnector, XverseConnector } from 'otx-btc-wallet-connectors';
21
+
22
+ const config = createConfig({
23
+ connectors: [
24
+ new UnisatConnector(),
25
+ new XverseConnector(),
26
+ ],
27
+ });
28
+
29
+ function App() {
30
+ return (
31
+ <BtcWalletProvider config={config}>
32
+ <YourApp />
33
+ </BtcWalletProvider>
34
+ );
35
+ }
36
+ ```
37
+
38
+ ### 2. Use Hooks
39
+
40
+ ```tsx
41
+ import { useAccount, useConnect, useDisconnect } from 'otx-btc-wallet-react';
42
+
43
+ function WalletButton() {
44
+ const { address, isConnected } = useAccount();
45
+ const { connect, connectors, isLoading } = useConnect();
46
+ const { disconnect } = useDisconnect();
47
+
48
+ if (isConnected) {
49
+ return (
50
+ <div>
51
+ <p>{address}</p>
52
+ <button onClick={() => disconnect()}>Disconnect</button>
53
+ </div>
54
+ );
55
+ }
56
+
57
+ return (
58
+ <div>
59
+ {connectors.map((connector) => (
60
+ <button
61
+ key={connector.id}
62
+ onClick={() => connect({ connector })}
63
+ disabled={!connector.ready || isLoading}
64
+ >
65
+ {connector.name}
66
+ {!connector.ready && ' (not installed)'}
67
+ </button>
68
+ ))}
69
+ </div>
70
+ );
71
+ }
72
+ ```
73
+
74
+ ## Provider
75
+
76
+ ### `BtcWalletProvider`
77
+
78
+ Required wrapper component. Must be placed above any component that uses hooks.
79
+
80
+ ```tsx
81
+ import { BtcWalletProvider } from 'otx-btc-wallet-react';
82
+
83
+ <BtcWalletProvider config={config}>
84
+ {children}
85
+ </BtcWalletProvider>
86
+ ```
87
+
88
+ **Props:**
89
+
90
+ | Prop | Type | Description |
91
+ |------|------|-------------|
92
+ | `config` | `ResolvedConfig` | Config object from `createConfig()` |
93
+ | `children` | `ReactNode` | Child components |
94
+
95
+ **Behavior:**
96
+ - Provides the config context to all child hooks
97
+ - Handles auto-reconnect on mount if `autoConnect` is enabled and a previous wallet session exists
98
+
99
+ ## Hooks
100
+
101
+ ### `useConfig`
102
+
103
+ Access the config object directly. Useful for advanced store operations.
104
+
105
+ ```tsx
106
+ import { useConfig } from 'otx-btc-wallet-react';
107
+
108
+ function Debug() {
109
+ const config = useConfig();
110
+ const state = config.store.getState();
111
+
112
+ return <pre>{JSON.stringify(state, null, 2)}</pre>;
113
+ }
114
+ ```
115
+
116
+ **Returns:** `ResolvedConfig` - The full config object including the Zustand store.
117
+
118
+ ---
119
+
120
+ ### `useAccount`
121
+
122
+ Get the connected account information. Reactively updates when the account changes.
123
+
124
+ ```tsx
125
+ import { useAccount } from 'otx-btc-wallet-react';
126
+
127
+ function Account() {
128
+ const {
129
+ address, // string | undefined
130
+ publicKey, // string | undefined
131
+ addressType, // AddressType | undefined ('legacy' | 'nested-segwit' | 'segwit' | 'taproot')
132
+ account, // WalletAccount | undefined
133
+ connector, // BitcoinConnector | undefined
134
+ status, // ConnectionStatus
135
+ isConnected, // boolean
136
+ isConnecting, // boolean
137
+ isDisconnected, // boolean
138
+ isReconnecting, // boolean
139
+ } = useAccount();
140
+
141
+ if (!isConnected) return <p>Not connected</p>;
142
+
143
+ return (
144
+ <div>
145
+ <p>Address: {address}</p>
146
+ <p>Type: {addressType}</p>
147
+ <p>Public Key: {publicKey}</p>
148
+ </div>
149
+ );
150
+ }
151
+ ```
152
+
153
+ **Return Type: `UseAccountReturn`**
154
+
155
+ | Field | Type | Description |
156
+ |-------|------|-------------|
157
+ | `address` | `string \| undefined` | Connected Bitcoin address |
158
+ | `publicKey` | `string \| undefined` | Hex-encoded public key |
159
+ | `addressType` | `AddressType \| undefined` | Address type |
160
+ | `account` | `WalletAccount \| undefined` | Full account object |
161
+ | `connector` | `BitcoinConnector \| undefined` | Active connector instance |
162
+ | `status` | `ConnectionStatus` | `'connected'` \| `'connecting'` \| `'disconnected'` \| `'reconnecting'` |
163
+ | `isConnected` | `boolean` | `true` when status is `'connected'` |
164
+ | `isConnecting` | `boolean` | `true` when status is `'connecting'` |
165
+ | `isDisconnected` | `boolean` | `true` when status is `'disconnected'` |
166
+ | `isReconnecting` | `boolean` | `true` when status is `'reconnecting'` |
167
+
168
+ ---
169
+
170
+ ### `useConnect`
171
+
172
+ Connect to a wallet connector.
173
+
174
+ ```tsx
175
+ import { useConnect } from 'otx-btc-wallet-react';
176
+
177
+ function ConnectWallet() {
178
+ const {
179
+ connect, // (args: ConnectArgs) => void
180
+ connectAsync, // (args: ConnectArgs) => Promise<WalletAccount>
181
+ connectors, // BitcoinConnector[]
182
+ isLoading, // boolean
183
+ isSuccess, // boolean
184
+ isError, // boolean
185
+ error, // Error | null
186
+ reset, // () => void
187
+ } = useConnect();
188
+
189
+ return (
190
+ <div>
191
+ {connectors.map((connector) => (
192
+ <button
193
+ key={connector.id}
194
+ onClick={() => connect({ connector })}
195
+ disabled={!connector.ready || isLoading}
196
+ >
197
+ {connector.name}
198
+ {!connector.ready && ' (not installed)'}
199
+ </button>
200
+ ))}
201
+ {isError && <p>Error: {error?.message}</p>}
202
+ </div>
203
+ );
204
+ }
205
+ ```
206
+
207
+ **Connect Args:**
208
+
209
+ ```typescript
210
+ type ConnectArgs = {
211
+ connector: BitcoinConnector; // The connector to use
212
+ network?: BitcoinNetwork; // Optional network override
213
+ };
214
+ ```
215
+
216
+ **Return Type: `UseConnectReturn`**
217
+
218
+ | Field | Type | Description |
219
+ |-------|------|-------------|
220
+ | `connect` | `(args: ConnectArgs) => void` | Fire-and-forget connect |
221
+ | `connectAsync` | `(args: ConnectArgs) => Promise<WalletAccount>` | Connect and await result |
222
+ | `connectors` | `BitcoinConnector[]` | All registered connectors |
223
+ | `isLoading` | `boolean` | Connection in progress |
224
+ | `isSuccess` | `boolean` | Connection succeeded |
225
+ | `isError` | `boolean` | Connection failed |
226
+ | `error` | `Error \| null` | Error details |
227
+ | `reset` | `() => void` | Reset loading/error/success state |
228
+
229
+ **Async Usage:**
230
+
231
+ ```tsx
232
+ const handleConnect = async () => {
233
+ try {
234
+ const account = await connectAsync({ connector, network: 'testnet' });
235
+ console.log('Connected:', account.address);
236
+ } catch (err) {
237
+ console.error('Connection failed:', err);
238
+ }
239
+ };
240
+ ```
241
+
242
+ ---
243
+
244
+ ### `useDisconnect`
245
+
246
+ Disconnect the current wallet.
247
+
248
+ ```tsx
249
+ import { useDisconnect } from 'otx-btc-wallet-react';
250
+
251
+ function DisconnectButton() {
252
+ const {
253
+ disconnect, // () => void
254
+ disconnectAsync, // () => Promise<void>
255
+ isLoading, // boolean
256
+ isSuccess, // boolean
257
+ isError, // boolean
258
+ error, // Error | null
259
+ } = useDisconnect();
260
+
261
+ return (
262
+ <button onClick={() => disconnect()} disabled={isLoading}>
263
+ Disconnect
264
+ </button>
265
+ );
266
+ }
267
+ ```
268
+
269
+ **Return Type: `UseDisconnectReturn`**
270
+
271
+ | Field | Type | Description |
272
+ |-------|------|-------------|
273
+ | `disconnect` | `() => void` | Fire-and-forget disconnect |
274
+ | `disconnectAsync` | `() => Promise<void>` | Disconnect and await completion |
275
+ | `isLoading` | `boolean` | Disconnect in progress |
276
+ | `isSuccess` | `boolean` | Disconnect succeeded |
277
+ | `isError` | `boolean` | Disconnect failed |
278
+ | `error` | `Error \| null` | Error details |
279
+
280
+ ---
281
+
282
+ ### `useNetwork`
283
+
284
+ Get the current Bitcoin network.
285
+
286
+ ```tsx
287
+ import { useNetwork } from 'otx-btc-wallet-react';
288
+
289
+ function NetworkInfo() {
290
+ const { network } = useNetwork();
291
+ // 'mainnet' | 'testnet' | 'testnet4' | 'signet'
292
+
293
+ return <p>Network: {network}</p>;
294
+ }
295
+ ```
296
+
297
+ **Return Type: `UseNetworkReturn`**
298
+
299
+ | Field | Type | Description |
300
+ |-------|------|-------------|
301
+ | `network` | `BitcoinNetwork` | Current Bitcoin network |
302
+
303
+ ---
304
+
305
+ ### `useSignMessage`
306
+
307
+ Sign a text message with the connected wallet.
308
+
309
+ ```tsx
310
+ import { useSignMessage } from 'otx-btc-wallet-react';
311
+
312
+ function SignMessage() {
313
+ const {
314
+ signMessage, // (args: { message: string }) => void
315
+ signMessageAsync, // (args: { message: string }) => Promise<string>
316
+ data, // string | undefined (signature)
317
+ isLoading, // boolean
318
+ isSuccess, // boolean
319
+ isError, // boolean
320
+ error, // Error | null
321
+ reset, // () => void
322
+ } = useSignMessage();
323
+
324
+ return (
325
+ <div>
326
+ <button
327
+ onClick={() => signMessage({ message: 'Hello Bitcoin!' })}
328
+ disabled={isLoading}
329
+ >
330
+ Sign Message
331
+ </button>
332
+ {data && <p>Signature: {data}</p>}
333
+ {isError && <p>Error: {error?.message}</p>}
334
+ </div>
335
+ );
336
+ }
337
+ ```
338
+
339
+ **Return Type: `UseSignMessageReturn`**
340
+
341
+ | Field | Type | Description |
342
+ |-------|------|-------------|
343
+ | `signMessage` | `(args: { message: string }) => void` | Fire-and-forget sign |
344
+ | `signMessageAsync` | `(args: { message: string }) => Promise<string>` | Sign and await signature |
345
+ | `data` | `string \| undefined` | The resulting signature |
346
+ | `isLoading` | `boolean` | Signing in progress |
347
+ | `isSuccess` | `boolean` | Signing succeeded |
348
+ | `isError` | `boolean` | Signing failed |
349
+ | `error` | `Error \| null` | Error details |
350
+ | `reset` | `() => void` | Reset state |
351
+
352
+ ---
353
+
354
+ ### `useSignPsbt`
355
+
356
+ Sign a single PSBT (Partially Signed Bitcoin Transaction).
357
+
358
+ ```tsx
359
+ import { useSignPsbt } from 'otx-btc-wallet-react';
360
+
361
+ function SignTransaction() {
362
+ const {
363
+ signPsbt, // (args) => void
364
+ signPsbtAsync, // (args) => Promise<string>
365
+ data, // string | undefined (signed PSBT hex)
366
+ isLoading,
367
+ isSuccess,
368
+ isError,
369
+ error,
370
+ reset,
371
+ } = useSignPsbt();
372
+
373
+ const handleSign = () => {
374
+ signPsbt({
375
+ psbt: '70736274ff01...', // PSBT hex string
376
+ options: {
377
+ autoFinalize: true,
378
+ broadcast: false,
379
+ toSignInputs: [
380
+ { index: 0, address: 'bc1q...' },
381
+ ],
382
+ },
383
+ });
384
+ };
385
+
386
+ return (
387
+ <div>
388
+ <button onClick={handleSign} disabled={isLoading}>
389
+ Sign PSBT
390
+ </button>
391
+ {data && <p>Signed: {data}</p>}
392
+ </div>
393
+ );
394
+ }
395
+ ```
396
+
397
+ **Return Type: `UseSignPsbtReturn`**
398
+
399
+ | Field | Type | Description |
400
+ |-------|------|-------------|
401
+ | `signPsbt` | `(args: { psbt: string; options?: SignPsbtOptions }) => void` | Fire-and-forget sign |
402
+ | `signPsbtAsync` | `(args: { psbt: string; options?: SignPsbtOptions }) => Promise<string>` | Sign and await result |
403
+ | `data` | `string \| undefined` | Signed PSBT hex |
404
+ | `isLoading` | `boolean` | Signing in progress |
405
+ | `isSuccess` | `boolean` | Signing succeeded |
406
+ | `isError` | `boolean` | Signing failed |
407
+ | `error` | `Error \| null` | Error details |
408
+ | `reset` | `() => void` | Reset state |
409
+
410
+ ---
411
+
412
+ ### `useSignPsbts`
413
+
414
+ Sign multiple PSBTs in a batch. Not all wallets support this (check `isSupported`).
415
+
416
+ ```tsx
417
+ import { useSignPsbts } from 'otx-btc-wallet-react';
418
+
419
+ function BatchSign() {
420
+ const {
421
+ signPsbts, // (args) => void
422
+ signPsbtsAsync, // (args) => Promise<string[]>
423
+ data, // string[] | undefined (signed PSBT hex array)
424
+ isLoading,
425
+ isSuccess,
426
+ isError,
427
+ error,
428
+ isSupported, // boolean - does the wallet support batch signing?
429
+ reset,
430
+ } = useSignPsbts();
431
+
432
+ if (!isSupported) {
433
+ return <p>This wallet does not support batch signing.</p>;
434
+ }
435
+
436
+ return (
437
+ <button
438
+ onClick={() => signPsbts({
439
+ psbts: [psbt1Hex, psbt2Hex],
440
+ options: { autoFinalize: true },
441
+ })}
442
+ disabled={isLoading}
443
+ >
444
+ Sign {2} PSBTs
445
+ </button>
446
+ );
447
+ }
448
+ ```
449
+
450
+ **Return Type: `UseSignPsbtsReturn`**
451
+
452
+ | Field | Type | Description |
453
+ |-------|------|-------------|
454
+ | `signPsbts` | `(args: { psbts: string[]; options?: SignPsbtOptions }) => void` | Fire-and-forget batch sign |
455
+ | `signPsbtsAsync` | `(args: { psbts: string[]; options?: SignPsbtOptions }) => Promise<string[]>` | Sign and await results |
456
+ | `data` | `string[] \| undefined` | Array of signed PSBT hex strings |
457
+ | `isLoading` | `boolean` | Signing in progress |
458
+ | `isSuccess` | `boolean` | Signing succeeded |
459
+ | `isError` | `boolean` | Signing failed |
460
+ | `error` | `Error \| null` | Error details |
461
+ | `isSupported` | `boolean` | `true` if the connected wallet has `signPsbts` method |
462
+ | `reset` | `() => void` | Reset state |
463
+
464
+ **Supported wallets:** Currently only Unisat supports batch PSBT signing.
465
+
466
+ ---
467
+
468
+ ### `useSendTransaction`
469
+
470
+ Send Bitcoin to an address. Amount is specified in satoshis.
471
+
472
+ ```tsx
473
+ import { useSendTransaction } from 'otx-btc-wallet-react';
474
+
475
+ function SendBitcoin() {
476
+ const {
477
+ sendTransaction, // (args: { to: string; amount: number }) => void
478
+ sendTransactionAsync, // (args: { to: string; amount: number }) => Promise<string>
479
+ data, // string | undefined (transaction ID)
480
+ isLoading,
481
+ isSuccess,
482
+ isError,
483
+ error,
484
+ reset,
485
+ } = useSendTransaction();
486
+
487
+ return (
488
+ <div>
489
+ <button
490
+ onClick={() => sendTransaction({
491
+ to: 'bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh',
492
+ amount: 10000, // 10,000 satoshis
493
+ })}
494
+ disabled={isLoading}
495
+ >
496
+ Send 10,000 sats
497
+ </button>
498
+ {data && <p>TX ID: {data}</p>}
499
+ {isError && <p>Error: {error?.message}</p>}
500
+ </div>
501
+ );
502
+ }
503
+ ```
504
+
505
+ **Return Type: `UseSendTransactionReturn`**
506
+
507
+ | Field | Type | Description |
508
+ |-------|------|-------------|
509
+ | `sendTransaction` | `(args: { to: string; amount: number }) => void` | Fire-and-forget send |
510
+ | `sendTransactionAsync` | `(args: { to: string; amount: number }) => Promise<string>` | Send and await txid |
511
+ | `data` | `string \| undefined` | Transaction ID |
512
+ | `isLoading` | `boolean` | Transaction in progress |
513
+ | `isSuccess` | `boolean` | Transaction succeeded |
514
+ | `isError` | `boolean` | Transaction failed |
515
+ | `error` | `Error \| null` | Error details |
516
+ | `reset` | `() => void` | Reset state |
517
+
518
+ ---
519
+
520
+ ### `useMultiAddress`
521
+
522
+ Manage multiple addresses from a single wallet. Useful for wallets like Xverse that provide separate payment and ordinals addresses.
523
+
524
+ ```tsx
525
+ import { useMultiAddress } from 'otx-btc-wallet-react';
526
+
527
+ function MultiAddress() {
528
+ const {
529
+ addresses, // WalletAccount[] - all addresses
530
+ paymentAddress, // WalletAccount | null - segwit/nested-segwit address
531
+ ordinalsAddress, // WalletAccount | null - taproot address
532
+ primaryAddress, // WalletAccount | null - currently selected
533
+ setPrimaryAddress, // (address: WalletAccount) => void
534
+ isLoading, // boolean
535
+ refresh, // () => Promise<void> - refetch from wallet
536
+ } = useMultiAddress();
537
+
538
+ return (
539
+ <div>
540
+ {paymentAddress && (
541
+ <p>Payment: {paymentAddress.address} ({paymentAddress.type})</p>
542
+ )}
543
+ {ordinalsAddress && (
544
+ <p>Ordinals: {ordinalsAddress.address} ({ordinalsAddress.type})</p>
545
+ )}
546
+
547
+ <h3>All Addresses:</h3>
548
+ {addresses.map((addr) => (
549
+ <button
550
+ key={addr.address}
551
+ onClick={() => setPrimaryAddress(addr)}
552
+ style={{ fontWeight: addr === primaryAddress ? 'bold' : 'normal' }}
553
+ >
554
+ {addr.address} ({addr.type})
555
+ </button>
556
+ ))}
557
+
558
+ <button onClick={refresh}>Refresh</button>
559
+ </div>
560
+ );
561
+ }
562
+ ```
563
+
564
+ **Return Type: `UseMultiAddressReturn`**
565
+
566
+ | Field | Type | Description |
567
+ |-------|------|-------------|
568
+ | `addresses` | `WalletAccount[]` | All wallet addresses |
569
+ | `paymentAddress` | `WalletAccount \| null` | First segwit or nested-segwit address (for payments) |
570
+ | `ordinalsAddress` | `WalletAccount \| null` | First taproot address (for ordinals/inscriptions) |
571
+ | `primaryAddress` | `WalletAccount \| null` | Currently selected address |
572
+ | `setPrimaryAddress` | `(address: WalletAccount) => void` | Change the primary address |
573
+ | `isLoading` | `boolean` | Fetching addresses |
574
+ | `refresh` | `() => Promise<void>` | Re-fetch addresses from the wallet |
575
+
576
+ **Address Selection Logic:**
577
+ - `paymentAddress`: First address with type `'segwit'` or `'nested-segwit'`, falls back to the first address
578
+ - `ordinalsAddress`: First address with type `'taproot'`
579
+
580
+ ## Hook Patterns
581
+
582
+ All action hooks follow a consistent pattern:
583
+
584
+ ### Fire-and-Forget vs Async
585
+
586
+ Every action hook provides two versions:
587
+ - **`action()`** - Fire-and-forget. Updates internal state (`isLoading`, `isSuccess`, `isError`, `data`).
588
+ - **`actionAsync()`** - Returns a Promise. Use with `try/catch` for more control.
589
+
590
+ ```tsx
591
+ // Fire-and-forget (state updates automatically)
592
+ signMessage({ message: 'Hello' });
593
+
594
+ // Async (handle result directly)
595
+ try {
596
+ const signature = await signMessageAsync({ message: 'Hello' });
597
+ doSomethingWith(signature);
598
+ } catch (err) {
599
+ handleError(err);
600
+ }
601
+ ```
602
+
603
+ ### Reset State
604
+
605
+ All action hooks provide a `reset()` method to clear `data`, `error`, `isSuccess`, and `isError` back to their initial values.
606
+
607
+ ```tsx
608
+ const { signMessage, data, reset } = useSignMessage();
609
+
610
+ // After showing result, clear it
611
+ <button onClick={reset}>Clear</button>
612
+ ```
613
+
614
+ ## Complete Example
615
+
616
+ ```tsx
617
+ import { createConfig } from 'otx-btc-wallet-core';
618
+ import {
619
+ BtcWalletProvider,
620
+ useAccount,
621
+ useConnect,
622
+ useDisconnect,
623
+ useSignMessage,
624
+ useSendTransaction,
625
+ useNetwork,
626
+ } from 'otx-btc-wallet-react';
627
+ import { UnisatConnector, OKXConnector } from 'otx-btc-wallet-connectors';
628
+
629
+ const config = createConfig({
630
+ connectors: [new UnisatConnector(), new OKXConnector()],
631
+ });
632
+
633
+ function Wallet() {
634
+ const { address, isConnected, addressType } = useAccount();
635
+ const { connect, connectors, isLoading: connecting } = useConnect();
636
+ const { disconnect } = useDisconnect();
637
+ const { signMessage, data: signature } = useSignMessage();
638
+ const { sendTransaction, data: txid } = useSendTransaction();
639
+ const { network } = useNetwork();
640
+
641
+ if (!isConnected) {
642
+ return (
643
+ <div>
644
+ <h2>Connect Wallet</h2>
645
+ {connectors.map((c) => (
646
+ <button
647
+ key={c.id}
648
+ onClick={() => connect({ connector: c })}
649
+ disabled={!c.ready || connecting}
650
+ >
651
+ {c.name} {!c.ready ? '(not installed)' : ''}
652
+ </button>
653
+ ))}
654
+ </div>
655
+ );
656
+ }
657
+
658
+ return (
659
+ <div>
660
+ <p>Address: {address}</p>
661
+ <p>Type: {addressType}</p>
662
+ <p>Network: {network}</p>
663
+
664
+ <button onClick={() => signMessage({ message: 'Hello!' })}>
665
+ Sign Message
666
+ </button>
667
+ {signature && <p>Signature: {signature}</p>}
668
+
669
+ <button onClick={() => sendTransaction({ to: 'bc1q...', amount: 10000 })}>
670
+ Send 10,000 sats
671
+ </button>
672
+ {txid && <p>TX: {txid}</p>}
673
+
674
+ <button onClick={() => disconnect()}>Disconnect</button>
675
+ </div>
676
+ );
677
+ }
678
+
679
+ function App() {
680
+ return (
681
+ <BtcWalletProvider config={config}>
682
+ <Wallet />
683
+ </BtcWalletProvider>
684
+ );
685
+ }
686
+ ```
687
+
688
+ ## Full Exports
689
+
690
+ ```typescript
691
+ // Provider
692
+ export { BtcWalletProvider } from './provider';
693
+ export type { BtcWalletProviderProps } from './provider';
694
+
695
+ // Context
696
+ export { useConfig, BtcWalletContext } from './context';
697
+
698
+ // Hooks
699
+ export { useAccount } from './hooks/useAccount';
700
+ export { useConnect } from './hooks/useConnect';
701
+ export { useDisconnect } from './hooks/useDisconnect';
702
+ export { useNetwork } from './hooks/useNetwork';
703
+ export { useSignMessage } from './hooks/useSignMessage';
704
+ export { useSignPsbt } from './hooks/useSignPsbt';
705
+ export { useSignPsbts } from './hooks/useSignPsbts';
706
+ export { useSendTransaction } from './hooks/useSendTransaction';
707
+ export { useMultiAddress } from './hooks/useMultiAddress';
708
+
709
+ // Return types
710
+ export type {
711
+ UseAccountReturn,
712
+ UseConnectReturn,
713
+ ConnectArgs,
714
+ UseDisconnectReturn,
715
+ UseNetworkReturn,
716
+ UseSignMessageReturn,
717
+ UseSignPsbtReturn,
718
+ UseSignPsbtsReturn,
719
+ UseSendTransactionReturn,
720
+ UseMultiAddressReturn,
721
+ } from './hooks';
722
+ ```
723
+
724
+ ## License
725
+
726
+ MIT