@usebutr/core 2.0.1 → 3.0.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/CHANGELOG.md +36 -0
- package/README.md +55 -9
- package/dist/index.d.ts +496 -498
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +870 -920
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { StoreApi } from "zustand/vanilla";
|
|
1
2
|
//#region src/types/chain.d.ts
|
|
2
3
|
/**
|
|
3
4
|
* CAIP-2 shaped. butr never reads past these four fields, so consumers
|
|
@@ -6,13 +7,19 @@
|
|
|
6
7
|
type ChainBase = {
|
|
7
8
|
/** CAIP-2 identifier, e.g. "eip155:1", "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" */
|
|
8
9
|
id: string;
|
|
9
|
-
/** Human-readable name, e.g. "Ethereum"
|
|
10
|
+
/** Human-readable chain name, e.g. "Ethereum". Never the wallet's name. */
|
|
10
11
|
name: string;
|
|
11
12
|
/** CAIP-2 namespace, e.g. "eip155", "solana" */
|
|
12
13
|
namespace: string;
|
|
13
14
|
/** CAIP-2 reference, e.g. "1", "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" */
|
|
14
15
|
reference: string;
|
|
15
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Wallets report bare CAIP-2 ids, so the display name comes from a chain
|
|
19
|
+
* registry. A chain outside `known` keeps its id as its name rather than
|
|
20
|
+
* borrowing the wallet's.
|
|
21
|
+
*/
|
|
22
|
+
declare const resolveChain: (id: string, known?: ReadonlyArray<ChainBase>) => ChainBase;
|
|
16
23
|
//#endregion
|
|
17
24
|
//#region src/types/account.d.ts
|
|
18
25
|
type Account = {
|
|
@@ -37,47 +44,6 @@ type Balance = {
|
|
|
37
44
|
value: bigint;
|
|
38
45
|
};
|
|
39
46
|
//#endregion
|
|
40
|
-
//#region src/types/capabilities.d.ts
|
|
41
|
-
/**
|
|
42
|
-
* Each flag means "can this work right now", not "is the method
|
|
43
|
-
* defined": `signMessage: false` means the call would reject,
|
|
44
|
-
* `switchChain: false` means switching is a no-op for every chain.
|
|
45
|
-
*/
|
|
46
|
-
type WalletCapabilities = {
|
|
47
|
-
/** `getBalance` returns a real on-chain value (vs. a 0n placeholder). */
|
|
48
|
-
getBalance: boolean;
|
|
49
|
-
/** `getTransactionReceipt` returns a real RPC response. */
|
|
50
|
-
getTransactionReceipt: boolean;
|
|
51
|
-
/** Calling `requestAccounts` will actually do something: either
|
|
52
|
-
* prompt the user (EIP-2255) or refresh the exposed list. */
|
|
53
|
-
requestAccounts: boolean;
|
|
54
|
-
/** `sendTx` / `sendTxToChain` will work. False for SVM wallets that
|
|
55
|
-
* don't advertise `solana:signAndSendTransaction`. */
|
|
56
|
-
sendTransaction: boolean;
|
|
57
|
-
/** `signIn` works: Sign In With Solana (`solana:signIn`). True only
|
|
58
|
-
* for SVM wallets advertising the feature. */
|
|
59
|
-
signIn: boolean;
|
|
60
|
-
/** `signMessage` will work. False for SVM wallets that don't
|
|
61
|
-
* advertise `solana:signMessage`. */
|
|
62
|
-
signMessage: boolean;
|
|
63
|
-
/** `signTransaction` returns a signed-but-unbroadcast transaction the
|
|
64
|
-
* consumer submits with their own RPC client. True only for SVM
|
|
65
|
-
* wallets advertising `solana:signTransaction`; butr ships no RPC so
|
|
66
|
-
* it can't broadcast the result itself. EVM/hardware adapters leave
|
|
67
|
-
* this `false` (no `signTransaction` method). */
|
|
68
|
-
signTransaction: boolean;
|
|
69
|
-
/** Wallet emits account/chain change events that butr can bridge. */
|
|
70
|
-
subscribe: boolean;
|
|
71
|
-
/** `switchAccount` is real. Almost always `false` for auto adapters;
|
|
72
|
-
* neither protocol exposes silent account switch. Hand-rolled
|
|
73
|
-
* adapters with custom transports may set it `true`. */
|
|
74
|
-
switchAccount: boolean;
|
|
75
|
-
/** `switchChain` routes subsequent calls through the new chain. EVM:
|
|
76
|
-
* true via `wallet_switchEthereumChain`. SVM: true (local state +
|
|
77
|
-
* per-call `chain` input) when more than one chain is advertised. */
|
|
78
|
-
switchChain: boolean;
|
|
79
|
-
};
|
|
80
|
-
//#endregion
|
|
81
47
|
//#region src/types/platform.d.ts
|
|
82
48
|
/**
|
|
83
49
|
* Single runtime source of truth: `ChainPlatform` and the storage
|
|
@@ -86,246 +52,267 @@ type WalletCapabilities = {
|
|
|
86
52
|
*/
|
|
87
53
|
declare const CHAIN_PLATFORMS: readonly ["evm", "svm", "sui", "bitcoin", "polkadot"];
|
|
88
54
|
type ChainPlatform = (typeof CHAIN_PLATFORMS)[number];
|
|
55
|
+
declare const isChainPlatform: (value: string) => value is ChainPlatform;
|
|
89
56
|
//#endregion
|
|
90
57
|
//#region src/types/chains-by-platform.d.ts
|
|
91
|
-
/**
|
|
92
|
-
* Values come from the per-platform packages (`EVM_CHAINS_LIST`,
|
|
93
|
-
* `SVM_CHAINS_LIST`, …); an empty list opts that platform out of the
|
|
94
|
-
* consumer's chain UI.
|
|
95
|
-
*/
|
|
58
|
+
/** An empty list opts that platform out of the consumer's chain UI. */
|
|
96
59
|
type ChainsByPlatform = Readonly<Record<ChainPlatform, ReadonlyArray<ChainBase>>>;
|
|
97
|
-
/**
|
|
98
|
-
* Naming only the platforms an app targets keeps the other packages'
|
|
99
|
-
* chain registries out of its bundle. Apps that want all of them import
|
|
100
|
-
* `CHAINS_BY_PLATFORM` from `@usebutr/wallets`.
|
|
101
|
-
*/
|
|
102
|
-
declare const buildChainsByPlatform: (partial: Partial<ChainsByPlatform>) => {
|
|
103
|
-
bitcoin: readonly ChainBase[];
|
|
104
|
-
evm: readonly ChainBase[];
|
|
105
|
-
polkadot: readonly ChainBase[];
|
|
106
|
-
sui: readonly ChainBase[];
|
|
107
|
-
svm: readonly ChainBase[];
|
|
108
|
-
};
|
|
109
60
|
//#endregion
|
|
110
61
|
//#region src/types/connector.d.ts
|
|
111
62
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*/
|
|
116
|
-
type WalletAvailability = "installed" | "loadable" | "not-installed";
|
|
117
|
-
/**
|
|
118
|
-
* `accountChanged` must carry every account the wallet still exposes,
|
|
119
|
-
* not just the new active one: the runtime mirrors the array verbatim
|
|
120
|
-
* into the pool entry. Chain switches arrive as `account.chain`.
|
|
63
|
+
* `accounts` carries every account the wallet still exposes, active first;
|
|
64
|
+
* the runtime mirrors it verbatim into the pool entry. Chain switches
|
|
65
|
+
* arrive as a changed `account.chain`. An empty list is `disconnected`.
|
|
121
66
|
*/
|
|
122
67
|
type ConnectorEvent = {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
type: "accountChanged";
|
|
68
|
+
accounts: ReadonlyArray<Account>;
|
|
69
|
+
type: "accountsChanged";
|
|
126
70
|
} | {
|
|
127
71
|
type: "disconnected";
|
|
128
72
|
};
|
|
129
73
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
74
|
+
* What butr itself calls during connect, disconnect and hydration. Optional
|
|
75
|
+
* members are defined only when they work for this wallet, so presence is
|
|
76
|
+
* the capability check.
|
|
133
77
|
*/
|
|
134
78
|
type Connector<P extends ChainPlatform = ChainPlatform> = {
|
|
135
|
-
/**
|
|
136
|
-
* to gate UI affordances rather than probing for method existence. */
|
|
137
|
-
capabilities: WalletCapabilities;
|
|
138
|
-
/** Discriminant: which chain platform this adapter speaks. Generic
|
|
139
|
-
* parameter `P` narrows this to a specific platform when consumers
|
|
140
|
-
* use one of the per-platform adapter types (`EvmAdapter`,
|
|
141
|
-
* `SvmAdapter`, etc). */
|
|
79
|
+
/** Discriminant: which chain platform this adapter speaks. */
|
|
142
80
|
chainPlatform: P;
|
|
143
|
-
/** `
|
|
81
|
+
/** `options.silent` is hydration's non-interactive reconnect (Wallet
|
|
144
82
|
* Standard `standard:connect` silent input, `eth_accounts` on
|
|
145
83
|
* EIP-1193). An adapter that cannot honour it must reject instead of
|
|
146
84
|
* prompting; hydration reads that as a clean restore failure. */
|
|
147
|
-
connect: (
|
|
85
|
+
connect: (options?: {
|
|
148
86
|
silent?: boolean;
|
|
149
87
|
}) => Promise<void>;
|
|
150
|
-
/**
|
|
88
|
+
/** Teardown. butr calls it on disconnect, failed connects and reset. */
|
|
151
89
|
disconnect?: () => Promise<void>;
|
|
152
|
-
/**
|
|
153
|
-
*
|
|
154
|
-
|
|
155
|
-
/** Optional. List every account the wallet exposes. Some browser wallets
|
|
156
|
-
* show many accounts at once (MetaMask with multiple imports). If
|
|
157
|
-
* omitted, butr defaults to `[await getAccount()]`. */
|
|
158
|
-
getAccounts?: () => Promise<Array<Account>>;
|
|
90
|
+
/** Every account the wallet exposes, active account first. Empty when
|
|
91
|
+
* the wallet is not connected. */
|
|
92
|
+
getAccounts: () => Promise<ReadonlyArray<Account>>;
|
|
159
93
|
/** Discovery runs `sanitizeIcon` at construction, so on discovered
|
|
160
|
-
* adapters this is a trimmed non-empty string or `undefined
|
|
161
|
-
*
|
|
162
|
-
* `icon !== ""` guard. Hand-rolled adapters own that guarantee. */
|
|
94
|
+
* adapters this is a trimmed non-empty string or `undefined`. Hand-rolled
|
|
95
|
+
* adapters own that guarantee. */
|
|
163
96
|
icon?: string;
|
|
164
|
-
/** Stable key: "metamask", "phantom", etc. Pool
|
|
97
|
+
/** Stable key: "io.metamask", "wallet-standard:svm-phantom", etc. Pool
|
|
98
|
+
* entries are keyed by this. */
|
|
165
99
|
id: string;
|
|
166
100
|
/** Human name: "MetaMask", "Phantom", etc. UI-facing only. */
|
|
167
101
|
name: string;
|
|
168
102
|
/** Opens the wallet's account-selection UI (`wallet_requestPermissions`
|
|
169
|
-
* on EIP-
|
|
170
|
-
*
|
|
171
|
-
* `useRequestAccounts` hook which refreshes the pool entry. */
|
|
103
|
+
* on EIP-1193). Resolution does not carry the new accounts; the
|
|
104
|
+
* manager's `requestAccounts` action refreshes the pool entry. */
|
|
172
105
|
requestAccounts?: () => Promise<void>;
|
|
173
|
-
/** Bridges native wallet events
|
|
174
|
-
*
|
|
175
|
-
* guarantees at most one live subscription per connector. */
|
|
106
|
+
/** Bridges native wallet events into the reducer. Only the manager's
|
|
107
|
+
* connector lifecycle calls this, at most once per live connector. */
|
|
176
108
|
subscribe?: (listener: (event: ConnectorEvent) => void) => () => void;
|
|
177
109
|
};
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
110
|
+
//#endregion
|
|
111
|
+
//#region src/storage/persistence.d.ts
|
|
112
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
113
|
+
/** Low-level key/value driver. Sync on web (localStorage, MMKV),
|
|
114
|
+
* async on React Native (AsyncStorage). */
|
|
115
|
+
type StorageDriver = {
|
|
116
|
+
getItem: (key: string) => MaybePromise<string | null>;
|
|
117
|
+
removeItem: (key: string) => MaybePromise<void>;
|
|
118
|
+
setItem: (key: string, value: string) => MaybePromise<void>;
|
|
119
|
+
};
|
|
120
|
+
/** Everything needed to render a connection before its adapter exists:
|
|
121
|
+
* the shadow adapter shows this identity until silent reconnect lands. */
|
|
122
|
+
type StoredPoolEntry = {
|
|
123
|
+
account: Account;
|
|
124
|
+
accounts: ReadonlyArray<Account>;
|
|
183
125
|
chainPlatform: ChainPlatform;
|
|
184
|
-
|
|
185
|
-
* `Connector.icon`, this one is consumer-supplied and butr does not
|
|
186
|
-
* sanitize it; run it through `sanitizeIcon` if the value came from
|
|
187
|
-
* wallet metadata rather than your own assets. */
|
|
126
|
+
connectorId: string;
|
|
188
127
|
icon?: string;
|
|
189
|
-
id: string;
|
|
190
128
|
name: string;
|
|
191
|
-
/** Optional. Where to send users who don't have this wallet (download
|
|
192
|
-
* page, app store link, etc.). */
|
|
193
|
-
url?: string;
|
|
194
129
|
};
|
|
130
|
+
type StoredPoolRecord = Partial<Record<string, StoredPoolEntry>>;
|
|
131
|
+
type StoredSelectionRecord = Partial<Record<ChainPlatform, string>>;
|
|
132
|
+
/**
|
|
133
|
+
* Carries no `Connector` by design: a wallet extension exists only in the
|
|
134
|
+
* browser, so a server render can name the wallet and its address but can
|
|
135
|
+
* never dispatch on it.
|
|
136
|
+
*/
|
|
137
|
+
type WalletSnapshot = {
|
|
138
|
+
activeConnectorId: string | null;
|
|
139
|
+
pool: StoredPoolRecord;
|
|
140
|
+
selection: StoredSelectionRecord;
|
|
141
|
+
};
|
|
142
|
+
type PersistedWalletState = WalletSnapshot & {
|
|
143
|
+
/** Session-scoped: a manual disconnect suppresses auto-connect for this
|
|
144
|
+
* session, not forever. */
|
|
145
|
+
isUserDisconnected: boolean;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* `save` receives the whole derived state after every change, so an
|
|
149
|
+
* implementation never merges or diffs. A `load` rejection is reported
|
|
150
|
+
* through `onStorageError` and treated as empty storage.
|
|
151
|
+
*/
|
|
152
|
+
type WalletPersistence = {
|
|
153
|
+
load: () => Promise<PersistedWalletState>;
|
|
154
|
+
save: (state: PersistedWalletState) => Promise<void>;
|
|
155
|
+
};
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/types/signer.d.ts
|
|
158
|
+
/**
|
|
159
|
+
* Filled by each transport package through module augmentation, e.g.
|
|
160
|
+
* `interface WalletSignerRegistry { eip1193: { provider: Eip1193Provider } }`.
|
|
161
|
+
* Keyed by transport, not platform: EVM through a Ledger is not EIP-1193.
|
|
162
|
+
*/
|
|
163
|
+
interface WalletSignerRegistry {}
|
|
164
|
+
/** Narrow with `switch (signer.kind)`; each branch is fully typed. */
|
|
165
|
+
type WalletSigner = { [K in keyof WalletSignerRegistry]: {
|
|
166
|
+
kind: K;
|
|
167
|
+
} & WalletSignerRegistry[K]; }[keyof WalletSignerRegistry];
|
|
168
|
+
type WalletSignerKind = WalletSigner["kind"];
|
|
169
|
+
type WalletSignerOf<K extends WalletSignerKind> = Extract<WalletSigner, {
|
|
170
|
+
kind: K;
|
|
171
|
+
}>;
|
|
195
172
|
//#endregion
|
|
196
173
|
//#region src/types/wallet.d.ts
|
|
197
174
|
type SignInInput = {
|
|
198
175
|
readonly [key: string]: SignInValue;
|
|
199
176
|
};
|
|
200
177
|
type SignInValue = boolean | number | string | null | ReadonlyArray<SignInValue> | SignInInput;
|
|
201
|
-
type
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
type
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
178
|
+
type SignedMessage = {
|
|
179
|
+
signature: Uint8Array;
|
|
180
|
+
signedMessage: Uint8Array;
|
|
181
|
+
};
|
|
182
|
+
type TransactionReceipt = {
|
|
183
|
+
status: "Error" | "Pending" | "Success";
|
|
184
|
+
};
|
|
185
|
+
/** Acts as `account`, which must be one the wallet exposes; an unknown one
|
|
186
|
+
* rejects rather than signing with another. Omitted, the wallet uses its own
|
|
187
|
+
* active account, so pass `wallet.account` to honour `setAccount`. */
|
|
188
|
+
type AccountOptions = {
|
|
189
|
+
account?: Account;
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* `chain` targets this one transaction. Wallet Standard routes it per call;
|
|
193
|
+
* an EVM wallet has one global network, so it switches first; a transport
|
|
194
|
+
* that can do neither rejects when `chain` is not its current chain.
|
|
195
|
+
*/
|
|
196
|
+
type TransactionOptions = AccountOptions & {
|
|
197
|
+
chain?: ChainBase;
|
|
198
|
+
};
|
|
199
|
+
/** `token` is chain-specific: an ERC-20 contract address on EVM. Omit it for
|
|
200
|
+
* the native asset. */
|
|
201
|
+
type BalanceOptions = AccountOptions & {
|
|
202
|
+
token?: string;
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* Presence is the capability check: an adapter defines an optional method
|
|
206
|
+
* only when calling it can succeed for this wallet, and never ships a
|
|
207
|
+
* placeholder (a zero balance, a receipt that stays pending).
|
|
208
|
+
*/
|
|
209
|
+
type WalletBase<Tx> = {
|
|
210
|
+
getBalance?: (options?: BalanceOptions) => Promise<Balance>;
|
|
211
|
+
/** Narrow with `switch (signer.kind)`; see `WalletSignerRegistry`. */
|
|
221
212
|
getSigner: () => Promise<WalletSigner>;
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}>;
|
|
226
|
-
/** `account` routes through a specific exposed address (EVM via
|
|
227
|
-
* `tx.from`, Wallet Standard via the feature's `account` input);
|
|
228
|
-
* omitting it lets the wallet pick. */
|
|
229
|
-
sendTx: (tx: TransactionInput, account?: Account) => Promise<string>;
|
|
230
|
-
/** Submit a transaction targeting a specific chain. The optional
|
|
231
|
-
* callback fires after the connector has switched chain (consumers
|
|
232
|
-
* use this to re-enable UI). Pass an `account` to route through a
|
|
233
|
-
* specific exposed address (see `sendTx`). */
|
|
234
|
-
sendTxToChain: (tx: TransactionInput, targetChainId: string, account?: Account, cb?: () => void) => Promise<string>;
|
|
213
|
+
getTransactionReceipt?: (hash: string) => Promise<TransactionReceipt>;
|
|
214
|
+
/** Signs and broadcasts; resolves the transaction hash or signature. */
|
|
215
|
+
sendTx?: (tx: Tx, options?: TransactionOptions) => Promise<string>;
|
|
235
216
|
/**
|
|
236
|
-
* Verify against `signedMessage`, not the input: Solana Wallet
|
|
237
|
-
*
|
|
238
|
-
* specific address without changing the wallet's active one.
|
|
217
|
+
* Verify against `signedMessage`, not the input: Solana Wallet Standard
|
|
218
|
+
* wallets may prefix or re-encode it.
|
|
239
219
|
*/
|
|
240
|
-
signMessage
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
*
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
*
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
* consumer via `@mysten/sui`'s SuiClient.
|
|
281
|
-
*/
|
|
282
|
-
type SuiWallet = WalletBase & {
|
|
283
|
-
/** Sign a Sui transaction WITHOUT executing it. Returns BOTH halves the
|
|
284
|
-
* chain requires: `SuiClient.executeTransactionBlock` needs
|
|
285
|
-
* `{ transactionBlock, signature }`, so a bare `Uint8Array` cannot express
|
|
286
|
-
* the result and a consumer holding one cannot tell which half they have. */
|
|
287
|
-
signTransaction?: (tx: TransactionInput, account?: Account) => Promise<{
|
|
220
|
+
signMessage?: (message: Uint8Array, options?: AccountOptions) => Promise<SignedMessage>;
|
|
221
|
+
/** Moves the wallet (or butr's view of it) to `chain`. Rejects for a
|
|
222
|
+
* chain outside this adapter's namespace or not advertised by the wallet. */
|
|
223
|
+
switchChain?: (chain: ChainBase) => Promise<void>;
|
|
224
|
+
};
|
|
225
|
+
type EvmTransactionValue = bigint | boolean | number | string | null | ReadonlyArray<EvmTransactionValue> | {
|
|
226
|
+
readonly [key: string]: EvmTransactionValue | undefined;
|
|
227
|
+
};
|
|
228
|
+
/** An `eth_sendTransaction` request. `bigint` quantities are encoded as hex. */
|
|
229
|
+
type EvmTransactionRequest = Readonly<Record<string, EvmTransactionValue | undefined>>;
|
|
230
|
+
/** A `@mysten/sui` `Transaction` (anything with `toJSON()`), its JSON string,
|
|
231
|
+
* or BCS bytes. */
|
|
232
|
+
type SuiTransactionInput = string | Uint8Array | {
|
|
233
|
+
toJSON: () => Promise<string>;
|
|
234
|
+
};
|
|
235
|
+
/** `amount` in satoshis. */
|
|
236
|
+
type BitcoinTransfer = {
|
|
237
|
+
amount: bigint;
|
|
238
|
+
recipient: string;
|
|
239
|
+
};
|
|
240
|
+
type SignInOutput = {
|
|
241
|
+
account: Account;
|
|
242
|
+
signature: Uint8Array;
|
|
243
|
+
signedMessage: Uint8Array;
|
|
244
|
+
};
|
|
245
|
+
/** No `signIn` (SIWE is app-level) and no `signTransaction`: EVM wallets sign
|
|
246
|
+
* and send in one step through `eth_sendTransaction`. */
|
|
247
|
+
type EvmWallet = WalletBase<EvmTransactionRequest>;
|
|
248
|
+
type SvmWallet = WalletBase<Uint8Array> & {
|
|
249
|
+
/** Sign In With Solana (`solana:signIn`). `input` holds the SIWS message
|
|
250
|
+
* fields (domain, statement, nonce, …). */
|
|
251
|
+
signIn?: (input?: SignInInput) => Promise<SignInOutput>;
|
|
252
|
+
/** Signs a serialized transaction without broadcasting it and resolves the
|
|
253
|
+
* full signed transaction, ready for your own RPC client. */
|
|
254
|
+
signTransaction?: (tx: Uint8Array, options?: TransactionOptions) => Promise<Uint8Array>;
|
|
255
|
+
};
|
|
256
|
+
type SuiWallet = WalletBase<SuiTransactionInput> & {
|
|
257
|
+
/** Signs without executing. `SuiClient.executeTransactionBlock` needs both
|
|
258
|
+
* halves, so the result carries the transaction bytes and the signature. */
|
|
259
|
+
signTransaction?: (tx: SuiTransactionInput, options?: TransactionOptions) => Promise<{
|
|
288
260
|
bytes: Uint8Array;
|
|
289
261
|
signature: Uint8Array;
|
|
290
262
|
}>;
|
|
291
263
|
};
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
type BitcoinWallet = WalletBase & {
|
|
298
|
-
signTransaction?: (tx: TransactionInput, account?: Account) => Promise<Uint8Array>;
|
|
264
|
+
type BitcoinWallet = WalletBase<BitcoinTransfer> & {
|
|
265
|
+
/** `bitcoin:signPsbt`: PSBT bytes in (`psbt.toBuffer()`), signed PSBT bytes
|
|
266
|
+
* out, to finalise and broadcast through your own Esplora or Electrum
|
|
267
|
+
* client. */
|
|
268
|
+
signTransaction?: (psbt: Uint8Array, options?: TransactionOptions) => Promise<Uint8Array>;
|
|
299
269
|
};
|
|
300
|
-
/**
|
|
301
|
-
*
|
|
302
|
-
|
|
303
|
-
* goes through the `getSigner()` handoff.
|
|
304
|
-
*/
|
|
305
|
-
type PolkadotWallet = WalletBase;
|
|
306
|
-
/** Per-platform full adapter shapes: `Connector` + the platform's
|
|
307
|
-
* `Wallet` surface. These are the discriminated-union variants of
|
|
308
|
-
* `WalletAdapter`. */
|
|
270
|
+
/** Building an extrinsic needs chain metadata over RPC, which butr does not
|
|
271
|
+
* ship, so transactions go through the `getSigner()` handoff. */
|
|
272
|
+
type PolkadotWallet = Omit<WalletBase<never>, "sendTx">;
|
|
309
273
|
type EvmAdapter = Connector<"evm"> & EvmWallet;
|
|
310
274
|
type SvmAdapter = Connector<"svm"> & SvmWallet;
|
|
311
275
|
type SuiAdapter = Connector<"sui"> & SuiWallet;
|
|
312
276
|
type BitcoinAdapter = Connector<"bitcoin"> & BitcoinWallet;
|
|
313
277
|
type PolkadotAdapter = Connector<"polkadot"> & PolkadotWallet;
|
|
314
|
-
/**
|
|
315
|
-
*
|
|
316
|
-
* `capabilities` flags narrow "this wallet supports it right now".
|
|
317
|
-
* Both gates are needed, and neither substitutes for the other.
|
|
318
|
-
*/
|
|
278
|
+
/** Narrow on `chainPlatform` to reach a platform's own methods and
|
|
279
|
+
* transaction type. */
|
|
319
280
|
type WalletAdapter = EvmAdapter | SvmAdapter | SuiAdapter | BitcoinAdapter | PolkadotAdapter;
|
|
320
|
-
type
|
|
321
|
-
|
|
281
|
+
type AdapterByPlatform = {
|
|
282
|
+
bitcoin: BitcoinAdapter;
|
|
283
|
+
evm: EvmAdapter;
|
|
284
|
+
polkadot: PolkadotAdapter;
|
|
285
|
+
sui: SuiAdapter;
|
|
286
|
+
svm: SvmAdapter;
|
|
287
|
+
};
|
|
288
|
+
type WalletAdapterFor<P extends ChainPlatform> = Extract<WalletAdapter, {
|
|
289
|
+
chainPlatform: P;
|
|
290
|
+
}>;
|
|
291
|
+
type ConnectedWallet<P extends ChainPlatform = ChainPlatform> = {
|
|
292
|
+
/** The active account; always one of `accounts`. */
|
|
322
293
|
account: Account;
|
|
323
|
-
/**
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
connector:
|
|
328
|
-
};
|
|
294
|
+
/** Every account the wallet exposed at the last connect or refresh. */
|
|
295
|
+
accounts: ReadonlyArray<Account>;
|
|
296
|
+
/** An indexed access rather than `WalletAdapterFor`, so TypeScript measures
|
|
297
|
+
* `P` covariant and `ConnectedWallet<"evm">` stays a `ConnectedWallet`. */
|
|
298
|
+
connector: AdapterByPlatform[P];
|
|
299
|
+
};
|
|
300
|
+
/** Narrows a pool entry to one platform, e.g. before calling its `sendTx`. */
|
|
301
|
+
declare const isPlatformWallet: <P extends ChainPlatform>(wallet: ConnectedWallet, platform: P) => wallet is ConnectedWallet<P>;
|
|
302
|
+
//#endregion
|
|
303
|
+
//#region src/wallet-source.d.ts
|
|
304
|
+
/**
|
|
305
|
+
* The discovery seam: a function that announces adapters and returns its
|
|
306
|
+
* unsubscribe. Every `discover*Adapters` export already has this shape, so
|
|
307
|
+
* it goes into `sources` as-is.
|
|
308
|
+
*/
|
|
309
|
+
type WalletSource = (onAdapter: (adapter: WalletAdapter) => void) => () => void;
|
|
310
|
+
/**
|
|
311
|
+
* For adapters that are built rather than discovered: WalletConnect, Ledger,
|
|
312
|
+
* hand-rolled ones. Takes one adapter or several, or a promise of either; a
|
|
313
|
+
* rejected promise is logged and contributes nothing.
|
|
314
|
+
*/
|
|
315
|
+
declare const fromAdapters: (adapters: MaybePromise<WalletAdapter | Iterable<WalletAdapter>>) => WalletSource;
|
|
329
316
|
//#endregion
|
|
330
317
|
//#region src/types/discoverer.d.ts
|
|
331
318
|
/**
|
|
@@ -340,256 +327,306 @@ type PlatformDiscoverer = {
|
|
|
340
327
|
* discovery already announced the same wallet, or it double-lists.
|
|
341
328
|
*/
|
|
342
329
|
fallback?: {
|
|
343
|
-
subscribe: (onAdapter: (adapter: WalletAdapter) => void,
|
|
330
|
+
subscribe: (onAdapter: (adapter: WalletAdapter) => void, options: {
|
|
344
331
|
hasAnyPrimaryAdapter: () => boolean;
|
|
345
332
|
}) => () => void;
|
|
346
333
|
};
|
|
347
334
|
/** Primary discovery subscription. */
|
|
348
|
-
subscribe:
|
|
335
|
+
subscribe: WalletSource;
|
|
349
336
|
};
|
|
350
337
|
//#endregion
|
|
351
338
|
//#region src/types/errors.d.ts
|
|
352
339
|
/**
|
|
353
340
|
* Wallet SDKs disagree on error shape (EIP-1193 codes, bare strings,
|
|
354
341
|
* bespoke classes), so consumers branch on `kind` rather than regexing
|
|
355
|
-
* messages. `cause` keeps the original value
|
|
356
|
-
*/
|
|
357
|
-
type ConnectionError = {
|
|
358
|
-
kind: "UserRejected";
|
|
359
|
-
message: string;
|
|
360
|
-
} | {
|
|
361
|
-
kind: "RequestPending";
|
|
362
|
-
message: string;
|
|
363
|
-
} | {
|
|
364
|
-
kind: "WalletLocked";
|
|
365
|
-
message: string;
|
|
366
|
-
} | {
|
|
367
|
-
actualChain?: string;
|
|
368
|
-
expectedChain?: string;
|
|
369
|
-
kind: "ChainMismatch";
|
|
370
|
-
message: string;
|
|
371
|
-
} | {
|
|
372
|
-
kind: "NotConnected";
|
|
373
|
-
message: string;
|
|
374
|
-
} | {
|
|
375
|
-
kind: "Timeout";
|
|
376
|
-
message: string;
|
|
377
|
-
} | {
|
|
378
|
-
cause?: ErrorCause;
|
|
379
|
-
kind: "Unknown";
|
|
380
|
-
message: string;
|
|
381
|
-
};
|
|
382
|
-
type ConnectionErrorKind = ConnectionError["kind"];
|
|
383
|
-
type ErrorCause = Error | string;
|
|
384
|
-
type CodedError = Error & {
|
|
385
|
-
code: number | string;
|
|
386
|
-
};
|
|
387
|
-
/**
|
|
388
|
-
* EIP-1193 codes: `4001` rejected, `-32002` pending, `4100`/`4900`/`4901`
|
|
389
|
-
* unauthorized or disconnected. Message-substring matching is the last
|
|
390
|
-
* resort for SDKs that ship no codes at all.
|
|
342
|
+
* messages. `cause` keeps the original value.
|
|
391
343
|
*/
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
getItem: (key: string) => MaybePromise<string | null>;
|
|
400
|
-
removeItem: (key: string) => MaybePromise<void>;
|
|
401
|
-
setItem: (key: string, value: string) => MaybePromise<void>;
|
|
402
|
-
};
|
|
403
|
-
type StoredPoolEntry = {
|
|
404
|
-
account: Account;
|
|
405
|
-
/** All known accounts on the wallet at last persist. Always contains
|
|
406
|
-
* `account`. */
|
|
407
|
-
accounts: Array<Account>;
|
|
408
|
-
chainPlatform: ChainPlatform;
|
|
409
|
-
connectorId: string;
|
|
410
|
-
/** Wallet icon URL or data-URI captured at persist time. Lets the
|
|
411
|
-
* shadow adapter render the same icon the live adapter will when
|
|
412
|
-
* the store is seeded from a snapshot. Omitted when the adapter
|
|
413
|
-
* itself has no icon. */
|
|
414
|
-
icon?: string;
|
|
415
|
-
/** Human-facing wallet name (e.g. "MetaMask") captured at persist
|
|
416
|
-
* time. Required so the shadow adapter renders the same identity
|
|
417
|
-
* the live adapter will; no "metamask" → "MetaMask" swap at the
|
|
418
|
-
* hydration boundary. */
|
|
419
|
-
name: string;
|
|
420
|
-
};
|
|
421
|
-
type StoredPoolRecord = Partial<Record<string, StoredPoolEntry>>;
|
|
422
|
-
type StoredSelectionRecord = Partial<Record<ChainPlatform, string>>;
|
|
423
|
-
type WalletPersistence = {
|
|
424
|
-
clearAll: () => Promise<void>;
|
|
425
|
-
clearPool: () => Promise<void>;
|
|
426
|
-
getActiveConnectorId: () => Promise<string | null>;
|
|
427
|
-
getPool: () => Promise<StoredPoolRecord>;
|
|
428
|
-
getSelection: () => Promise<StoredSelectionRecord>;
|
|
429
|
-
isUserDisconnected: () => Promise<boolean>;
|
|
430
|
-
markUserDisconnected: (value: boolean) => Promise<void>;
|
|
431
|
-
removePoolEntry: (connectorId: string) => Promise<void>;
|
|
432
|
-
setActiveConnectorId: (connectorId: string | null) => Promise<void>;
|
|
433
|
-
setPool: (pool: Map<string, ConnectedWallet>) => Promise<void>;
|
|
434
|
-
setSelection: (selection: Map<ChainPlatform, string>) => Promise<void>;
|
|
435
|
-
};
|
|
436
|
-
//#endregion
|
|
437
|
-
//#region src/storage/snapshot.d.ts
|
|
438
|
-
/**
|
|
439
|
-
* Carries no `Connector` by design: a wallet extension exists only in
|
|
440
|
-
* the browser, so a server render can name the wallet and its address
|
|
441
|
-
* but can never dispatch on it.
|
|
442
|
-
*/
|
|
443
|
-
type WalletSnapshot = {
|
|
444
|
-
activeConnectorId: string | null;
|
|
445
|
-
pool: StoredPoolRecord;
|
|
446
|
-
selection: StoredSelectionRecord;
|
|
447
|
-
};
|
|
448
|
-
type CookieSource = Iterable<{
|
|
449
|
-
name: string;
|
|
450
|
-
value: string;
|
|
451
|
-
}> | Iterable<[string, string]> | Readonly<Record<string, string>>;
|
|
452
|
-
type SnapshotOptions = {
|
|
453
|
-
/**
|
|
454
|
-
* Same prefix passed to `WalletManagerProvider` / `WalletStorage`.
|
|
455
|
-
* Defaults to `"butr"` to match the library default.
|
|
456
|
-
*/
|
|
457
|
-
keyPrefix?: string;
|
|
458
|
-
};
|
|
459
|
-
declare const EMPTY_SNAPSHOT: WalletSnapshot;
|
|
460
|
-
/**
|
|
461
|
-
* Optimistic: only what the browser last persisted, so an uninstall or
|
|
462
|
-
* other-tab disconnect makes it stale. Authoritative once the entry
|
|
463
|
-
* leaves `reconnectingIds`; `isHydrated` is true from render one.
|
|
464
|
-
*/
|
|
465
|
-
declare const readWalletSnapshot: (source: CookieSource, options?: SnapshotOptions) => WalletSnapshot;
|
|
344
|
+
type ConnectionErrorKind = "ChainMismatch" | "NotConnected" | "RequestPending" | "Timeout" | "Unknown" | "UserRejected" | "WalletLocked" | "WalletNotFound";
|
|
345
|
+
declare class ConnectionError extends Error {
|
|
346
|
+
readonly kind: ConnectionErrorKind;
|
|
347
|
+
constructor(kind: ConnectionErrorKind, message: string, options?: ErrorOptions);
|
|
348
|
+
}
|
|
349
|
+
/** The one boundary where a thrown value of unknown shape becomes typed. */
|
|
350
|
+
declare const toConnectionError: (cause: unknown) => ConnectionError;
|
|
466
351
|
//#endregion
|
|
467
352
|
//#region src/types/manager.d.ts
|
|
468
353
|
/**
|
|
469
|
-
* `pendingIds` are not failures:
|
|
470
|
-
*
|
|
471
|
-
*
|
|
354
|
+
* `pendingIds` are not failures: their adapters have not been announced yet,
|
|
355
|
+
* and the manager restores them the moment they are. Only `dropped` entries
|
|
356
|
+
* failed their silent reconnect; they stay persisted for the next load.
|
|
472
357
|
*/
|
|
473
358
|
type HydrationOutcome = {
|
|
474
|
-
dropped:
|
|
359
|
+
dropped: ReadonlyArray<{
|
|
475
360
|
connectorId: string;
|
|
476
|
-
reason:
|
|
361
|
+
reason: ConnectionError;
|
|
477
362
|
}>;
|
|
478
|
-
pendingIds:
|
|
479
|
-
restoredIds:
|
|
363
|
+
pendingIds: ReadonlyArray<string>;
|
|
364
|
+
restoredIds: ReadonlyArray<string>;
|
|
480
365
|
};
|
|
366
|
+
/**
|
|
367
|
+
* Read once, when the manager is created. Define it at module scope; the
|
|
368
|
+
* callbacks never see later values.
|
|
369
|
+
*/
|
|
481
370
|
type WalletManagerConfig = {
|
|
482
|
-
/**
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
*
|
|
489
|
-
* id sits in `reconnectingIds` until silent reconnect verifies it.
|
|
490
|
-
*/
|
|
491
|
-
initialState?: WalletSnapshot;
|
|
492
|
-
/** Called after a wallet is successfully connected */
|
|
493
|
-
onConnect?: (wallet: ConnectedWallet) => void;
|
|
494
|
-
/**
|
|
495
|
-
* Fires for every failed attempt (rejection, locked wallet, timeout,
|
|
496
|
-
* …), so observability can hook here instead of wrapping every
|
|
497
|
-
* `connectWallet` call.
|
|
498
|
-
*/
|
|
371
|
+
/** Fires whenever a wallet goes live: a user `connect` (`reconnected:
|
|
372
|
+
* false`) or a silent restore of a persisted connection (`true`). */
|
|
373
|
+
onConnect?: (wallet: ConnectedWallet, context: {
|
|
374
|
+
reconnected: boolean;
|
|
375
|
+
}) => void;
|
|
376
|
+
/** Fires for every failed attempt, so observability hooks here instead of
|
|
377
|
+
* wrapping every `connect` call. */
|
|
499
378
|
onConnectError?: (error: ConnectionError, connectorId: string) => void;
|
|
500
|
-
/**
|
|
501
|
-
|
|
502
|
-
|
|
379
|
+
/** `byUser` is false when the wallet itself ended the session (locked,
|
|
380
|
+
* extension removed, relay session expired). */
|
|
381
|
+
onDisconnect?: (wallet: ConnectedWallet, context: {
|
|
382
|
+
byUser: boolean;
|
|
383
|
+
}) => void;
|
|
384
|
+
/** Fires once, after the start-up hydration pass. */
|
|
503
385
|
onHydrated?: (outcome: HydrationOutcome) => void;
|
|
504
|
-
/**
|
|
505
|
-
|
|
506
|
-
/**
|
|
507
|
-
* Fires at most once per attempt, once it passes
|
|
508
|
-
* `slowConnectThresholdMs` without settling. The attempt keeps
|
|
509
|
-
* running; this is a hint, not a timeout.
|
|
510
|
-
*/
|
|
386
|
+
/** Fires at most once per attempt, once it passes `slowConnectThresholdMs`
|
|
387
|
+
* without settling. A hint, not a timeout. */
|
|
511
388
|
onSlowConnect?: (connectorId: string) => void;
|
|
512
|
-
/**
|
|
513
|
-
*
|
|
514
|
-
|
|
515
|
-
* here. Defaults to `console.warn`.
|
|
516
|
-
*/
|
|
517
|
-
onStorageError?: (error: ErrorCause, context: string) => void;
|
|
389
|
+
/** Persistence is fire-and-forget: a failed write never breaks state, it
|
|
390
|
+
* only surfaces here. Defaults to `console.warn`. */
|
|
391
|
+
onStorageError?: (error: Error) => void;
|
|
518
392
|
/** Threshold for `onSlowConnect`, in milliseconds. Defaults to 5_000. */
|
|
519
393
|
slowConnectThresholdMs?: number;
|
|
520
|
-
/**
|
|
394
|
+
/** Where adapters come from: `autoDiscovery()`, any `discover*Adapters`
|
|
395
|
+
* export, or `fromAdapters(…)` for WalletConnect, Ledger and hand-rolled
|
|
396
|
+
* adapters. The first adapter announced for an id wins. */
|
|
397
|
+
sources?: ReadonlyArray<WalletSource>;
|
|
398
|
+
/** Replaces the default localStorage + sessionStorage persistence. */
|
|
521
399
|
storage?: WalletPersistence;
|
|
522
|
-
/**
|
|
400
|
+
/** Key prefix for the default persistence. Ignored when `storage` is set;
|
|
401
|
+
* pass the same value to `readWalletSnapshot`. */
|
|
523
402
|
storageKeyPrefix?: string;
|
|
524
403
|
};
|
|
525
404
|
//#endregion
|
|
526
|
-
//#region src/
|
|
527
|
-
/**
|
|
528
|
-
*
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
405
|
+
//#region src/chains.d.ts
|
|
406
|
+
/** Common EVM chains. `switchChain` accepts any `ChainBase`, so a chain
|
|
407
|
+
* missing here still works; it is just named by its CAIP-2 id. */
|
|
408
|
+
declare const EVM_CHAINS: {
|
|
409
|
+
readonly arbitrum: {
|
|
410
|
+
readonly id: "eip155:42161";
|
|
411
|
+
readonly name: "Arbitrum One";
|
|
412
|
+
readonly namespace: "eip155";
|
|
413
|
+
readonly reference: "42161";
|
|
414
|
+
};
|
|
415
|
+
readonly base: {
|
|
416
|
+
readonly id: "eip155:8453";
|
|
417
|
+
readonly name: "Base";
|
|
418
|
+
readonly namespace: "eip155";
|
|
419
|
+
readonly reference: "8453";
|
|
420
|
+
};
|
|
421
|
+
readonly bsc: {
|
|
422
|
+
readonly id: "eip155:56";
|
|
423
|
+
readonly name: "BNB Smart Chain";
|
|
424
|
+
readonly namespace: "eip155";
|
|
425
|
+
readonly reference: "56";
|
|
426
|
+
};
|
|
427
|
+
readonly ethereum: {
|
|
428
|
+
readonly id: "eip155:1";
|
|
429
|
+
readonly name: "Ethereum";
|
|
430
|
+
readonly namespace: "eip155";
|
|
431
|
+
readonly reference: "1";
|
|
432
|
+
};
|
|
433
|
+
readonly optimism: {
|
|
434
|
+
readonly id: "eip155:10";
|
|
435
|
+
readonly name: "Optimism";
|
|
436
|
+
readonly namespace: "eip155";
|
|
437
|
+
readonly reference: "10";
|
|
438
|
+
};
|
|
439
|
+
readonly polygon: {
|
|
440
|
+
readonly id: "eip155:137";
|
|
441
|
+
readonly name: "Polygon";
|
|
442
|
+
readonly namespace: "eip155";
|
|
443
|
+
readonly reference: "137";
|
|
444
|
+
};
|
|
445
|
+
readonly sepolia: {
|
|
446
|
+
readonly id: "eip155:11155111";
|
|
447
|
+
readonly name: "Sepolia";
|
|
448
|
+
readonly namespace: "eip155";
|
|
449
|
+
readonly reference: "11155111";
|
|
450
|
+
};
|
|
544
451
|
};
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
452
|
+
declare const SVM_CHAINS: {
|
|
453
|
+
readonly devnet: {
|
|
454
|
+
readonly id: "solana:devnet";
|
|
455
|
+
readonly name: "Solana Devnet";
|
|
456
|
+
readonly namespace: "solana";
|
|
457
|
+
readonly reference: "devnet";
|
|
458
|
+
};
|
|
459
|
+
readonly mainnet: {
|
|
460
|
+
readonly id: "solana:mainnet";
|
|
461
|
+
readonly name: "Solana Mainnet";
|
|
462
|
+
readonly namespace: "solana";
|
|
463
|
+
readonly reference: "mainnet";
|
|
464
|
+
};
|
|
465
|
+
readonly testnet: {
|
|
466
|
+
readonly id: "solana:testnet";
|
|
467
|
+
readonly name: "Solana Testnet";
|
|
468
|
+
readonly namespace: "solana";
|
|
469
|
+
readonly reference: "testnet";
|
|
470
|
+
};
|
|
471
|
+
};
|
|
472
|
+
declare const SUI_CHAINS: {
|
|
473
|
+
readonly devnet: {
|
|
474
|
+
readonly id: "sui:devnet";
|
|
475
|
+
readonly name: "Sui Devnet";
|
|
476
|
+
readonly namespace: "sui";
|
|
477
|
+
readonly reference: "devnet";
|
|
478
|
+
};
|
|
479
|
+
readonly localnet: {
|
|
480
|
+
readonly id: "sui:localnet";
|
|
481
|
+
readonly name: "Sui Localnet";
|
|
482
|
+
readonly namespace: "sui";
|
|
483
|
+
readonly reference: "localnet";
|
|
484
|
+
};
|
|
485
|
+
readonly mainnet: {
|
|
486
|
+
readonly id: "sui:mainnet";
|
|
487
|
+
readonly name: "Sui Mainnet";
|
|
488
|
+
readonly namespace: "sui";
|
|
489
|
+
readonly reference: "mainnet";
|
|
490
|
+
};
|
|
491
|
+
readonly testnet: {
|
|
492
|
+
readonly id: "sui:testnet";
|
|
493
|
+
readonly name: "Sui Testnet";
|
|
494
|
+
readonly namespace: "sui";
|
|
495
|
+
readonly reference: "testnet";
|
|
496
|
+
};
|
|
497
|
+
};
|
|
498
|
+
/** CAIP-2 Bitcoin references are the first 16 bytes of each network's
|
|
499
|
+
* genesis block hash, which is what wallets advertise in `wallet.chains`. */
|
|
500
|
+
declare const BITCOIN_CHAINS: {
|
|
501
|
+
readonly mainnet: {
|
|
502
|
+
readonly id: "bip122:000000000019d6689c085ae165831e93";
|
|
503
|
+
readonly name: "Bitcoin";
|
|
504
|
+
readonly namespace: "bip122";
|
|
505
|
+
readonly reference: "000000000019d6689c085ae165831e93";
|
|
506
|
+
};
|
|
507
|
+
readonly signet: {
|
|
508
|
+
readonly id: "bip122:00000008819873e925422c1ff0f99f7c";
|
|
509
|
+
readonly name: "Bitcoin Signet";
|
|
510
|
+
readonly namespace: "bip122";
|
|
511
|
+
readonly reference: "00000008819873e925422c1ff0f99f7c";
|
|
512
|
+
};
|
|
513
|
+
readonly testnet: {
|
|
514
|
+
readonly id: "bip122:000000000933ea01ad0ee984209779ba";
|
|
515
|
+
readonly name: "Bitcoin Testnet";
|
|
516
|
+
readonly namespace: "bip122";
|
|
517
|
+
readonly reference: "000000000933ea01ad0ee984209779ba";
|
|
518
|
+
};
|
|
519
|
+
readonly testnet4: {
|
|
520
|
+
readonly id: "bip122:00000000da84f2bafbbc53dee25a72ae";
|
|
521
|
+
readonly name: "Bitcoin Testnet4";
|
|
522
|
+
readonly namespace: "bip122";
|
|
523
|
+
readonly reference: "00000000da84f2bafbbc53dee25a72ae";
|
|
524
|
+
};
|
|
525
|
+
};
|
|
526
|
+
declare const POLKADOT_CHAINS: {
|
|
527
|
+
readonly kusama: {
|
|
528
|
+
readonly id: "polkadot:b0a8d493285c2df73290dfb7e61f870f";
|
|
529
|
+
readonly name: "Kusama";
|
|
530
|
+
readonly namespace: "polkadot";
|
|
531
|
+
readonly reference: "b0a8d493285c2df73290dfb7e61f870f";
|
|
532
|
+
};
|
|
533
|
+
readonly paseo: {
|
|
534
|
+
readonly id: "polkadot:77afd6190f1554ad45fd0d31aee62aac";
|
|
535
|
+
readonly name: "Paseo";
|
|
536
|
+
readonly namespace: "polkadot";
|
|
537
|
+
readonly reference: "77afd6190f1554ad45fd0d31aee62aac";
|
|
538
|
+
};
|
|
539
|
+
readonly polkadot: {
|
|
540
|
+
readonly id: "polkadot:91b171bb158e2d3848fa23a9f1c25182";
|
|
541
|
+
readonly name: "Polkadot";
|
|
542
|
+
readonly namespace: "polkadot";
|
|
543
|
+
readonly reference: "91b171bb158e2d3848fa23a9f1c25182";
|
|
544
|
+
};
|
|
545
|
+
readonly westend: {
|
|
546
|
+
readonly id: "polkadot:e143f23803ac50e8f6f8e62695d1ce9e";
|
|
547
|
+
readonly name: "Westend";
|
|
548
|
+
readonly namespace: "polkadot";
|
|
549
|
+
readonly reference: "e143f23803ac50e8f6f8e62695d1ce9e";
|
|
550
|
+
};
|
|
551
|
+
};
|
|
552
|
+
declare const EVM_CHAINS_LIST: ReadonlyArray<ChainBase>;
|
|
553
|
+
declare const SVM_CHAINS_LIST: ReadonlyArray<ChainBase>;
|
|
554
|
+
declare const SUI_CHAINS_LIST: ReadonlyArray<ChainBase>;
|
|
555
|
+
declare const BITCOIN_CHAINS_LIST: ReadonlyArray<ChainBase>;
|
|
556
|
+
declare const POLKADOT_CHAINS_LIST: ReadonlyArray<ChainBase>;
|
|
557
|
+
/** Every registry as a list, keyed by platform: the shape chain pickers want. */
|
|
558
|
+
declare const CHAINS_BY_PLATFORM: ChainsByPlatform;
|
|
550
559
|
//#endregion
|
|
551
560
|
//#region src/store/reducer.d.ts
|
|
552
|
-
/**
|
|
553
|
-
*
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
*/
|
|
557
|
-
type ConnectionStatus = "idle" | "connecting" | "success" | "error" | "reconnecting";
|
|
558
|
-
type State = {
|
|
561
|
+
/** Status of the latest `connect` attempt, not of the connection itself;
|
|
562
|
+
* `useConnectionStatus` derives the latter. */
|
|
563
|
+
type ConnectStatus = "idle" | "connecting" | "success" | "error";
|
|
564
|
+
type WalletState = {
|
|
559
565
|
activeConnectorId: string | null;
|
|
566
|
+
/** Every adapter the sources announced, in announcement order. */
|
|
567
|
+
adapters: ReadonlyArray<WalletAdapter>;
|
|
560
568
|
connectingConnectorId: string | null;
|
|
561
569
|
connectionError: ConnectionError | null;
|
|
562
|
-
connectionStatus:
|
|
563
|
-
isHydrated: boolean;
|
|
564
|
-
isUserDisconnected: boolean;
|
|
565
|
-
pool: Map<string, ConnectedWallet>;
|
|
570
|
+
connectionStatus: ConnectStatus;
|
|
566
571
|
/**
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
572
|
+
* Persisted connections that are not live: awaiting their adapter, failed
|
|
573
|
+
* their silent reconnect, or ended by the wallet rather than the user.
|
|
574
|
+
* They stay persisted so the next load retries them.
|
|
570
575
|
*/
|
|
576
|
+
dormant: ReadonlyMap<string, StoredPoolEntry>;
|
|
577
|
+
isHydrated: boolean;
|
|
578
|
+
isUserDisconnected: boolean;
|
|
579
|
+
pool: ReadonlyMap<string, ConnectedWallet>;
|
|
580
|
+
/** Pool ids still backed by a shadow adapter seeded from `initialState`. */
|
|
571
581
|
reconnectingIds: ReadonlySet<string>;
|
|
572
|
-
|
|
582
|
+
/** Which pool entry serves each platform present in the pool. */
|
|
583
|
+
selection: ReadonlyMap<ChainPlatform, string>;
|
|
573
584
|
};
|
|
574
585
|
//#endregion
|
|
575
586
|
//#region src/store/shadow-adapter.d.ts
|
|
576
587
|
/**
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
*
|
|
588
|
+
* Thrown by the three required methods of a shadow adapter. Every optional
|
|
589
|
+
* method is simply absent, so only code that skipped the `reconnectingIds`
|
|
590
|
+
* check and called `connect`, `getAccounts` or `getSigner` sees this.
|
|
580
591
|
*/
|
|
581
|
-
declare class ShadowConnectorError extends Error
|
|
582
|
-
readonly code = "BUTR_RECONNECTING";
|
|
592
|
+
declare class ShadowConnectorError extends Error {
|
|
583
593
|
readonly connectorId: string;
|
|
584
594
|
readonly method: string;
|
|
585
595
|
constructor(method: string, connectorId: string);
|
|
586
596
|
}
|
|
597
|
+
//#endregion
|
|
598
|
+
//#region src/store/wallet-manager.d.ts
|
|
599
|
+
type WalletManager = Pick<StoreApi<WalletState>, "getInitialState" | "getState" | "subscribe"> & {
|
|
600
|
+
/** Clears `connectionError` and returns `connectionStatus` to idle. */
|
|
601
|
+
clearConnectionError: () => void;
|
|
602
|
+
/** Resolves the connected wallet; rejects with a `ConnectionError`. */
|
|
603
|
+
connect: (connectorId: string) => Promise<ConnectedWallet>;
|
|
604
|
+
disconnect: (connectorId: string) => void;
|
|
605
|
+
/** Disconnects every wallet and forgets every persisted connection. */
|
|
606
|
+
disconnectAll: () => void;
|
|
607
|
+
/** Opens the wallet's account picker, then refreshes the pool entry. A no-op
|
|
608
|
+
* for wallets without `requestAccounts`. */
|
|
609
|
+
requestAccounts: (connectorId: string) => Promise<void>;
|
|
610
|
+
/** Selects an exposed account without changing its chain or the account
|
|
611
|
+
* list. Unknown wallets and accounts are ignored. */
|
|
612
|
+
setAccount: (connectorId: string, account: Account) => void;
|
|
613
|
+
setActive: (connectorId: string) => void;
|
|
614
|
+
setSelection: (chainPlatform: ChainPlatform, connectorId: string) => void;
|
|
615
|
+
/**
|
|
616
|
+
* Subscribes the sources, hydrates persisted connections (once per
|
|
617
|
+
* manager) and bridges wallet events. The returned function undoes all of
|
|
618
|
+
* it except hydration, so a StrictMode remount is safe.
|
|
619
|
+
*/
|
|
620
|
+
start: () => () => void;
|
|
621
|
+
};
|
|
587
622
|
/**
|
|
588
|
-
*
|
|
589
|
-
*
|
|
590
|
-
*
|
|
623
|
+
* Framework-free: React binds it through `WalletManagerProvider`, anything
|
|
624
|
+
* else calls `start()` itself. Creating one has no side effects, so it is
|
|
625
|
+
* safe during a server render.
|
|
591
626
|
*/
|
|
592
|
-
declare const
|
|
627
|
+
declare const createWalletManager: (config?: WalletManagerConfig, options?: {
|
|
628
|
+
initialState?: WalletSnapshot;
|
|
629
|
+
}) => WalletManager;
|
|
593
630
|
//#endregion
|
|
594
631
|
//#region src/storage/browser-storage-driver.d.ts
|
|
595
632
|
type BrowserStorageDrivers = {
|
|
@@ -648,8 +685,28 @@ type CookieDriverOptions = {
|
|
|
648
685
|
*/
|
|
649
686
|
declare const createCookieStorageDriver: (options?: CookieDriverOptions) => StorageDriver;
|
|
650
687
|
//#endregion
|
|
688
|
+
//#region src/storage/snapshot.d.ts
|
|
689
|
+
type CookieSource = Iterable<{
|
|
690
|
+
name: string;
|
|
691
|
+
value: string;
|
|
692
|
+
}> | Iterable<[string, string]> | Readonly<Record<string, string>>;
|
|
693
|
+
type SnapshotOptions = {
|
|
694
|
+
/**
|
|
695
|
+
* Same prefix passed as `storageKeyPrefix` / to `createWalletStorage`.
|
|
696
|
+
* Defaults to `"butr"` to match the library default.
|
|
697
|
+
*/
|
|
698
|
+
keyPrefix?: string;
|
|
699
|
+
};
|
|
700
|
+
declare const EMPTY_SNAPSHOT: WalletSnapshot;
|
|
701
|
+
/**
|
|
702
|
+
* Optimistic: only what the browser last persisted, so an uninstall or
|
|
703
|
+
* other-tab disconnect makes it stale. Authoritative once the entry
|
|
704
|
+
* leaves `reconnectingIds`; `isHydrated` is true from render one.
|
|
705
|
+
*/
|
|
706
|
+
declare const readWalletSnapshot: (source: CookieSource, options?: SnapshotOptions) => WalletSnapshot;
|
|
707
|
+
//#endregion
|
|
651
708
|
//#region src/storage/wallet-storage.d.ts
|
|
652
|
-
type
|
|
709
|
+
type WalletStorageOptions = {
|
|
653
710
|
/** Defaults to `"butr"`, matching `readWalletSnapshot`. */
|
|
654
711
|
keyPrefix?: string;
|
|
655
712
|
/** Survives app restart. Defaults to localStorage on web. */
|
|
@@ -657,73 +714,12 @@ type StorageConfig = {
|
|
|
657
714
|
/** Cleared on session end. Defaults to sessionStorage on web. */
|
|
658
715
|
session?: StorageDriver;
|
|
659
716
|
};
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
private readonly session;
|
|
667
|
-
/**
|
|
668
|
-
* Serializes pool read-modify-writes; without it concurrent `setPool`
|
|
669
|
-
* calls drop each other's entries. Not reentrant, so a queued mutation
|
|
670
|
-
* must read via `readPool`: `getPool` re-enters and deadlocks it.
|
|
671
|
-
*/
|
|
672
|
-
private poolMutationQueue;
|
|
673
|
-
constructor(config: StorageConfig);
|
|
674
|
-
/** Chain `fn` after the in-flight pool mutation. */
|
|
675
|
-
private serializePoolMutation;
|
|
676
|
-
/** Read and decode the pool without touching the mutation queue. Safe to
|
|
677
|
-
* call from inside a queued mutation, unlike `getPool`. */
|
|
678
|
-
private readPool;
|
|
679
|
-
getPool(): Promise<StoredPoolRecord>;
|
|
680
|
-
/**
|
|
681
|
-
* Additive on purpose: a failed silent reconnect drops the entry from
|
|
682
|
-
* the live pool, and it must survive to be retried next load.
|
|
683
|
-
* Eviction goes through `removePoolEntry` or `clearAll`.
|
|
684
|
-
*/
|
|
685
|
-
setPool(pool: Map<string, ConnectedWallet>): Promise<void>;
|
|
686
|
-
removePoolEntry(connectorId: string): Promise<void>;
|
|
687
|
-
clearPool(): Promise<void>;
|
|
688
|
-
getSelection(): Promise<StoredSelectionRecord>;
|
|
689
|
-
setSelection(selection: Map<ChainPlatform, string>): Promise<void>;
|
|
690
|
-
getActiveConnectorId(): Promise<string | null>;
|
|
691
|
-
setActiveConnectorId(connectorId: string | null): Promise<void>;
|
|
692
|
-
clearAll(): Promise<void>;
|
|
693
|
-
/**
|
|
694
|
-
* Kept in the session driver so it survives remounts (unlike a ref)
|
|
695
|
-
* yet clears at session end (unlike the persistent driver): a manual
|
|
696
|
-
* disconnect must suppress auto-connect now, not forever.
|
|
697
|
-
*/
|
|
698
|
-
isUserDisconnected(): Promise<boolean>;
|
|
699
|
-
markUserDisconnected(value: boolean): Promise<void>;
|
|
700
|
-
}
|
|
701
|
-
//#endregion
|
|
702
|
-
//#region src/store/wallet-store.d.ts
|
|
703
|
-
type ExtractState<S> = S extends {
|
|
704
|
-
getState: () => infer T;
|
|
705
|
-
} ? T : never;
|
|
706
|
-
type RuntimeMembers = {
|
|
707
|
-
_config: WalletManagerConfig;
|
|
708
|
-
_storage: WalletPersistence;
|
|
709
|
-
connectWallet: (connectorId: string, onSuccess?: (wallet: ConnectedWallet) => void, onError?: (error: Error) => void) => Promise<void>;
|
|
710
|
-
disconnectWallet: (connectorId: string) => void;
|
|
711
|
-
getConnectorInstance: (id: string) => ReturnType<WalletManagerConfig["createConnector"]>;
|
|
712
|
-
hydrateWallets: () => Promise<void>;
|
|
713
|
-
refreshWallet: (connectorId: string) => void;
|
|
714
|
-
requestAccounts: (connectorId: string) => Promise<void>;
|
|
715
|
-
reset: () => void;
|
|
716
|
-
resetConnectionStatus: () => void;
|
|
717
|
-
setActiveConnector: (connectorId: string | null) => void;
|
|
718
|
-
setConnectionError: (error: ConnectionError | null) => void;
|
|
719
|
-
setSelection: (chainPlatform: ChainPlatform, connectorId: string | null) => void;
|
|
720
|
-
setUserDisconnected: (value: boolean) => void;
|
|
721
|
-
tryRestoreFromPending: (connectorId: string) => Promise<void>;
|
|
722
|
-
updateWalletAccount: (connectorId: string, account: Account) => void;
|
|
723
|
-
};
|
|
724
|
-
type WalletStore = ReturnType<typeof createWalletStore>;
|
|
725
|
-
type WalletStoreState = ExtractState<WalletStore>;
|
|
726
|
-
declare const createWalletStore: (config: WalletManagerConfig) => import("zustand/vanilla").StoreApi<State & RuntimeMembers>;
|
|
717
|
+
/**
|
|
718
|
+
* Pool, selection and active id go to the persistent driver, the disconnect
|
|
719
|
+
* intent to the session driver. Unchanged keys are not rewritten, so a
|
|
720
|
+
* cookie-backed driver does not re-send every cookie on each save.
|
|
721
|
+
*/
|
|
722
|
+
declare const createWalletStorage: (options?: WalletStorageOptions) => WalletPersistence;
|
|
727
723
|
//#endregion
|
|
728
724
|
//#region src/group-by-platform.d.ts
|
|
729
725
|
/**
|
|
@@ -797,10 +793,12 @@ declare class SignInUnsupportedError extends Error {
|
|
|
797
793
|
declare const createSignInFlow: (options: SignInFlowOptions) => SignInFlow;
|
|
798
794
|
//#endregion
|
|
799
795
|
//#region src/wallet-equal.d.ts
|
|
796
|
+
/** Account ids are canonical (`buildAccount`), so identity is the id. */
|
|
797
|
+
declare const accountsEqual: (a: ReadonlyArray<Account>, b: ReadonlyArray<Account>) => boolean;
|
|
800
798
|
/**
|
|
801
799
|
* The adapter is compared by reference, not `connector.id`: hydration
|
|
802
800
|
* swaps a shadow adapter for the live one under an unchanged id, and an
|
|
803
|
-
* id check would strand consumers on the
|
|
801
|
+
* id check would strand consumers on the placeholder.
|
|
804
802
|
*/
|
|
805
803
|
declare const walletEqual: (a: ConnectedWallet | undefined, b: ConnectedWallet | undefined) => boolean;
|
|
806
804
|
//#endregion
|
|
@@ -849,5 +847,5 @@ declare const bytesToBase58: (bytes: Uint8Array) => string;
|
|
|
849
847
|
* rather than silently dropping them. */
|
|
850
848
|
declare const base58ToBytes: (input: string) => Uint8Array;
|
|
851
849
|
//#endregion
|
|
852
|
-
export { type Account, type Balance, type BitcoinAdapter, type BitcoinWallet, type BrowserStorageDrivers, CHAIN_PLATFORMS, type ChainBase, type ChainPlatform, type ChainsByPlatform, type
|
|
850
|
+
export { type Account, type AccountOptions, BITCOIN_CHAINS, BITCOIN_CHAINS_LIST, type Balance, type BalanceOptions, type BitcoinAdapter, type BitcoinTransfer, type BitcoinWallet, type BrowserStorageDrivers, CHAINS_BY_PLATFORM, CHAIN_PLATFORMS, type ChainBase, type ChainPlatform, type ChainsByPlatform, type ConnectStatus, type ConnectedWallet, ConnectionError, type ConnectionErrorKind, type Connector, type ConnectorEvent, type CookieDriverOptions, type CookieSource, EMPTY_SNAPSHOT, EVM_CHAINS, EVM_CHAINS_LIST, type EvmAdapter, type EvmTransactionRequest, type EvmTransactionValue, type EvmWallet, type HydrationOutcome, type InitialCookies, type MaybePromise, POLKADOT_CHAINS, POLKADOT_CHAINS_LIST, type PersistedWalletState, type PlatformDiscoverer, type PolkadotAdapter, type PolkadotWallet, SUI_CHAINS, SUI_CHAINS_LIST, SVM_CHAINS, SVM_CHAINS_LIST, ShadowConnectorError, type SignInFlowOptions, type SignInInput, type SignInMessageContext, type SignInOutput, type SignInResult, SignInUnsupportedError, type SignInValue, type SignedMessage, type SnapshotOptions, type StorageDriver, type StoredPoolEntry, type StoredPoolRecord, type StoredSelectionRecord, type SuiAdapter, type SuiTransactionInput, type SuiWallet, type SvmAdapter, type SvmWallet, type TransactionOptions, type TransactionReceipt, type WalletAdapter, type WalletAdapterFor, type WalletBase, type WalletManager, type WalletManagerConfig, type WalletPersistence, type WalletSigner, type WalletSignerKind, type WalletSignerOf, type WalletSignerRegistry, type WalletSnapshot, type WalletSource, type WalletState, type WalletStorageOptions, accountsEqual, base58ToBytes, base64ToBytes, buildAccount, bytesToBase58, bytesToBase64, bytesToHex, bytesToHexPrefixed, createBrowserStorageDriver, createCookieStorageDriver, createMemoryStorageDriver, createSignInFlow, createWalletManager, createWalletStorage, fromAdapters, groupByPlatform, hexToBytes, isChainPlatform, isPlatformWallet, logError, logWarn, readWalletSnapshot, resolveChain, sanitizeIcon, toConnectionError, walletEqual };
|
|
853
851
|
//# sourceMappingURL=index.d.ts.map
|