otx-btc-wallet-core 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 +312 -0
- package/dist/index.d.mts +320 -0
- package/dist/index.d.ts +320 -0
- package/dist/index.js +342 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +331 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +41 -0
- package/src/createConfig.ts +80 -0
- package/src/index.ts +40 -0
- package/src/store/index.ts +296 -0
- package/src/types/account.ts +26 -0
- package/src/types/config.ts +28 -0
- package/src/types/connector.ts +109 -0
- package/src/types/index.ts +12 -0
- package/src/types/network.ts +4 -0
- package/src/types/psbt.ts +27 -0
- package/src/types/state.ts +35 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/psbt.ts +185 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { createStore as createZustandStore } from 'zustand/vanilla';
|
|
2
|
+
import { persist, subscribeWithSelector } from 'zustand/middleware';
|
|
3
|
+
import type { PersistOptions } from 'zustand/middleware';
|
|
4
|
+
import type { BitcoinConnector } from '../types/connector';
|
|
5
|
+
import type { WalletAccount } from '../types/account';
|
|
6
|
+
import type { BtcWalletState, ConnectionStatus } from '../types/state';
|
|
7
|
+
import type { BitcoinNetwork } from '../types/network';
|
|
8
|
+
import type { Config } from '../types/config';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Store actions
|
|
12
|
+
*/
|
|
13
|
+
export type StoreActions = {
|
|
14
|
+
/** Connect to a wallet */
|
|
15
|
+
connect: (
|
|
16
|
+
connector: BitcoinConnector,
|
|
17
|
+
network?: BitcoinNetwork
|
|
18
|
+
) => Promise<WalletAccount>;
|
|
19
|
+
|
|
20
|
+
/** Disconnect from current wallet */
|
|
21
|
+
disconnect: () => Promise<void>;
|
|
22
|
+
|
|
23
|
+
/** Reconnect to previously connected wallet */
|
|
24
|
+
reconnect: (connectors: BitcoinConnector[]) => Promise<void>;
|
|
25
|
+
|
|
26
|
+
/** Set account */
|
|
27
|
+
setAccount: (account: WalletAccount | null) => void;
|
|
28
|
+
|
|
29
|
+
/** Set connection status */
|
|
30
|
+
setStatus: (status: ConnectionStatus) => void;
|
|
31
|
+
|
|
32
|
+
/** Set error */
|
|
33
|
+
setError: (error: Error | null) => void;
|
|
34
|
+
|
|
35
|
+
/** Reset store to initial state */
|
|
36
|
+
reset: () => void;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type Store = BtcWalletState & StoreActions;
|
|
40
|
+
|
|
41
|
+
/** Persisted state shape - only these fields are saved to storage */
|
|
42
|
+
type PersistedState = {
|
|
43
|
+
connectorId: string | null;
|
|
44
|
+
network: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const initialState: BtcWalletState = {
|
|
48
|
+
status: 'disconnected',
|
|
49
|
+
account: null,
|
|
50
|
+
connector: null,
|
|
51
|
+
connectorId: null,
|
|
52
|
+
network: 'mainnet',
|
|
53
|
+
error: null,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Create the btc-wallet store
|
|
58
|
+
*/
|
|
59
|
+
export function createStore(config: Config) {
|
|
60
|
+
// Track cleanup functions for event listeners to prevent memory leaks
|
|
61
|
+
let unsubscribeAccounts: (() => void) | null = null;
|
|
62
|
+
let unsubscribeNetwork: (() => void) | null = null;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Cleanup all event listeners
|
|
66
|
+
*/
|
|
67
|
+
const cleanupListeners = () => {
|
|
68
|
+
if (unsubscribeAccounts) {
|
|
69
|
+
unsubscribeAccounts();
|
|
70
|
+
unsubscribeAccounts = null;
|
|
71
|
+
}
|
|
72
|
+
if (unsubscribeNetwork) {
|
|
73
|
+
unsubscribeNetwork();
|
|
74
|
+
unsubscribeNetwork = null;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Setup event listeners for a connector
|
|
80
|
+
* This is shared between connect and reconnect to avoid code duplication
|
|
81
|
+
*/
|
|
82
|
+
const setupConnectorListeners = (
|
|
83
|
+
connector: BitcoinConnector,
|
|
84
|
+
get: () => Store,
|
|
85
|
+
set: (partial: Partial<Store>) => void
|
|
86
|
+
) => {
|
|
87
|
+
// Clean up any existing listeners first
|
|
88
|
+
cleanupListeners();
|
|
89
|
+
|
|
90
|
+
// Subscribe to account changes
|
|
91
|
+
unsubscribeAccounts = connector.onAccountsChanged((accounts) => {
|
|
92
|
+
const currentState = get();
|
|
93
|
+
|
|
94
|
+
// Only handle if this connector is still the active one
|
|
95
|
+
if (currentState.connector?.id !== connector.id) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (accounts.length === 0) {
|
|
100
|
+
// Wallet disconnected from extension side
|
|
101
|
+
// Use catch to handle any errors silently
|
|
102
|
+
get().disconnect().catch(() => {
|
|
103
|
+
// Disconnect failed, but we should still clean up state
|
|
104
|
+
set({
|
|
105
|
+
status: 'disconnected',
|
|
106
|
+
account: null,
|
|
107
|
+
connector: null,
|
|
108
|
+
connectorId: null,
|
|
109
|
+
error: null,
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
} else if (accounts[0]) {
|
|
113
|
+
set({ account: accounts[0] });
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Subscribe to network changes
|
|
118
|
+
unsubscribeNetwork = connector.onNetworkChanged((network) => {
|
|
119
|
+
const currentState = get();
|
|
120
|
+
|
|
121
|
+
// Only handle if this connector is still the active one
|
|
122
|
+
if (currentState.connector?.id !== connector.id) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
set({ network });
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// Define persist options with proper typing
|
|
131
|
+
const persistOptions: PersistOptions<Store, PersistedState> = {
|
|
132
|
+
name: config.storageKey,
|
|
133
|
+
storage: config.storage
|
|
134
|
+
? {
|
|
135
|
+
getItem: (name) => {
|
|
136
|
+
const value = config.storage?.getItem(name);
|
|
137
|
+
if (!value) return null;
|
|
138
|
+
try {
|
|
139
|
+
return JSON.parse(value) as { state: PersistedState };
|
|
140
|
+
} catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
setItem: (name, value) => {
|
|
145
|
+
config.storage?.setItem(name, JSON.stringify(value));
|
|
146
|
+
},
|
|
147
|
+
removeItem: (name) => {
|
|
148
|
+
config.storage?.removeItem(name);
|
|
149
|
+
},
|
|
150
|
+
}
|
|
151
|
+
: undefined,
|
|
152
|
+
// Only persist connectorId and network
|
|
153
|
+
partialize: (state): PersistedState => ({
|
|
154
|
+
connectorId: state.connectorId,
|
|
155
|
+
network: state.network,
|
|
156
|
+
}),
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const store = createZustandStore<Store>()(
|
|
160
|
+
subscribeWithSelector(
|
|
161
|
+
persist(
|
|
162
|
+
(set, get) => ({
|
|
163
|
+
// Initial state
|
|
164
|
+
...initialState,
|
|
165
|
+
|
|
166
|
+
// Actions
|
|
167
|
+
connect: async (
|
|
168
|
+
connector: BitcoinConnector,
|
|
169
|
+
networkParam?: BitcoinNetwork
|
|
170
|
+
) => {
|
|
171
|
+
const { status, network: storeNetwork } = get();
|
|
172
|
+
const network = networkParam ?? storeNetwork;
|
|
173
|
+
|
|
174
|
+
// Prevent duplicate connection attempts
|
|
175
|
+
if (status === 'connecting') {
|
|
176
|
+
throw new Error('Connection already in progress');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Clean up any existing connection first
|
|
180
|
+
cleanupListeners();
|
|
181
|
+
|
|
182
|
+
set({ status: 'connecting', error: null, network });
|
|
183
|
+
|
|
184
|
+
try {
|
|
185
|
+
// Check if wallet is ready
|
|
186
|
+
if (!connector.ready) {
|
|
187
|
+
throw new Error(`${connector.name} wallet is not available`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Connect to wallet with network
|
|
191
|
+
const account = await connector.connect(network);
|
|
192
|
+
|
|
193
|
+
set({
|
|
194
|
+
status: 'connected',
|
|
195
|
+
account,
|
|
196
|
+
connector,
|
|
197
|
+
connectorId: connector.id,
|
|
198
|
+
error: null,
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// Setup event listeners
|
|
202
|
+
setupConnectorListeners(connector, get, set);
|
|
203
|
+
|
|
204
|
+
return account;
|
|
205
|
+
} catch (error) {
|
|
206
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
207
|
+
set({
|
|
208
|
+
status: 'disconnected',
|
|
209
|
+
error: err,
|
|
210
|
+
});
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
disconnect: async () => {
|
|
216
|
+
const { connector } = get();
|
|
217
|
+
|
|
218
|
+
// Clean up listeners first
|
|
219
|
+
cleanupListeners();
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
if (connector) {
|
|
223
|
+
await connector.disconnect();
|
|
224
|
+
}
|
|
225
|
+
} catch {
|
|
226
|
+
// Ignore disconnect errors (wallet might already be locked)
|
|
227
|
+
} finally {
|
|
228
|
+
set({
|
|
229
|
+
status: 'disconnected',
|
|
230
|
+
account: null,
|
|
231
|
+
connector: null,
|
|
232
|
+
connectorId: null,
|
|
233
|
+
error: null,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
reconnect: async (connectors: BitcoinConnector[]) => {
|
|
239
|
+
const { connectorId, status, network } = get();
|
|
240
|
+
|
|
241
|
+
// Only reconnect if we have a saved connector and not already connected
|
|
242
|
+
if (!connectorId || status === 'connected') {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Find the connector
|
|
247
|
+
const connector = connectors.find((c) => c.id === connectorId);
|
|
248
|
+
if (!connector?.ready) {
|
|
249
|
+
// Clear saved connector if not available
|
|
250
|
+
set({ connectorId: null });
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
set({ status: 'reconnecting' });
|
|
255
|
+
|
|
256
|
+
try {
|
|
257
|
+
const account = await connector.connect(network);
|
|
258
|
+
|
|
259
|
+
set({
|
|
260
|
+
status: 'connected',
|
|
261
|
+
account,
|
|
262
|
+
connector,
|
|
263
|
+
error: null,
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// Setup event listeners (reusing shared function)
|
|
267
|
+
setupConnectorListeners(connector, get, set);
|
|
268
|
+
} catch {
|
|
269
|
+
// Reconnect failed silently, clear state
|
|
270
|
+
set({
|
|
271
|
+
status: 'disconnected',
|
|
272
|
+
connectorId: null,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
|
|
277
|
+
setAccount: (account) => set({ account }),
|
|
278
|
+
|
|
279
|
+
setStatus: (status) => set({ status }),
|
|
280
|
+
|
|
281
|
+
setError: (error) => set({ error }),
|
|
282
|
+
|
|
283
|
+
reset: () => {
|
|
284
|
+
cleanupListeners();
|
|
285
|
+
set(initialState);
|
|
286
|
+
},
|
|
287
|
+
}),
|
|
288
|
+
persistOptions
|
|
289
|
+
)
|
|
290
|
+
)
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
return store;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export type BtcWalletStore = ReturnType<typeof createStore>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bitcoin address types supported by wallets
|
|
3
|
+
*/
|
|
4
|
+
export type AddressType = 'legacy' | 'nested-segwit' | 'segwit' | 'taproot';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Wallet account information returned from connection
|
|
8
|
+
*/
|
|
9
|
+
export type WalletAccount = {
|
|
10
|
+
/** Bitcoin address */
|
|
11
|
+
address: string;
|
|
12
|
+
/** Hex-encoded public key */
|
|
13
|
+
publicKey: string;
|
|
14
|
+
/** Address format type */
|
|
15
|
+
type: AddressType;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Multi-address account for wallets supporting both payment and ordinals addresses
|
|
20
|
+
*/
|
|
21
|
+
export type MultiAddressAccount = {
|
|
22
|
+
/** Payment address for BTC transfers (typically segwit) */
|
|
23
|
+
payment: WalletAccount;
|
|
24
|
+
/** Ordinals address for Ordinals/Runes (typically taproot) */
|
|
25
|
+
ordinals: WalletAccount;
|
|
26
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { BitcoinConnector } from './connector';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for otx-btc-wallet
|
|
5
|
+
*/
|
|
6
|
+
export type BtcWalletConfig = {
|
|
7
|
+
/** Array of wallet connectors to support */
|
|
8
|
+
connectors: BitcoinConnector[];
|
|
9
|
+
|
|
10
|
+
/** Whether to auto-connect on page load (default: true) */
|
|
11
|
+
autoConnect?: boolean;
|
|
12
|
+
|
|
13
|
+
/** Storage implementation for persistence (default: localStorage) */
|
|
14
|
+
storage?: Storage;
|
|
15
|
+
|
|
16
|
+
/** Key to use for storage (default: 'optimex-btc-wallet.store') */
|
|
17
|
+
storageKey?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Internal config with resolved defaults
|
|
22
|
+
*/
|
|
23
|
+
export type Config = {
|
|
24
|
+
connectors: BitcoinConnector[];
|
|
25
|
+
autoConnect: boolean;
|
|
26
|
+
storage: Storage | null;
|
|
27
|
+
storageKey: string;
|
|
28
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { WalletAccount } from './account';
|
|
2
|
+
import type { BitcoinNetwork } from './network';
|
|
3
|
+
import type { SignPsbtOptions } from './psbt';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Interface that all wallet connectors must implement
|
|
7
|
+
*/
|
|
8
|
+
export type NetworkType = 'mainnet' | 'testnet' | 'testnet4' | 'signet';
|
|
9
|
+
|
|
10
|
+
export interface BitcoinConnector {
|
|
11
|
+
/** Unique identifier for the connector (e.g., 'unisat') */
|
|
12
|
+
readonly id: string;
|
|
13
|
+
|
|
14
|
+
/** Display name for the wallet (e.g., 'Unisat Wallet') */
|
|
15
|
+
readonly name: string;
|
|
16
|
+
|
|
17
|
+
/** Base64 encoded icon or URL to wallet icon */
|
|
18
|
+
readonly icon: string;
|
|
19
|
+
|
|
20
|
+
/** Whether the wallet extension is detected and ready */
|
|
21
|
+
ready: boolean;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Connect to the wallet
|
|
25
|
+
* @returns The connected wallet account
|
|
26
|
+
* @throws ConnectionError if connection fails
|
|
27
|
+
* @throws UserRejectedError if user rejects connection
|
|
28
|
+
*/
|
|
29
|
+
connect(network?: NetworkType): Promise<WalletAccount>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Disconnect from the wallet
|
|
33
|
+
*/
|
|
34
|
+
disconnect(): Promise<void>;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get all accounts from the wallet
|
|
38
|
+
* @returns Array of wallet accounts
|
|
39
|
+
*/
|
|
40
|
+
getAccounts(): Promise<WalletAccount[]>;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Sign an arbitrary message
|
|
44
|
+
* @param message - Message to sign
|
|
45
|
+
* @returns Signature string
|
|
46
|
+
* @throws SigningError if signing fails
|
|
47
|
+
* @throws UserRejectedError if user rejects signing
|
|
48
|
+
*/
|
|
49
|
+
signMessage(message: string): Promise<string>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Sign a PSBT (Partially Signed Bitcoin Transaction)
|
|
53
|
+
* @param psbtHex - PSBT in hex format
|
|
54
|
+
* @param options - Signing options
|
|
55
|
+
* @returns Signed PSBT in hex format
|
|
56
|
+
* @throws SigningError if signing fails
|
|
57
|
+
* @throws UserRejectedError if user rejects signing
|
|
58
|
+
*/
|
|
59
|
+
signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Sign multiple PSBTs (optional, not all wallets support this)
|
|
63
|
+
* @param psbtHexs - Array of PSBTs in hex format
|
|
64
|
+
* @param options - Signing options
|
|
65
|
+
* @returns Array of signed PSBTs in hex format
|
|
66
|
+
*/
|
|
67
|
+
signPsbts?(psbtHexs: string[], options?: SignPsbtOptions): Promise<string[]>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Send a Bitcoin transaction
|
|
71
|
+
* @param to - Recipient address
|
|
72
|
+
* @param satoshis - Amount in satoshis
|
|
73
|
+
* @returns Transaction ID
|
|
74
|
+
* @throws SigningError if transaction fails
|
|
75
|
+
* @throws UserRejectedError if user rejects transaction
|
|
76
|
+
*/
|
|
77
|
+
sendTransaction(to: string, satoshis: number): Promise<string>;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get current network from the wallet
|
|
81
|
+
* @returns Current network
|
|
82
|
+
*/
|
|
83
|
+
getNetwork(): Promise<BitcoinNetwork>;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Switch to a different network (optional, not all wallets support this)
|
|
87
|
+
* @param network - Network to switch to
|
|
88
|
+
* @throws NetworkError if switch fails
|
|
89
|
+
*/
|
|
90
|
+
switchNetwork?(network: BitcoinNetwork): Promise<void>;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Subscribe to account changes
|
|
94
|
+
* @param callback - Called when accounts change
|
|
95
|
+
* @returns Unsubscribe function
|
|
96
|
+
*/
|
|
97
|
+
onAccountsChanged(
|
|
98
|
+
callback: (accounts: WalletAccount[]) => void
|
|
99
|
+
): () => void;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Subscribe to network changes
|
|
103
|
+
* @param callback - Called when network changes
|
|
104
|
+
* @returns Unsubscribe function
|
|
105
|
+
*/
|
|
106
|
+
onNetworkChanged(
|
|
107
|
+
callback: (network: BitcoinNetwork) => void
|
|
108
|
+
): () => void;
|
|
109
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// otx-btc-wallet-core types
|
|
2
|
+
|
|
3
|
+
export type { BitcoinConnector, NetworkType } from './connector';
|
|
4
|
+
export type {
|
|
5
|
+
WalletAccount,
|
|
6
|
+
AddressType,
|
|
7
|
+
MultiAddressAccount,
|
|
8
|
+
} from './account';
|
|
9
|
+
export type { BitcoinNetwork } from './network';
|
|
10
|
+
export type { SignPsbtOptions, SignInput } from './psbt';
|
|
11
|
+
export type { BtcWalletConfig, Config } from './config';
|
|
12
|
+
export type { BtcWalletState, ConnectionStatus } from './state';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for signing a PSBT
|
|
3
|
+
*/
|
|
4
|
+
export type SignPsbtOptions = {
|
|
5
|
+
/** Auto-finalize inputs after signing (default: true) */
|
|
6
|
+
autoFinalize?: boolean;
|
|
7
|
+
/** Specific inputs to sign */
|
|
8
|
+
toSignInputs?: SignInput[];
|
|
9
|
+
/** Broadcast transaction after signing (where supported) */
|
|
10
|
+
broadcast?: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Configuration for signing a specific input
|
|
15
|
+
*/
|
|
16
|
+
export type SignInput = {
|
|
17
|
+
/** Input index to sign */
|
|
18
|
+
index: number;
|
|
19
|
+
/** Address to use for signing */
|
|
20
|
+
address?: string;
|
|
21
|
+
/** Public key to use for signing */
|
|
22
|
+
publicKey?: string;
|
|
23
|
+
/** Allowed sighash types */
|
|
24
|
+
sighashTypes?: number[];
|
|
25
|
+
/** Disable tweak signer for taproot key-path spends */
|
|
26
|
+
disableTweakSigner?: boolean;
|
|
27
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { BitcoinConnector } from './connector';
|
|
2
|
+
import type { WalletAccount } from './account';
|
|
3
|
+
import type { BitcoinNetwork } from './network';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Connection status states
|
|
7
|
+
*/
|
|
8
|
+
export type ConnectionStatus =
|
|
9
|
+
| 'disconnected'
|
|
10
|
+
| 'connecting'
|
|
11
|
+
| 'connected'
|
|
12
|
+
| 'reconnecting';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Store state shape
|
|
16
|
+
*/
|
|
17
|
+
export type BtcWalletState = {
|
|
18
|
+
/** Current connection status */
|
|
19
|
+
status: ConnectionStatus;
|
|
20
|
+
|
|
21
|
+
/** Connected account (null if disconnected) */
|
|
22
|
+
account: WalletAccount | null;
|
|
23
|
+
|
|
24
|
+
/** Active connector (null if disconnected) */
|
|
25
|
+
connector: BitcoinConnector | null;
|
|
26
|
+
|
|
27
|
+
/** Connected connector ID (for persistence) */
|
|
28
|
+
connectorId: string | null;
|
|
29
|
+
|
|
30
|
+
/** Current network */
|
|
31
|
+
network: BitcoinNetwork;
|
|
32
|
+
|
|
33
|
+
/** Last error (null if no error) */
|
|
34
|
+
error: Error | null;
|
|
35
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './psbt';
|