@usebutr/core 1.1.0 → 2.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 +213 -0
- package/LICENSE +21 -0
- package/README.md +40 -0
- package/dist/index.d.ts +201 -591
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +211 -358
- package/dist/index.js.map +1 -1
- package/package.json +20 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
//#region src/types/chain.d.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Consumers extend this with app-specific fields (logos, block explorers, etc.)
|
|
7
|
-
* via structural typing; butr never inspects beyond these 4 fields.
|
|
3
|
+
* CAIP-2 shaped. butr never reads past these four fields, so consumers
|
|
4
|
+
* can extend the type structurally with logos, explorers and the like.
|
|
8
5
|
*/
|
|
9
6
|
type ChainBase = {
|
|
10
7
|
/** CAIP-2 identifier, e.g. "eip155:1", "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" */
|
|
@@ -24,11 +21,9 @@ type Account = {
|
|
|
24
21
|
walletAddress: string;
|
|
25
22
|
};
|
|
26
23
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* must build accounts through this helper (or keep the format
|
|
31
|
-
* byte-identical).
|
|
24
|
+
* The reducer compares accounts by the composite `<chain>:<address>`
|
|
25
|
+
* id, so every adapter must build accounts here or reproduce that
|
|
26
|
+
* format byte for byte.
|
|
32
27
|
*/
|
|
33
28
|
declare const buildAccount: (address: string, chain: ChainBase) => Account;
|
|
34
29
|
type Balance = {
|
|
@@ -44,24 +39,9 @@ type Balance = {
|
|
|
44
39
|
//#endregion
|
|
45
40
|
//#region src/types/capabilities.d.ts
|
|
46
41
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* hand-rolled adapters declare them explicitly). Consumers branch on
|
|
51
|
-
* these to gate UI affordances:
|
|
52
|
-
*
|
|
53
|
-
* ```tsx
|
|
54
|
-
* {wallet.connector.capabilities.requestAccounts ? (
|
|
55
|
-
* <button onClick={() => requestAccounts(wallet.connector.id)}>
|
|
56
|
-
* Request more accounts
|
|
57
|
-
* </button>
|
|
58
|
-
* ) : null}
|
|
59
|
-
* ```
|
|
60
|
-
*
|
|
61
|
-
* Each flag means "can this work right now," not "is the method
|
|
62
|
-
* defined": `signMessage: false` means calling `signMessage()` would
|
|
63
|
-
* reject; `switchChain: false` means switching is a no-op regardless
|
|
64
|
-
* of which chain is passed.
|
|
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.
|
|
65
45
|
*/
|
|
66
46
|
type WalletCapabilities = {
|
|
67
47
|
/** `getBalance` returns a real on-chain value (vs. a 0n placeholder). */
|
|
@@ -100,84 +80,44 @@ type WalletCapabilities = {
|
|
|
100
80
|
//#endregion
|
|
101
81
|
//#region src/types/platform.d.ts
|
|
102
82
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* never drift (a missing platform here was why Polkadot connections failed
|
|
107
|
-
* to persist).
|
|
83
|
+
* Single runtime source of truth: `ChainPlatform` and the storage
|
|
84
|
+
* validators' allowlists both derive from it. Omitting a platform here
|
|
85
|
+
* silently stops its connections from persisting.
|
|
108
86
|
*/
|
|
109
87
|
declare const CHAIN_PLATFORMS: readonly ["evm", "svm", "sui", "bitcoin", "polkadot"];
|
|
110
88
|
type ChainPlatform = (typeof CHAIN_PLATFORMS)[number];
|
|
111
89
|
//#endregion
|
|
112
90
|
//#region src/types/chains-by-platform.d.ts
|
|
113
91
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* The platform key set is fixed by `ChainPlatform`. The value is the
|
|
118
|
-
* chain list; empty when the consumer doesn't want to support that
|
|
119
|
-
* platform's chains in this view. This is the only type that callers
|
|
120
|
-
* write down; the values come from per-platform packages
|
|
121
|
-
* (`EVM_CHAINS_LIST`, `SVM_CHAINS_LIST`, etc).
|
|
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.
|
|
122
95
|
*/
|
|
123
96
|
type ChainsByPlatform = Readonly<Record<ChainPlatform, ReadonlyArray<ChainBase>>>;
|
|
124
97
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* Use this in apps that target one or two chain platforms; importing
|
|
129
|
-
* only those packages keeps unused chain registries out of the bundle.
|
|
130
|
-
* Apps that want every chain reach for `CHAINS_BY_PLATFORM` from
|
|
131
|
-
* `@usebutr/wallets` instead.
|
|
132
|
-
*
|
|
133
|
-
* @example
|
|
134
|
-
* // EVM-only app: Solana/Sui/Bitcoin tables never enter the bundle
|
|
135
|
-
* import { EVM_CHAINS_LIST } from "@usebutr/evm";
|
|
136
|
-
* import { buildChainsByPlatform } from "@usebutr/core";
|
|
137
|
-
*
|
|
138
|
-
* const chains = buildChainsByPlatform({ evm: EVM_CHAINS_LIST });
|
|
139
|
-
*
|
|
140
|
-
* @example
|
|
141
|
-
* // Multi-chain app: pull from each package the app actually uses
|
|
142
|
-
* import { EVM_CHAINS_LIST } from "@usebutr/evm";
|
|
143
|
-
* import { SVM_CHAINS_LIST } from "@usebutr/svm";
|
|
144
|
-
*
|
|
145
|
-
* const chains = buildChainsByPlatform({
|
|
146
|
-
* evm: EVM_CHAINS_LIST,
|
|
147
|
-
* svm: SVM_CHAINS_LIST,
|
|
148
|
-
* });
|
|
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`.
|
|
149
101
|
*/
|
|
150
|
-
declare const buildChainsByPlatform: (partial: Partial<ChainsByPlatform>) =>
|
|
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
|
+
};
|
|
151
109
|
//#endregion
|
|
152
110
|
//#region src/types/connector.d.ts
|
|
153
111
|
/**
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
* -
|
|
157
|
-
* - `loadable`: the wallet's SDK can be loaded on demand (e.g. WalletConnect
|
|
158
|
-
* modal that pops a QR code without requiring a browser extension).
|
|
159
|
-
* - `not-installed`: the wallet isn't reachable. Consumers typically render
|
|
160
|
-
* a "download" affordance pointing at `meta.url`.
|
|
112
|
+
* Gate Connect on `installed` or `loadable`: a `loadable` wallet has no
|
|
113
|
+
* extension yet still connects (WalletConnect's QR modal). Only
|
|
114
|
+
* `not-installed` should degrade to a download link at `meta.url`.
|
|
161
115
|
*/
|
|
162
116
|
type WalletAvailability = "installed" | "loadable" | "not-installed";
|
|
163
117
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* the
|
|
167
|
-
*
|
|
168
|
-
* - `accountChanged` carries both the new active `account` AND the full
|
|
169
|
-
* `accounts` array the wallet currently exposes. The runtime mirrors
|
|
170
|
-
* that list verbatim into the pool entry. This handles two cases
|
|
171
|
-
* uniformly:
|
|
172
|
-
* - Multi-account wallets (MetaMask, Rabby, Brave): the user adds or
|
|
173
|
-
* removes accounts from the dapp's permission set; the array grows
|
|
174
|
-
* or shrinks to match.
|
|
175
|
-
* - Single-account-exposure wallets (Phantom EVM/SVM, MetaMask Snap):
|
|
176
|
-
* only the active account is ever in `accounts`; switching swaps it
|
|
177
|
-
* in place rather than appending.
|
|
178
|
-
* Also covers chain switches; the new chain lives inside `account.chain`.
|
|
179
|
-
* - `disconnected` → `DISCONNECTED` (wallet has gone away externally:
|
|
180
|
-
* user locked it, removed the extension, etc.).
|
|
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`.
|
|
181
121
|
*/
|
|
182
122
|
type ConnectorEvent = {
|
|
183
123
|
account: Account;
|
|
@@ -200,16 +140,10 @@ type Connector<P extends ChainPlatform = ChainPlatform> = {
|
|
|
200
140
|
* use one of the per-platform adapter types (`EvmAdapter`,
|
|
201
141
|
* `SvmAdapter`, etc). */
|
|
202
142
|
chainPlatform: P;
|
|
203
|
-
/**
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
* already-authorized accounts; butr's mount-time hydration passes it
|
|
208
|
-
* so a reload restores wallets without re-prompting (Wallet Standard
|
|
209
|
-
* `standard:connect`'s `silent` input; the `eth_accounts` read on
|
|
210
|
-
* EIP-1193). Adapters that can't reconnect without a prompt should
|
|
211
|
-
* reject when `silent` is set rather than show UI; hydration treats
|
|
212
|
-
* the rejection as a clean restore failure. */
|
|
143
|
+
/** `opts.silent` is hydration's non-interactive reconnect (Wallet
|
|
144
|
+
* Standard `standard:connect` silent input, `eth_accounts` on
|
|
145
|
+
* EIP-1193). An adapter that cannot honour it must reject instead of
|
|
146
|
+
* prompting; hydration reads that as a clean restore failure. */
|
|
213
147
|
connect: (opts?: {
|
|
214
148
|
silent?: boolean;
|
|
215
149
|
}) => Promise<void>;
|
|
@@ -222,38 +156,23 @@ type Connector<P extends ChainPlatform = ChainPlatform> = {
|
|
|
222
156
|
* show many accounts at once (MetaMask with multiple imports). If
|
|
223
157
|
* omitted, butr defaults to `[await getAccount()]`. */
|
|
224
158
|
getAccounts?: () => Promise<Array<Account>>;
|
|
225
|
-
/**
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
* **Already sanitized on discovered adapters.** Discovery runs
|
|
231
|
-
* `sanitizeIcon` at construction, so the value is either a trimmed,
|
|
232
|
-
* non-empty string or `undefined`: never blank, never whitespace-led.
|
|
233
|
-
* Render it directly, including into strict consumers like
|
|
234
|
-
* `next/image`. No second `sanitizeIcon` call and no `icon !== ""`
|
|
235
|
-
* guard is needed. Hand-rolled adapters set this field themselves and
|
|
236
|
-
* own the guarantee. */
|
|
159
|
+
/** Discovery runs `sanitizeIcon` at construction, so on discovered
|
|
160
|
+
* adapters this is a trimmed non-empty string or `undefined`: render
|
|
161
|
+
* it straight into `next/image` with no re-sanitizing and no
|
|
162
|
+
* `icon !== ""` guard. Hand-rolled adapters own that guarantee. */
|
|
237
163
|
icon?: string;
|
|
238
164
|
/** Stable key: "metamask", "phantom", etc. Pool entries are keyed by this. */
|
|
239
165
|
id: string;
|
|
240
166
|
/** Human name: "MetaMask", "Phantom", etc. UI-facing only. */
|
|
241
167
|
name: string;
|
|
242
|
-
/**
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
* accounts directly in the extension. Resolution doesn't include the
|
|
247
|
-
* new accounts; call `getAccounts()` (or use butr's
|
|
248
|
-
* `useRequestAccounts` hook, which refreshes the pool entry for
|
|
249
|
-
* you). */
|
|
168
|
+
/** Opens the wallet's account-selection UI (`wallet_requestPermissions`
|
|
169
|
+
* on EIP-6963; usually unset on Wallet Standard). Resolution does not
|
|
170
|
+
* carry the new accounts: follow it with `getAccounts()`, or use the
|
|
171
|
+
* `useRequestAccounts` hook which refreshes the pool entry. */
|
|
250
172
|
requestAccounts?: () => Promise<void>;
|
|
251
|
-
/**
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
* disconnect / reset. Bridges native wallet events into the reducer so
|
|
255
|
-
* consumers don't have to wire `accountsChanged` / `chainChanged`
|
|
256
|
-
* themselves. */
|
|
173
|
+
/** Bridges native wallet events (`accountsChanged`, `chainChanged`, …)
|
|
174
|
+
* into the reducer. Only `ConnectorLifecycle` may call this, and it
|
|
175
|
+
* guarantees at most one live subscription per connector. */
|
|
257
176
|
subscribe?: (listener: (event: ConnectorEvent) => void) => () => void;
|
|
258
177
|
};
|
|
259
178
|
type ConnectorMeta = {
|
|
@@ -275,6 +194,17 @@ type ConnectorMeta = {
|
|
|
275
194
|
};
|
|
276
195
|
//#endregion
|
|
277
196
|
//#region src/types/wallet.d.ts
|
|
197
|
+
type SignInInput = {
|
|
198
|
+
readonly [key: string]: SignInValue;
|
|
199
|
+
};
|
|
200
|
+
type SignInValue = boolean | number | string | null | ReadonlyArray<SignInValue> | SignInInput;
|
|
201
|
+
type TransactionObject = {
|
|
202
|
+
readonly [key: string]: TransactionValue | undefined;
|
|
203
|
+
};
|
|
204
|
+
type TransactionMethod = (...args: ReadonlyArray<never>) => Promise<string>;
|
|
205
|
+
type TransactionValue = bigint | boolean | number | string | null | Uint8Array | ReadonlyArray<TransactionValue> | TransactionObject | TransactionMethod;
|
|
206
|
+
type TransactionInput = TransactionObject | string | Uint8Array;
|
|
207
|
+
type WalletSigner = object;
|
|
278
208
|
/**
|
|
279
209
|
* Methods every connected wallet supports regardless of chain. The
|
|
280
210
|
* per-platform `Wallet` types extend this with their platform-specific
|
|
@@ -288,33 +218,24 @@ type WalletBase = {
|
|
|
288
218
|
/** Returns a chain-specific signer. Consumers cast to the concrete
|
|
289
219
|
* type via the `SignerForPlatform` registry (or directly to the
|
|
290
220
|
* library shape they wrap: `WalletClient` on viem, etc.). */
|
|
291
|
-
getSigner: () => Promise<
|
|
221
|
+
getSigner: () => Promise<WalletSigner>;
|
|
292
222
|
/** Look up the status of a previously-submitted transaction. */
|
|
293
223
|
getTransactionReceipt: (tx: string) => Promise<{
|
|
294
224
|
status: "Success" | "Error" | "Pending";
|
|
295
225
|
}>;
|
|
296
|
-
/**
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
|
|
300
|
-
* `tx.from`; Wallet Standard wallets via the feature's `account`
|
|
301
|
-
* input. Omit for "use whichever the wallet picks." */
|
|
302
|
-
sendTx: (tx: unknown, account?: Account) => Promise<string>;
|
|
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>;
|
|
303
230
|
/** Submit a transaction targeting a specific chain. The optional
|
|
304
231
|
* callback fires after the connector has switched chain (consumers
|
|
305
232
|
* use this to re-enable UI). Pass an `account` to route through a
|
|
306
233
|
* specific exposed address (see `sendTx`). */
|
|
307
|
-
sendTxToChain: (tx:
|
|
234
|
+
sendTxToChain: (tx: TransactionInput, targetChainId: string, account?: Account, cb?: () => void) => Promise<string>;
|
|
308
235
|
/**
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
* `signedMessage`, not the input bytes. EVM wallets echo the input.
|
|
313
|
-
*
|
|
314
|
-
* Pass an `account` to sign with a specific exposed address. EIP-1193
|
|
315
|
-
* routes it through `personal_sign`'s address param; Wallet Standard
|
|
316
|
-
* uses the feature's `account` input. Both support per-call signing
|
|
317
|
-
* without changing the wallet's active account.
|
|
236
|
+
* Verify against `signedMessage`, not the input: Solana Wallet
|
|
237
|
+
* Standard wallets may prefix or re-encode it. `account` signs with a
|
|
238
|
+
* specific address without changing the wallet's active one.
|
|
318
239
|
*/
|
|
319
240
|
signMessage: (msg: Uint8Array, account?: Account) => Promise<{
|
|
320
241
|
signature: Uint8Array;
|
|
@@ -327,19 +248,15 @@ type WalletBase = {
|
|
|
327
248
|
switchChain: (chain: ChainBase) => Promise<void>;
|
|
328
249
|
};
|
|
329
250
|
/**
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
* flows aren't exposed through this surface.
|
|
251
|
+
* No `signIn` (SIWE is app-level here, not a protocol method) and no
|
|
252
|
+
* `signTransaction`: EVM wallets sign and send in one step through
|
|
253
|
+
* `eth_sendTransaction`.
|
|
334
254
|
*/
|
|
335
255
|
type EvmWallet = WalletBase;
|
|
336
256
|
/**
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
* - `signTransaction`: sign-only path for wallets that advertise
|
|
341
|
-
* `solana:signTransaction` but not `solana:signAndSendTransaction`.
|
|
342
|
-
* Optional; `capabilities.signTransaction` gates availability.
|
|
257
|
+
* Both additions are optional at runtime; gate them on
|
|
258
|
+
* `capabilities.signIn` / `capabilities.signTransaction`, which mirror
|
|
259
|
+
* what the wallet actually advertises.
|
|
343
260
|
*/
|
|
344
261
|
type SvmWallet = WalletBase & {
|
|
345
262
|
/** Sign In With Solana (SIWS, `solana:signIn`). Authenticates the user
|
|
@@ -347,7 +264,7 @@ type SvmWallet = WalletBase & {
|
|
|
347
264
|
* consumer can verify server-side. `input` is the SIWS message fields
|
|
348
265
|
* (domain, statement, nonce, …); pass `{}` or omit for wallet
|
|
349
266
|
* defaults. */
|
|
350
|
-
signIn?: (input?:
|
|
267
|
+
signIn?: (input?: SignInInput) => Promise<{
|
|
351
268
|
account: Account;
|
|
352
269
|
signature: Uint8Array;
|
|
353
270
|
signedMessage: Uint8Array;
|
|
@@ -355,7 +272,7 @@ type SvmWallet = WalletBase & {
|
|
|
355
272
|
/** Sign a Solana transaction WITHOUT broadcasting it. butr ships no
|
|
356
273
|
* RPC, so the consumer broadcasts the returned bytes via
|
|
357
274
|
* `@solana/kit` / `@solana/web3.js` / etc. */
|
|
358
|
-
signTransaction?: (tx:
|
|
275
|
+
signTransaction?: (tx: TransactionInput, account?: Account) => Promise<Uint8Array>;
|
|
359
276
|
};
|
|
360
277
|
/**
|
|
361
278
|
* Sui wallet surface. Adds optional `signTransaction` for the
|
|
@@ -363,24 +280,27 @@ type SvmWallet = WalletBase & {
|
|
|
363
280
|
* consumer via `@mysten/sui`'s SuiClient.
|
|
364
281
|
*/
|
|
365
282
|
type SuiWallet = WalletBase & {
|
|
366
|
-
|
|
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<{
|
|
288
|
+
bytes: Uint8Array;
|
|
289
|
+
signature: Uint8Array;
|
|
290
|
+
}>;
|
|
367
291
|
};
|
|
368
292
|
/**
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
* broadcast through their own Esplora / Electrum client.
|
|
293
|
+
* `signTransaction` is `bitcoin:signPsbt`: pass `psbt.toBuffer()` bytes
|
|
294
|
+
* and get signed PSBT bytes back, to finalise and broadcast through
|
|
295
|
+
* your own Esplora or Electrum client.
|
|
373
296
|
*/
|
|
374
297
|
type BitcoinWallet = WalletBase & {
|
|
375
|
-
signTransaction?: (tx:
|
|
298
|
+
signTransaction?: (tx: TransactionInput, account?: Account) => Promise<Uint8Array>;
|
|
376
299
|
};
|
|
377
300
|
/**
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
*
|
|
381
|
-
* `getSigner()` handoff; the consumer builds and submits with the
|
|
382
|
-
* wallet's signer (e.g. polkadot-api). Message signing works via the
|
|
383
|
-
* injected `signer.signRaw`. Same shape as `EvmWallet`.
|
|
301
|
+
* No standalone `signTransaction`: building an extrinsic needs chain
|
|
302
|
+
* metadata over RPC, which butr does not ship, so transaction signing
|
|
303
|
+
* goes through the `getSigner()` handoff.
|
|
384
304
|
*/
|
|
385
305
|
type PolkadotWallet = WalletBase;
|
|
386
306
|
/** Per-platform full adapter shapes: `Connector` + the platform's
|
|
@@ -392,22 +312,9 @@ type SuiAdapter = Connector<"sui"> & SuiWallet;
|
|
|
392
312
|
type BitcoinAdapter = Connector<"bitcoin"> & BitcoinWallet;
|
|
393
313
|
type PolkadotAdapter = Connector<"polkadot"> & PolkadotWallet;
|
|
394
314
|
/**
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
*
|
|
398
|
-
* access to platform-specific methods like `signIn` (SVM) or
|
|
399
|
-
* `signTransaction` (SVM / Sui / Bitcoin). Calling those methods on a
|
|
400
|
-
* non-narrowed `WalletAdapter` is a TypeScript error; that's the
|
|
401
|
-
* point. The discriminant carries the type-level fact "this method
|
|
402
|
-
* doesn't exist on EVM" so consumers can't accidentally branch on
|
|
403
|
-
* `capabilities.signIn` and call a method that EVM adapters don't
|
|
404
|
-
* implement.
|
|
405
|
-
*
|
|
406
|
-
* Runtime gating via `capabilities` still matters for the methods that
|
|
407
|
-
* are OPTIONAL within a platform (a Solana wallet might or might not
|
|
408
|
-
* advertise `solana:signTransaction`). Capabilities narrow "wallet
|
|
409
|
-
* supports this feature"; the discriminated union narrows "this
|
|
410
|
-
* platform has this concept at all".
|
|
315
|
+
* The union narrows "this platform has the concept at all"; the
|
|
316
|
+
* `capabilities` flags narrow "this wallet supports it right now".
|
|
317
|
+
* Both gates are needed, and neither substitutes for the other.
|
|
411
318
|
*/
|
|
412
319
|
type WalletAdapter = EvmAdapter | SvmAdapter | SuiAdapter | BitcoinAdapter | PolkadotAdapter;
|
|
413
320
|
type ConnectedWallet = {
|
|
@@ -422,33 +329,15 @@ type ConnectedWallet = {
|
|
|
422
329
|
//#endregion
|
|
423
330
|
//#region src/types/discoverer.d.ts
|
|
424
331
|
/**
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
* `@usebutr/bitcoin`) exports one of these. The aggregator package
|
|
429
|
-
* (`@usebutr/wallets`) composes them into `autoDiscovery()` without
|
|
430
|
-
* needing to know per-platform defaults; the descriptor owns them.
|
|
431
|
-
*
|
|
432
|
-
* Adding a new chain platform means writing a `PlatformDiscoverer`
|
|
433
|
-
* inside the new package and adding one import to the aggregator's
|
|
434
|
-
* registry, which is keyed by `ChainPlatform`. The aggregator's logic
|
|
435
|
-
* doesn't need to grow.
|
|
436
|
-
*
|
|
437
|
-
* Two parts:
|
|
438
|
-
* - `subscribe`: the primary discovery channel (EIP-6963 / Wallet
|
|
439
|
-
* Standard / etc).
|
|
440
|
-
* - `fallback`: optional. The legacy-injected channel that should
|
|
441
|
-
* only emit if the primary channel hasn't produced an adapter for
|
|
442
|
-
* the same browser session by the settle deadline. `@usebutr/evm`
|
|
443
|
-
* has one (window.ethereum); `@usebutr/bitcoin` has one
|
|
444
|
-
* (window.unisat / sats-connect / window.btc); SVM and Sui don't.
|
|
332
|
+
* Each platform package exports exactly one; `@usebutr/wallets` composes
|
|
333
|
+
* them via a registry keyed by `ChainPlatform`, so a new chain adds a
|
|
334
|
+
* descriptor and a registry entry, not aggregator logic.
|
|
445
335
|
*/
|
|
446
336
|
type PlatformDiscoverer = {
|
|
447
337
|
/**
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
* for the same wallet has already announced through the primary path.
|
|
338
|
+
* Legacy-injected channel (window.ethereum, window.unisat, …). Must
|
|
339
|
+
* consult `hasAnyPrimaryAdapter` and stay quiet when standards-based
|
|
340
|
+
* discovery already announced the same wallet, or it double-lists.
|
|
452
341
|
*/
|
|
453
342
|
fallback?: {
|
|
454
343
|
subscribe: (onAdapter: (adapter: WalletAdapter) => void, opts: {
|
|
@@ -461,16 +350,9 @@ type PlatformDiscoverer = {
|
|
|
461
350
|
//#endregion
|
|
462
351
|
//#region src/types/errors.d.ts
|
|
463
352
|
/**
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
*
|
|
467
|
-
* MetaMask uses EIP-1193 codes, Phantom throws stringly-typed errors,
|
|
468
|
-
* embedded SDKs throw their own classes) into a small set of UX-meaningful
|
|
469
|
-
* variants. Consumers branch on `kind` instead of regexing message strings.
|
|
470
|
-
*
|
|
471
|
-
* `message` is always present and human-readable. `cause` preserves the
|
|
472
|
-
* original thrown value so callers can inspect raw connector errors when
|
|
473
|
-
* the variant is `Unknown`.
|
|
353
|
+
* Wallet SDKs disagree on error shape (EIP-1193 codes, bare strings,
|
|
354
|
+
* bespoke classes), so consumers branch on `kind` rather than regexing
|
|
355
|
+
* messages. `cause` keeps the original value for the `Unknown` case.
|
|
474
356
|
*/
|
|
475
357
|
type ConnectionError = {
|
|
476
358
|
kind: "UserRejected";
|
|
@@ -493,25 +375,21 @@ type ConnectionError = {
|
|
|
493
375
|
kind: "Timeout";
|
|
494
376
|
message: string;
|
|
495
377
|
} | {
|
|
496
|
-
cause?:
|
|
378
|
+
cause?: ErrorCause;
|
|
497
379
|
kind: "Unknown";
|
|
498
380
|
message: string;
|
|
499
381
|
};
|
|
500
382
|
type ConnectionErrorKind = ConnectionError["kind"];
|
|
383
|
+
type ErrorCause = Error | string;
|
|
384
|
+
type CodedError = Error & {
|
|
385
|
+
code: number | string;
|
|
386
|
+
};
|
|
501
387
|
/**
|
|
502
|
-
*
|
|
503
|
-
*
|
|
504
|
-
*
|
|
505
|
-
* - butr's own `Error("Connection timeout")` (from the 90s connect timeout)
|
|
506
|
-
* - butr's own `Error("Failed to get account")` (from the connect flow)
|
|
507
|
-
* - EIP-1193 numeric `code` properties (`4001` → UserRejected,
|
|
508
|
-
* `-32002` → RequestPending, `4100`/`4900`/`4901` → NotConnected:
|
|
509
|
-
* unauthorized / disconnected from all-or-one chains)
|
|
510
|
-
* - common message substrings: "user rejected" / "user denied",
|
|
511
|
-
* "locked", "chain", etc.
|
|
512
|
-
* - anything else → `Unknown` with `cause` set to the original value.
|
|
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.
|
|
513
391
|
*/
|
|
514
|
-
declare const mapConnectionError: (raw:
|
|
392
|
+
declare const mapConnectionError: (raw: ErrorCause) => ConnectionError;
|
|
515
393
|
//#endregion
|
|
516
394
|
//#region src/storage/persistence.d.ts
|
|
517
395
|
type MaybePromise<T> = T | Promise<T>;
|
|
@@ -558,16 +436,9 @@ type WalletPersistence = {
|
|
|
558
436
|
//#endregion
|
|
559
437
|
//#region src/storage/snapshot.d.ts
|
|
560
438
|
/**
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
* Notably absent: the `Connector` instance. A wallet extension exists
|
|
566
|
-
* only in the browser, so a server render can know *which* wallet was
|
|
567
|
-
* connected and *what address* it held, but cannot dispatch
|
|
568
|
-
* `signMessage`/`sendTransaction` on it. Splitting display from action
|
|
569
|
-
* along this seam keeps the impossibility expressed in the types
|
|
570
|
-
* rather than hidden inside a runtime check.
|
|
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.
|
|
571
442
|
*/
|
|
572
443
|
type WalletSnapshot = {
|
|
573
444
|
activeConnectorId: string | null;
|
|
@@ -587,53 +458,22 @@ type SnapshotOptions = {
|
|
|
587
458
|
};
|
|
588
459
|
declare const EMPTY_SNAPSHOT: WalletSnapshot;
|
|
589
460
|
/**
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
* (Server Component, route handler, edge middleware, even client
|
|
594
|
-
* code). Pair with `createCookieStorageDriver({ initialCookies })`
|
|
595
|
-
* and `<WalletManagerProvider initialSnapshot={…} />` to render a
|
|
596
|
-
* connected shell server-side without a hydration flash.
|
|
597
|
-
*
|
|
598
|
-
* **Stale-snapshot semantics.** The snapshot reflects whatever the
|
|
599
|
-
* browser most recently persisted. If the user has since uninstalled
|
|
600
|
-
* the wallet, switched accounts, or disconnected in another tab, the
|
|
601
|
-
* client-side hydration will reconcile reality and the live store
|
|
602
|
-
* will diverge from the snapshot. Treat the snapshot as an
|
|
603
|
-
* *optimistic* shell; accurate enough to avoid a paint flicker,
|
|
604
|
-
* authoritative only after `useIsHydrated()` is true.
|
|
605
|
-
*
|
|
606
|
-
* **Inputs.** Accepts the three shapes Next.js / Express / Hono /
|
|
607
|
-
* generic-Node cookie code naturally produces:
|
|
608
|
-
* - A plain object: `{ "butr-pool": "{...}", … }`
|
|
609
|
-
* - An array of `{ name, value }` (Next.js' `cookies().getAll()`)
|
|
610
|
-
* - An iterable of `[name, value]` tuples
|
|
611
|
-
*
|
|
612
|
-
* Malformed entries are dropped with a `logWarn` (same policy as
|
|
613
|
-
* `WalletStorage.getPool`); a cross-tab corruption shouldn't crash
|
|
614
|
-
* the server render.
|
|
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.
|
|
615
464
|
*/
|
|
616
465
|
declare const readWalletSnapshot: (source: CookieSource, options?: SnapshotOptions) => WalletSnapshot;
|
|
617
466
|
//#endregion
|
|
618
467
|
//#region src/types/manager.d.ts
|
|
619
468
|
/**
|
|
620
|
-
*
|
|
621
|
-
*
|
|
622
|
-
*
|
|
623
|
-
* - `restoredIds`: wallets that came back fully. Their pool entries
|
|
624
|
-
* are live and consumers can use them immediately.
|
|
625
|
-
* - `pendingIds`: wallets whose adapter wasn't registered yet
|
|
626
|
-
* (auto-discovery's async warmup). The runtime retries each one
|
|
627
|
-
* when discovery announces a matching id, so most of these will
|
|
628
|
-
* restore within a few hundred ms of mount.
|
|
629
|
-
* - `dropped`: wallets whose restore actually failed (connector
|
|
630
|
-
* threw mid-flight). These have been removed from storage; consumer
|
|
631
|
-
* UX can surface "Couldn't reconnect Phantom; connect again."
|
|
469
|
+
* `pendingIds` are not failures: discovery announces those adapters
|
|
470
|
+
* asynchronously and the runtime retries them, usually within a few
|
|
471
|
+
* hundred ms. Only `dropped` entries have been removed from storage.
|
|
632
472
|
*/
|
|
633
473
|
type HydrationOutcome = {
|
|
634
474
|
dropped: Array<{
|
|
635
475
|
connectorId: string;
|
|
636
|
-
reason:
|
|
476
|
+
reason: ErrorCause;
|
|
637
477
|
}>;
|
|
638
478
|
pendingIds: Array<string>;
|
|
639
479
|
restoredIds: Array<string>;
|
|
@@ -644,67 +484,37 @@ type WalletManagerConfig = {
|
|
|
644
484
|
/** Function to instantiate a connector by ID */
|
|
645
485
|
createConnector: (id: string) => WalletAdapter | null;
|
|
646
486
|
/**
|
|
647
|
-
*
|
|
648
|
-
*
|
|
649
|
-
*
|
|
650
|
-
* - `pool` is populated with `ConnectedWallet` entries whose
|
|
651
|
-
* `connector` is a shadow adapter (see `createShadowAdapter`):
|
|
652
|
-
* identity-only, all capabilities `false`, methods throw
|
|
653
|
-
* `ShadowConnectorError` if called.
|
|
654
|
-
* - `activeConnectorId` and `selection` are set from the snapshot.
|
|
655
|
-
* - `isHydrated` flips `true` immediately on construction.
|
|
656
|
-
* - Every seeded id appears in `reconnectingIds`; the background
|
|
657
|
-
* silent-reconnect pass removes the id and replaces the pool
|
|
658
|
-
* entry with a live adapter on success, or drops the entry on
|
|
659
|
-
* failure.
|
|
660
|
-
*
|
|
661
|
-
* Pre-hydration UI renders from the snapshot's data (address,
|
|
662
|
-
* accounts, chain, name, icon) without a flash. Action affordances
|
|
663
|
-
* (sign, send) are naturally gated by the shadow's all-false
|
|
664
|
-
* capabilities, or consumers can branch on `reconnectingIds`.
|
|
487
|
+
* Seeds the pool with shadow adapters and flips `isHydrated` true on
|
|
488
|
+
* construction, so identity renders without a flash but every seeded
|
|
489
|
+
* id sits in `reconnectingIds` until silent reconnect verifies it.
|
|
665
490
|
*/
|
|
666
491
|
initialState?: WalletSnapshot;
|
|
667
492
|
/** Called after a wallet is successfully connected */
|
|
668
493
|
onConnect?: (wallet: ConnectedWallet) => void;
|
|
669
494
|
/**
|
|
670
|
-
*
|
|
671
|
-
*
|
|
672
|
-
* `
|
|
673
|
-
* connected. Useful for piping into observability tooling
|
|
674
|
-
* (Sentry, OTel) without each consumer wiring `try/catch`s around
|
|
675
|
-
* `connectWallet` themselves.
|
|
495
|
+
* Fires for every failed attempt (rejection, locked wallet, timeout,
|
|
496
|
+
* …), so observability can hook here instead of wrapping every
|
|
497
|
+
* `connectWallet` call.
|
|
676
498
|
*/
|
|
677
499
|
onConnectError?: (error: ConnectionError, connectorId: string) => void;
|
|
678
500
|
/** Called after a wallet is disconnected */
|
|
679
501
|
onDisconnect?: (chainPlatform: ChainPlatform) => void;
|
|
680
|
-
/**
|
|
681
|
-
* Called once after butr's mount-time hydration finishes. Receives a
|
|
682
|
-
* `HydrationOutcome` summarising which stored wallets were restored,
|
|
683
|
-
* which are pending an adapter announcement, and which failed.
|
|
684
|
-
* Useful for surfacing "Phantom couldn't be reconnected; try
|
|
685
|
-
* again" UX or piping a metric to telemetry.
|
|
686
|
-
*/
|
|
502
|
+
/** Fires once, after the mount-time hydration pass. */
|
|
687
503
|
onHydrated?: (outcome: HydrationOutcome) => void;
|
|
688
504
|
/** Called after all wallets are reset (e.g., to clear auth tokens) */
|
|
689
505
|
onReset?: () => void | Promise<void>;
|
|
690
506
|
/**
|
|
691
|
-
*
|
|
692
|
-
* `slowConnectThresholdMs`
|
|
693
|
-
*
|
|
694
|
-
* surfacing a "still trying, check your wallet" hint in the UI or
|
|
695
|
-
* piping a slow-path metric to telemetry.
|
|
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.
|
|
696
510
|
*/
|
|
697
511
|
onSlowConnect?: (connectorId: string) => void;
|
|
698
512
|
/**
|
|
699
|
-
*
|
|
700
|
-
*
|
|
701
|
-
*
|
|
702
|
-
* to know; quota-exceeded errors, IndexedDB shutdown, cross-tab
|
|
703
|
-
* conflicts, cookie size limits. `context` is a short string
|
|
704
|
-
* describing which write failed (e.g. `"failed to persist pool"`).
|
|
705
|
-
* The default behaviour when no callback is set is `console.warn`.
|
|
513
|
+
* Persistence is fire-and-forget: a failed write (quota, cookie size,
|
|
514
|
+
* cross-tab conflict) never breaks reducer state, it only surfaces
|
|
515
|
+
* here. Defaults to `console.warn`.
|
|
706
516
|
*/
|
|
707
|
-
onStorageError?: (error:
|
|
517
|
+
onStorageError?: (error: ErrorCause, context: string) => void;
|
|
708
518
|
/** Threshold for `onSlowConnect`, in milliseconds. Defaults to 5_000. */
|
|
709
519
|
slowConnectThresholdMs?: number;
|
|
710
520
|
/** Optional custom persistence implementation (e.g., cookie-backed) */
|
|
@@ -715,55 +525,9 @@ type WalletManagerConfig = {
|
|
|
715
525
|
//#endregion
|
|
716
526
|
//#region src/types/signer.d.ts
|
|
717
527
|
/**
|
|
718
|
-
*
|
|
719
|
-
*
|
|
720
|
-
*
|
|
721
|
-
* signer shape lives in the platform-specific packages: `@usebutr/evm`
|
|
722
|
-
* returns an EIP-1193 provider, `@usebutr/svm` returns a Wallet
|
|
723
|
-
* Standard wallet, `@usebutr/sui` returns the same Wallet Standard
|
|
724
|
-
* wallet narrowed to Sui features, `@usebutr/bitcoin` returns either a
|
|
725
|
-
* Wallet Standard wallet or an injected provider depending on which
|
|
726
|
-
* adapter discovered it.
|
|
727
|
-
*
|
|
728
|
-
* Consumers cast the `unknown` to whichever signer their integration
|
|
729
|
-
* library expects. This registry exists so the cast target is sourced
|
|
730
|
-
* from one place; when a platform package renames its signer type,
|
|
731
|
-
* consumer code keeps working through the registry without an explicit
|
|
732
|
-
* patch.
|
|
733
|
-
*
|
|
734
|
-
* **How to extend.** Each platform package declares a module-augmentation
|
|
735
|
-
* block that adds its key to this interface. For example,
|
|
736
|
-
* `@usebutr/evm` ships:
|
|
737
|
-
*
|
|
738
|
-
* ```ts
|
|
739
|
-
* declare module "@usebutr/core" {
|
|
740
|
-
* interface SignerForPlatform {
|
|
741
|
-
* evm: Eip1193Provider;
|
|
742
|
-
* }
|
|
743
|
-
* }
|
|
744
|
-
* ```
|
|
745
|
-
*
|
|
746
|
-
* Consumers that import the EVM package get the typed entry for free;
|
|
747
|
-
* the augmentation is transitive through TypeScript's structural
|
|
748
|
-
* declaration merging.
|
|
749
|
-
*
|
|
750
|
-
* **Usage.**
|
|
751
|
-
*
|
|
752
|
-
* ```ts
|
|
753
|
-
* import type { SignerForPlatform } from "@usebutr/core";
|
|
754
|
-
*
|
|
755
|
-
* const signer = (await wallet.connector.getSigner()) as SignerForPlatform["evm"];
|
|
756
|
-
* ```
|
|
757
|
-
*
|
|
758
|
-
* The cast is still there: `getSigner` itself stays type-erased to
|
|
759
|
-
* keep the cross-package boundary loose, but the cast target lives in
|
|
760
|
-
* one canonical place.
|
|
761
|
-
*
|
|
762
|
-
* **Why not make `getSigner` generic.** Generic-on-platform `getSigner`
|
|
763
|
-
* would require `Connector` to be a discriminated union by
|
|
764
|
-
* `chainPlatform`, which is a public-API breaking change held for a
|
|
765
|
-
* future major release. The registry is the small step you can take
|
|
766
|
-
* today; the union is the larger step that makes the cast obsolete.
|
|
528
|
+
* Canonical cast target for `getSigner()`'s `unknown`, which stays
|
|
529
|
+
* type-erased to keep the cross-package boundary loose. Platform
|
|
530
|
+
* packages add their key by augmenting this interface.
|
|
767
531
|
*/
|
|
768
532
|
interface SignerForPlatform {}
|
|
769
533
|
/** Convenience alias for narrowing a single platform's signer type. */
|
|
@@ -771,34 +535,24 @@ type SignerOf<P extends keyof SignerForPlatform> = SignerForPlatform[P];
|
|
|
771
535
|
//#endregion
|
|
772
536
|
//#region src/wallet-source.d.ts
|
|
773
537
|
/**
|
|
774
|
-
*
|
|
775
|
-
*
|
|
776
|
-
*
|
|
777
|
-
* implement this type without depending on `@usebutr/wallets`.
|
|
538
|
+
* The discovery seam: implementable by third parties without depending
|
|
539
|
+
* on `@usebutr/wallets`, which itself just composes the per-platform
|
|
540
|
+
* sources into one.
|
|
778
541
|
*/
|
|
779
542
|
type WalletSource = {
|
|
780
543
|
subscribe: (onAdapter: (adapter: WalletAdapter) => void) => () => void;
|
|
781
544
|
};
|
|
782
545
|
/**
|
|
783
|
-
*
|
|
784
|
-
*
|
|
785
|
-
* so an EVM-only app can do
|
|
786
|
-
* `createWalletSource(discoverEvmAdapters)` without importing anything
|
|
787
|
-
* protocol-bearing beyond `@usebutr/evm`.
|
|
546
|
+
* Takes the exact shape of `discoverEvmAdapters` and friends, so a
|
|
547
|
+
* single-platform app keeps `@usebutr/wallets` out of its bundle.
|
|
788
548
|
*/
|
|
789
549
|
declare const createWalletSource: (subscribe: (onAdapter: (adapter: WalletAdapter) => void) => () => void) => WalletSource;
|
|
790
550
|
//#endregion
|
|
791
551
|
//#region src/store/reducer.d.ts
|
|
792
552
|
/**
|
|
793
|
-
*
|
|
794
|
-
*
|
|
795
|
-
*
|
|
796
|
-
* attempt. The fifth value, `"reconnecting"`, is *derived* by
|
|
797
|
-
* `useConnectionStatus` when the active wallet is still backed by a
|
|
798
|
-
* shadow adapter (its id is in `state.reconnectingIds`). The
|
|
799
|
-
* derivation lives in the React selector so the reducer can stay a
|
|
800
|
-
* narrow state machine while the public API matches wagmi's
|
|
801
|
-
* vocabulary.
|
|
553
|
+
* The reducer never writes `"reconnecting"`; `useConnectionStatus`
|
|
554
|
+
* derives it from `reconnectingIds` so the state machine stays narrow
|
|
555
|
+
* while the public vocabulary matches wagmi's.
|
|
802
556
|
*/
|
|
803
557
|
type ConnectionStatus = "idle" | "connecting" | "success" | "error" | "reconnecting";
|
|
804
558
|
type State = {
|
|
@@ -810,13 +564,9 @@ type State = {
|
|
|
810
564
|
isUserDisconnected: boolean;
|
|
811
565
|
pool: Map<string, ConnectedWallet>;
|
|
812
566
|
/**
|
|
813
|
-
*
|
|
814
|
-
*
|
|
815
|
-
*
|
|
816
|
-
* the silent reconnect to succeed. The set shrinks as entries
|
|
817
|
-
* upgrade (`HYDRATED` / `CONNECT_SUCCEEDED` clear matching ids) or
|
|
818
|
-
* drop (`DISCONNECTED` / `RESET`). Empty for stores constructed
|
|
819
|
-
* without `initialState`.
|
|
567
|
+
* Ids still backed by a shadow adapter from `initialState`. Empty
|
|
568
|
+
* without `initialState`; shrinks on `HYDRATED` / `CONNECT_SUCCEEDED`
|
|
569
|
+
* and on `DISCONNECTED` / `RESET`.
|
|
820
570
|
*/
|
|
821
571
|
reconnectingIds: ReadonlySet<string>;
|
|
822
572
|
selection: Map<ChainPlatform, string>;
|
|
@@ -824,40 +574,20 @@ type State = {
|
|
|
824
574
|
//#endregion
|
|
825
575
|
//#region src/store/shadow-adapter.d.ts
|
|
826
576
|
/**
|
|
827
|
-
*
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
* snapshot). Shadow adapters carry the identity and account data of a
|
|
831
|
-
* previously-connected wallet, but the live wallet extension hasn't
|
|
832
|
-
* been verified yet; the silent reconnect happens asynchronously
|
|
833
|
-
* after mount.
|
|
834
|
-
*
|
|
835
|
-
* UI code that gates affordances on `wallet.connector.capabilities.*`
|
|
836
|
-
* never reaches a shadow method (capabilities are all `false`). Code
|
|
837
|
-
* that calls through anyway hits this typed error, which is the
|
|
838
|
-
* correct loud failure: the consumer ignored the capability gate.
|
|
839
|
-
*
|
|
840
|
-
* Consumers wanting to wait out the reconnecting window should branch
|
|
841
|
-
* on whether `connectorId` is in `state.reconnectingIds`.
|
|
577
|
+
* Loud failure for consumers that called a wallet method without gating
|
|
578
|
+
* on `capabilities.*` (all `false` here) or `reconnectingIds`, before
|
|
579
|
+
* silent reconnect swapped in the live adapter.
|
|
842
580
|
*/
|
|
843
|
-
declare class ShadowConnectorError extends Error {
|
|
581
|
+
declare class ShadowConnectorError extends Error implements CodedError {
|
|
844
582
|
readonly code = "BUTR_RECONNECTING";
|
|
845
583
|
readonly connectorId: string;
|
|
846
584
|
readonly method: string;
|
|
847
585
|
constructor(method: string, connectorId: string);
|
|
848
586
|
}
|
|
849
587
|
/**
|
|
850
|
-
*
|
|
851
|
-
*
|
|
852
|
-
*
|
|
853
|
-
* for consumers writing wagmi-style "is this connection verified yet"
|
|
854
|
-
* checks without subscribing to `reconnectingIds` directly.
|
|
855
|
-
*
|
|
856
|
-
* Detection is structural: a shadow has all capabilities set to false.
|
|
857
|
-
* Live adapters always advertise at least one capability (every wallet
|
|
858
|
-
* surface includes `getBalance`, `signMessage`, `switchChain` as
|
|
859
|
-
* required methods, and adapter constructors set their flags
|
|
860
|
-
* accordingly).
|
|
588
|
+
* Structural detection: relies on every live adapter advertising at
|
|
589
|
+
* least one capability, since `getBalance`, `signMessage` and
|
|
590
|
+
* `switchChain` are required on all wallet surfaces.
|
|
861
591
|
*/
|
|
862
592
|
declare const isShadowAdapter: (adapter: WalletAdapter) => boolean;
|
|
863
593
|
//#endregion
|
|
@@ -886,22 +616,13 @@ type CookieDriverOptions = {
|
|
|
886
616
|
*/
|
|
887
617
|
domain?: string;
|
|
888
618
|
/**
|
|
889
|
-
*
|
|
890
|
-
*
|
|
891
|
-
*
|
|
892
|
-
*
|
|
893
|
-
* When provided, `getItem` reads from this snapshot during the
|
|
894
|
-
* server render so the store sees the same persisted state the
|
|
895
|
-
* client will see after hydration. Writes remain no-ops on the
|
|
896
|
-
* server: emitting `Set-Cookie` has to be done by the framework
|
|
897
|
-
* layer that owns the response.
|
|
619
|
+
* Server-side cookie snapshot (Next.js' `cookies()`, a parsed
|
|
620
|
+
* `req.headers.cookie`, …) read only when `document` is unavailable,
|
|
621
|
+
* so the SSR pass sees the state the client will hydrate with.
|
|
898
622
|
*/
|
|
899
623
|
initialCookies?: InitialCookies;
|
|
900
624
|
/**
|
|
901
|
-
* Lifetime in seconds. Defaults to 30 days.
|
|
902
|
-
* (the default) for "until the session ends", but note that
|
|
903
|
-
* butr persists wallet state across sessions, so a finite
|
|
904
|
-
* max-age is usually what consumers want.
|
|
625
|
+
* Lifetime in seconds. Defaults to 30 days.
|
|
905
626
|
*/
|
|
906
627
|
maxAgeSeconds?: number;
|
|
907
628
|
/**
|
|
@@ -921,34 +642,16 @@ type CookieDriverOptions = {
|
|
|
921
642
|
secure?: boolean;
|
|
922
643
|
};
|
|
923
644
|
/**
|
|
924
|
-
*
|
|
925
|
-
*
|
|
926
|
-
*
|
|
927
|
-
* **When to use this:** SSR apps that need to know who's connected
|
|
928
|
-
* during the server render (so they can stream the connected-wallet
|
|
929
|
-
* UI without a client-side hydration flicker). Pass `initialCookies`
|
|
930
|
-
* from a server-side cookie source (e.g. `cookies()` in Next.js'
|
|
931
|
-
* `next/headers`, or a parsed `req.headers.cookie`) and the same
|
|
932
|
-
* driver will serve those values during the server render and switch
|
|
933
|
-
* to `document.cookie` once it mounts in the browser.
|
|
934
|
-
*
|
|
935
|
-
* **Trade-offs vs `localStorage`:** cookies travel with every
|
|
936
|
-
* request, so they cost bytes on the wire. Keep the storage key
|
|
937
|
-
* prefix short, and prefer this driver for the `persistent` slot
|
|
938
|
-
* only: the `session` slot can stay in `sessionStorage` (which
|
|
939
|
-
* cookies can't natively model anyway).
|
|
940
|
-
*
|
|
941
|
-
* **Server-side writes are no-ops.** Emitting `Set-Cookie` requires
|
|
942
|
-
* access to the framework's response object, which a storage driver
|
|
943
|
-
* shouldn't reach into. The store doesn't mutate persisted state
|
|
944
|
-
* during the SSR pass anyway; writes only fire after client mount,
|
|
945
|
-
* once `document.cookie` is reachable.
|
|
645
|
+
* Server-side writes are no-ops: `Set-Cookie` needs the framework's
|
|
646
|
+
* response object. Cookies ride every request, so use this driver for
|
|
647
|
+
* the `persistent` slot only and leave `session` on `sessionStorage`.
|
|
946
648
|
*/
|
|
947
649
|
declare const createCookieStorageDriver: (options?: CookieDriverOptions) => StorageDriver;
|
|
948
650
|
//#endregion
|
|
949
651
|
//#region src/storage/wallet-storage.d.ts
|
|
950
652
|
type StorageConfig = {
|
|
951
|
-
|
|
653
|
+
/** Defaults to `"butr"`, matching `readWalletSnapshot`. */
|
|
654
|
+
keyPrefix?: string;
|
|
952
655
|
/** Survives app restart. Defaults to localStorage on web. */
|
|
953
656
|
persistent?: StorageDriver;
|
|
954
657
|
/** Cleared on session end. Defaults to sessionStorage on web. */
|
|
@@ -962,27 +665,22 @@ declare class WalletStorage implements WalletPersistence {
|
|
|
962
665
|
private readonly persistent;
|
|
963
666
|
private readonly session;
|
|
964
667
|
/**
|
|
965
|
-
* Serializes pool-
|
|
966
|
-
*
|
|
967
|
-
*
|
|
968
|
-
* state, each merge their own entries, and whichever finishes last
|
|
969
|
-
* overwrites the other's additions. Reads (`getPool`) don't enter
|
|
970
|
-
* the queue; they observe whatever's currently in the driver.
|
|
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.
|
|
971
671
|
*/
|
|
972
672
|
private poolMutationQueue;
|
|
973
673
|
constructor(config: StorageConfig);
|
|
974
674
|
/** Chain `fn` after the in-flight pool mutation. */
|
|
975
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;
|
|
976
679
|
getPool(): Promise<StoredPoolRecord>;
|
|
977
680
|
/**
|
|
978
|
-
*
|
|
979
|
-
*
|
|
980
|
-
*
|
|
981
|
-
* now", not "the complete list of remembered connections"; a
|
|
982
|
-
* silent reconnect that fails on reload leaves the entry out of
|
|
983
|
-
* the pool but the saved entry stays so the next load can retry.
|
|
984
|
-
* Use `removePoolEntry` for explicit eviction (the user clicked
|
|
985
|
-
* Disconnect) and `clearAll` for a full wipe (reset).
|
|
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`.
|
|
986
684
|
*/
|
|
987
685
|
setPool(pool: Map<string, ConnectedWallet>): Promise<void>;
|
|
988
686
|
removePoolEntry(connectorId: string): Promise<void>;
|
|
@@ -993,12 +691,9 @@ declare class WalletStorage implements WalletPersistence {
|
|
|
993
691
|
setActiveConnectorId(connectorId: string | null): Promise<void>;
|
|
994
692
|
clearAll(): Promise<void>;
|
|
995
693
|
/**
|
|
996
|
-
*
|
|
997
|
-
*
|
|
998
|
-
*
|
|
999
|
-
* but clears when the session ends (unlike the persistent driver).
|
|
1000
|
-
* Prevents auto-connect from firing immediately after a manual disconnect,
|
|
1001
|
-
* while still allowing auto-connect on fresh sessions.
|
|
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.
|
|
1002
697
|
*/
|
|
1003
698
|
isUserDisconnected(): Promise<boolean>;
|
|
1004
699
|
markUserDisconnected(value: boolean): Promise<void>;
|
|
@@ -1032,38 +727,17 @@ declare const createWalletStore: (config: WalletManagerConfig) => import("zustan
|
|
|
1032
727
|
//#endregion
|
|
1033
728
|
//#region src/group-by-platform.d.ts
|
|
1034
729
|
/**
|
|
1035
|
-
*
|
|
1036
|
-
*
|
|
1037
|
-
*
|
|
1038
|
-
* discovery hands back a flat list where a single brand appears several
|
|
1039
|
-
* times. Any app targeting more than one chain has to bucket that list
|
|
1040
|
-
* before rendering, and hand-rolled versions drift: butr's own demos
|
|
1041
|
-
* carried a copy that reimplemented `CHAIN_PLATFORMS` as a local
|
|
1042
|
-
* ordering constant.
|
|
1043
|
-
*
|
|
1044
|
-
* Keys are inserted in `CHAIN_PLATFORMS` order and platforms with no
|
|
1045
|
-
* members are omitted, so the result is directly iterable for rendering
|
|
1046
|
-
* (`[...groups]`) as well as addressable for lookup (`groups.get("evm")`)
|
|
1047
|
-
* without a further emptiness filter.
|
|
1048
|
-
*
|
|
1049
|
-
* `getPlatform` exists because the discriminant sits at a different depth
|
|
1050
|
-
* depending on the input: a discovered `WalletAdapter` carries
|
|
1051
|
-
* `chainPlatform` at the top level, a pool entry nests it under
|
|
1052
|
-
* `connector`. React consumers should reach for
|
|
1053
|
-
* `useDiscoveredWalletsByPlatform` / `useConnectedWalletsByPlatform`
|
|
1054
|
-
* instead, which bind the accessor for them.
|
|
730
|
+
* A multi-chain wallet announces one adapter per platform, so brands
|
|
731
|
+
* repeat in the flat list. Keys follow `CHAIN_PLATFORMS` order and empty
|
|
732
|
+
* platforms are omitted, so `[...groups]` needs no emptiness filter.
|
|
1055
733
|
*/
|
|
1056
734
|
declare const groupByPlatform: <T>(items: ReadonlyArray<T>, getPlatform: (item: T) => ChainPlatform) => Map<ChainPlatform, Array<T>>;
|
|
1057
735
|
//#endregion
|
|
1058
736
|
//#region src/sign-in/sign-in-flow.d.ts
|
|
1059
737
|
/**
|
|
1060
|
-
*
|
|
1061
|
-
*
|
|
1062
|
-
* `Uint8Array`
|
|
1063
|
-
*
|
|
1064
|
-
* Verify against `signedMessage`, not `message`. Solana Wallet Standard
|
|
1065
|
-
* wallets may prefix or re-encode what they sign, so the bytes that carry
|
|
1066
|
-
* the signature are the wallet's, not yours.
|
|
738
|
+
* Verify against `signedMessage`, not `message`: Solana Wallet Standard
|
|
739
|
+
* wallets may prefix or re-encode what they sign. Base64 mirrors exist
|
|
740
|
+
* because `Uint8Array` does not survive `JSON.stringify`.
|
|
1067
741
|
*/
|
|
1068
742
|
type SignInResult = {
|
|
1069
743
|
account: Account;
|
|
@@ -1086,15 +760,9 @@ type SignInMessageContext = {
|
|
|
1086
760
|
};
|
|
1087
761
|
type SignInFlowOptions = {
|
|
1088
762
|
/**
|
|
1089
|
-
*
|
|
1090
|
-
*
|
|
1091
|
-
*
|
|
1092
|
-
* butr deliberately does not ship a wire format here: a message a
|
|
1093
|
-
* server must parse is an authentication spec, and SIWE / SIWS already
|
|
1094
|
-
* fill that role. Pass the formatter your backend expects.
|
|
1095
|
-
*
|
|
1096
|
-
* Unused on the SIWS path, where the wallet composes the message from
|
|
1097
|
-
* the input fields.
|
|
763
|
+
* butr ships no wire format: a server-parsed message is an auth spec,
|
|
764
|
+
* and SIWE / SIWS already fill that role. Pass what your backend
|
|
765
|
+
* expects. Unused on the SIWS path, where the wallet composes it.
|
|
1098
766
|
*/
|
|
1099
767
|
buildMessage?: (ctx: SignInMessageContext) => string;
|
|
1100
768
|
/** Fetch a single-use nonce from your backend. */
|
|
@@ -1111,6 +779,9 @@ type SignInFlowOptions = {
|
|
|
1111
779
|
/** Hand the signed result to your backend. Throw to fail the flow. */
|
|
1112
780
|
verify: (result: SignInResult) => Promise<void>;
|
|
1113
781
|
};
|
|
782
|
+
type SignInFlow = {
|
|
783
|
+
signIn: (wallet: ConnectedWallet, account?: Account) => Promise<SignInResult>;
|
|
784
|
+
};
|
|
1114
785
|
/** Thrown before any wallet interaction when the wallet can't sign at
|
|
1115
786
|
* all. Distinct from a rejection: nothing was asked of the user, so UI
|
|
1116
787
|
* should say "this wallet can't sign in" rather than "you declined". */
|
|
@@ -1119,52 +790,17 @@ declare class SignInUnsupportedError extends Error {
|
|
|
1119
790
|
constructor(connectorId: string);
|
|
1120
791
|
}
|
|
1121
792
|
/**
|
|
1122
|
-
*
|
|
1123
|
-
*
|
|
1124
|
-
*
|
|
1125
|
-
* Every wallet-auth app writes this same sequence, and the parts that
|
|
1126
|
-
* are easy to get wrong are the ones that aren't about the app: which
|
|
1127
|
-
* capability flag gates the attempt, whether a Solana wallet should take
|
|
1128
|
-
* the SIWS path instead, and which bytes to base64 for the server (the
|
|
1129
|
-
* wallet's `signedMessage`, not the input). This owns those; you own the
|
|
1130
|
-
* nonce endpoint, the message format, and the verifier.
|
|
1131
|
-
*
|
|
1132
|
-
* ```ts
|
|
1133
|
-
* const { signIn } = createSignInFlow({
|
|
1134
|
-
* getNonce: () => fetch("/api/nonce").then((r) => r.text()),
|
|
1135
|
-
* verify: (result) =>
|
|
1136
|
-
* fetch("/api/verify", { body: JSON.stringify(result), method: "POST" }).then(() => {}),
|
|
1137
|
-
* });
|
|
1138
|
-
*
|
|
1139
|
-
* await signIn(wallet);
|
|
1140
|
-
* ```
|
|
1141
|
-
*
|
|
1142
|
-
* Solana wallets advertising `solana:signIn` take the SIWS path
|
|
1143
|
-
* automatically, so `result.signedMessage` holds the wallet-composed
|
|
1144
|
-
* SIWS statement and `result.message` is absent. Set
|
|
1145
|
-
* `preferSignMessage` to opt out.
|
|
793
|
+
* Solana wallets advertising `solana:signIn` take the SIWS path, so
|
|
794
|
+
* `result.signedMessage` holds the wallet-composed statement and
|
|
795
|
+
* `result.message` is absent. `preferSignMessage` opts out.
|
|
1146
796
|
*/
|
|
1147
|
-
declare const createSignInFlow: (options: SignInFlowOptions) =>
|
|
1148
|
-
signIn: (wallet: ConnectedWallet, account?: Account) => Promise<SignInResult>;
|
|
1149
|
-
};
|
|
797
|
+
declare const createSignInFlow: (options: SignInFlowOptions) => SignInFlow;
|
|
1150
798
|
//#endregion
|
|
1151
799
|
//#region src/wallet-equal.d.ts
|
|
1152
800
|
/**
|
|
1153
|
-
*
|
|
1154
|
-
*
|
|
1155
|
-
*
|
|
1156
|
-
* (active-wallet, selected-wallet, useWalletEntry) to suppress spurious
|
|
1157
|
-
* re-renders when the underlying Map churns but the resolved entry
|
|
1158
|
-
* hasn't changed.
|
|
1159
|
-
*
|
|
1160
|
-
* The adapter is compared by reference, not by `connector.id`: hydration
|
|
1161
|
-
* replaces a shadow adapter with the live one under an unchanged id and
|
|
1162
|
-
* address, so an id comparison reports "equal" and leaves consumers
|
|
1163
|
-
* holding a placeholder whose every method throws ShadowConnectorError.
|
|
1164
|
-
*
|
|
1165
|
-
* Hoisted to its own module so the equivalence rule lives in one place;
|
|
1166
|
-
* if we ever extend the snapshot (e.g. to consider `accounts.length`),
|
|
1167
|
-
* every selector hook picks up the new rule for free.
|
|
801
|
+
* The adapter is compared by reference, not `connector.id`: hydration
|
|
802
|
+
* swaps a shadow adapter for the live one under an unchanged id, and an
|
|
803
|
+
* id check would strand consumers on the throwing placeholder.
|
|
1168
804
|
*/
|
|
1169
805
|
declare const walletEqual: (a: ConnectedWallet | undefined, b: ConnectedWallet | undefined) => boolean;
|
|
1170
806
|
//#endregion
|
|
@@ -1174,43 +810,17 @@ declare const logError: (...args: ReadonlyArray<unknown>) => void;
|
|
|
1174
810
|
//#endregion
|
|
1175
811
|
//#region src/sanitize-icon.d.ts
|
|
1176
812
|
/**
|
|
1177
|
-
*
|
|
1178
|
-
*
|
|
1179
|
-
*
|
|
1180
|
-
* `providerInfo.icon`, Wallet Standard `wallet.icon`. That value is
|
|
1181
|
-
* not under butr's control, and some wallets ship data-URI icons with
|
|
1182
|
-
* surrounding whitespace (a newline left over from a pretty-printed
|
|
1183
|
-
* manifest). Strict consumers reject it: Next.js's `<Image>` throws
|
|
1184
|
-
* because `src` must not start with a control character.
|
|
1185
|
-
*
|
|
1186
|
-
* Trims surrounding whitespace and treats an all-whitespace (or empty)
|
|
1187
|
-
* icon as absent, so consumers get either a usable string or
|
|
1188
|
-
* `undefined`: never a blank or malformed one. `undefined` passes
|
|
1189
|
-
* through untouched.
|
|
1190
|
-
*
|
|
1191
|
-
* **Discovery already applies this.** Every adapter butr discovers has
|
|
1192
|
-
* had its icon sanitized at construction, so `Connector.icon` is safe to
|
|
1193
|
-
* render as-is. Reach for this helper only when building adapter or
|
|
1194
|
-
* `ConnectorMeta` metadata yourself from a source butr didn't produce.
|
|
813
|
+
* Some wallets announce data-URI icons wrapped in whitespace, which
|
|
814
|
+
* makes Next.js `<Image>` throw on a leading control character.
|
|
815
|
+
* Discovery already applies this; only hand-built metadata needs it.
|
|
1195
816
|
*/
|
|
1196
817
|
declare const sanitizeIcon: (icon: string | undefined) => string | undefined;
|
|
1197
818
|
//#endregion
|
|
1198
819
|
//#region src/encoding/bytes.d.ts
|
|
1199
820
|
/**
|
|
1200
|
-
*
|
|
1201
|
-
*
|
|
1202
|
-
*
|
|
1203
|
-
* chain. They used to be hand-reimplemented in ~10 connector files; a
|
|
1204
|
-
* single tested module removes the drift surface (a `padStart` omission
|
|
1205
|
-
* or base64 variant mismatch corrupts signatures/addresses for one chain
|
|
1206
|
-
* only, and the divergence is invisible because the copies look "the
|
|
1207
|
-
* same").
|
|
1208
|
-
*
|
|
1209
|
-
* Hex prefixing diverges across chains, so the module exposes **explicit
|
|
1210
|
-
* variants** rather than one function:
|
|
1211
|
-
* - {@link bytesToHex} returns bare hex (Bitcoin, Ledger).
|
|
1212
|
-
* - {@link bytesToHexPrefixed} returns `0x`-prefixed hex (EVM, Polkadot).
|
|
1213
|
-
* - {@link hexToBytes} tolerantly strips an optional `0x` (all callers).
|
|
821
|
+
* Hex prefixing diverges by chain (bare for Bitcoin and Ledger, `0x` for
|
|
822
|
+
* EVM and Polkadot), so the variants stay explicit: these sit on the
|
|
823
|
+
* signing path, where a silent mismatch corrupts one chain's signatures.
|
|
1214
824
|
*/
|
|
1215
825
|
/** Bare lowercase hex, no `0x` prefix (Bitcoin, Ledger). */
|
|
1216
826
|
declare const bytesToHex: (bytes: Uint8Array) => string;
|
|
@@ -1239,5 +849,5 @@ declare const bytesToBase58: (bytes: Uint8Array) => string;
|
|
|
1239
849
|
* rather than silently dropping them. */
|
|
1240
850
|
declare const base58ToBytes: (input: string) => Uint8Array;
|
|
1241
851
|
//#endregion
|
|
1242
|
-
export { type Account, type Balance, type BitcoinAdapter, type BitcoinWallet, type BrowserStorageDrivers, CHAIN_PLATFORMS, type ChainBase, type ChainPlatform, type ChainsByPlatform, type ConnectedWallet, type ConnectionError, type ConnectionErrorKind, type ConnectionStatus, type Connector, type ConnectorEvent, type ConnectorMeta, type CookieDriverOptions, type CookieSource, EMPTY_SNAPSHOT, type EvmAdapter, type EvmWallet, type HydrationOutcome, type InitialCookies, type MaybePromise, type PlatformDiscoverer, type PolkadotAdapter, type PolkadotWallet, ShadowConnectorError, type SignInFlowOptions, type SignInMessageContext, type SignInResult, SignInUnsupportedError, type SignerForPlatform, type SignerOf, type SnapshotOptions, type StorageDriver, type StoredPoolEntry, type StoredPoolRecord, type StoredSelectionRecord, type SuiAdapter, type SuiWallet, type SvmAdapter, type SvmWallet, type WalletAdapter, type WalletAvailability, type WalletBase, type WalletCapabilities, type WalletManagerConfig, type WalletPersistence, type WalletSnapshot, type WalletSource, WalletStorage, type WalletStore, type WalletStoreState, base58ToBytes, base64ToBytes, buildAccount, buildChainsByPlatform, bytesToBase58, bytesToBase64, bytesToHex, bytesToHexPrefixed, createBrowserStorageDriver, createCookieStorageDriver, createMemoryStorageDriver, createSignInFlow, createWalletSource, createWalletStore, groupByPlatform, hexToBytes, isShadowAdapter, logError, logWarn, mapConnectionError, readWalletSnapshot, sanitizeIcon, walletEqual };
|
|
852
|
+
export { type Account, type Balance, type BitcoinAdapter, type BitcoinWallet, type BrowserStorageDrivers, CHAIN_PLATFORMS, type ChainBase, type ChainPlatform, type ChainsByPlatform, type ConnectedWallet, type ConnectionError, type ConnectionErrorKind, type ConnectionStatus, type Connector, type ConnectorEvent, type ConnectorMeta, type CookieDriverOptions, type CookieSource, EMPTY_SNAPSHOT, type EvmAdapter, type EvmWallet, type HydrationOutcome, type InitialCookies, type MaybePromise, type PlatformDiscoverer, type PolkadotAdapter, type PolkadotWallet, ShadowConnectorError, type SignInFlowOptions, type SignInInput, type SignInMessageContext, type SignInResult, SignInUnsupportedError, type SignInValue, type SignerForPlatform, type SignerOf, type SnapshotOptions, type StorageDriver, type StoredPoolEntry, type StoredPoolRecord, type StoredSelectionRecord, type SuiAdapter, type SuiWallet, type SvmAdapter, type SvmWallet, type TransactionInput, type TransactionMethod, type TransactionObject, type TransactionValue, type WalletAdapter, type WalletAvailability, type WalletBase, type WalletCapabilities, type WalletManagerConfig, type WalletPersistence, type WalletSigner, type WalletSnapshot, type WalletSource, WalletStorage, type WalletStore, type WalletStoreState, base58ToBytes, base64ToBytes, buildAccount, buildChainsByPlatform, bytesToBase58, bytesToBase64, bytesToHex, bytesToHexPrefixed, createBrowserStorageDriver, createCookieStorageDriver, createMemoryStorageDriver, createSignInFlow, createWalletSource, createWalletStore, groupByPlatform, hexToBytes, isShadowAdapter, logError, logWarn, mapConnectionError, readWalletSnapshot, sanitizeIcon, walletEqual };
|
|
1243
853
|
//# sourceMappingURL=index.d.ts.map
|