@usebutr/core 0.4.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +400 -340
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +202 -131
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -17,172 +17,7 @@ type ChainBase = {
|
|
|
17
17
|
reference: string;
|
|
18
18
|
};
|
|
19
19
|
//#endregion
|
|
20
|
-
//#region src/
|
|
21
|
-
type MaybePromise<T> = T | Promise<T>;
|
|
22
|
-
/** Low-level key/value driver. Sync on web (localStorage, MMKV),
|
|
23
|
-
* async on React Native (AsyncStorage). */
|
|
24
|
-
type StorageDriver = {
|
|
25
|
-
getItem: (key: string) => MaybePromise<string | null>;
|
|
26
|
-
removeItem: (key: string) => MaybePromise<void>;
|
|
27
|
-
setItem: (key: string, value: string) => MaybePromise<void>;
|
|
28
|
-
};
|
|
29
|
-
type StoredPoolEntry = {
|
|
30
|
-
account: Account;
|
|
31
|
-
/** All known accounts on the wallet at last persist. Always contains
|
|
32
|
-
* `account`. */
|
|
33
|
-
accounts: Array<Account>;
|
|
34
|
-
chainPlatform: ChainPlatform;
|
|
35
|
-
connectorId: string;
|
|
36
|
-
/** Wallet icon URL or data-URI captured at persist time. Lets the
|
|
37
|
-
* shadow adapter render the same icon the live adapter will when
|
|
38
|
-
* the store is seeded from a snapshot. Omitted when the adapter
|
|
39
|
-
* itself has no icon. */
|
|
40
|
-
icon?: string;
|
|
41
|
-
/** Human-facing wallet name (e.g. "MetaMask") captured at persist
|
|
42
|
-
* time. Required so the shadow adapter renders the same identity
|
|
43
|
-
* the live adapter will; no "metamask" → "MetaMask" swap at the
|
|
44
|
-
* hydration boundary. */
|
|
45
|
-
name: string;
|
|
46
|
-
};
|
|
47
|
-
type StoredPoolRecord = Partial<Record<string, StoredPoolEntry>>;
|
|
48
|
-
type StoredSelectionRecord = Partial<Record<ChainPlatform, string>>;
|
|
49
|
-
type WalletPersistence = {
|
|
50
|
-
clearAll: () => Promise<void>;
|
|
51
|
-
clearPool: () => Promise<void>;
|
|
52
|
-
getActiveConnectorId: () => Promise<string | null>;
|
|
53
|
-
getPool: () => Promise<StoredPoolRecord>;
|
|
54
|
-
getSelection: () => Promise<StoredSelectionRecord>;
|
|
55
|
-
isUserDisconnected: () => Promise<boolean>;
|
|
56
|
-
markUserDisconnected: (value: boolean) => Promise<void>;
|
|
57
|
-
removePoolEntry: (connectorId: string) => Promise<void>;
|
|
58
|
-
setActiveConnectorId: (connectorId: string | null) => Promise<void>;
|
|
59
|
-
setPool: (pool: Map<string, ConnectedWallet>) => Promise<void>;
|
|
60
|
-
setSelection: (selection: Map<ChainPlatform, string>) => Promise<void>;
|
|
61
|
-
};
|
|
62
|
-
//#endregion
|
|
63
|
-
//#region src/storage/snapshot.d.ts
|
|
64
|
-
/**
|
|
65
|
-
* Server-safe view of a butr-persisted session; everything you can
|
|
66
|
-
* know about a user's connected wallets from the cookie payload alone,
|
|
67
|
-
* without instantiating a `Connector`.
|
|
68
|
-
*
|
|
69
|
-
* Notably absent: the `Connector` instance. A wallet extension exists
|
|
70
|
-
* only in the browser, so a server render can know *which* wallet was
|
|
71
|
-
* connected and *what address* it held, but cannot dispatch
|
|
72
|
-
* `signMessage`/`sendTransaction` on it. Splitting display from action
|
|
73
|
-
* along this seam keeps the impossibility expressed in the types
|
|
74
|
-
* rather than hidden inside a runtime check.
|
|
75
|
-
*/
|
|
76
|
-
type WalletSnapshot = {
|
|
77
|
-
activeConnectorId: string | null;
|
|
78
|
-
pool: StoredPoolRecord;
|
|
79
|
-
selection: StoredSelectionRecord;
|
|
80
|
-
};
|
|
81
|
-
type CookieSource = Iterable<{
|
|
82
|
-
name: string;
|
|
83
|
-
value: string;
|
|
84
|
-
}> | Iterable<[string, string]> | Readonly<Record<string, string>>;
|
|
85
|
-
type SnapshotOptions = {
|
|
86
|
-
/**
|
|
87
|
-
* Same prefix passed to `WalletManagerProvider` / `WalletStorage`.
|
|
88
|
-
* Defaults to `"butr"` to match the library default.
|
|
89
|
-
*/
|
|
90
|
-
keyPrefix?: string;
|
|
91
|
-
};
|
|
92
|
-
declare const EMPTY_SNAPSHOT: WalletSnapshot;
|
|
93
|
-
/**
|
|
94
|
-
* Parse a cookie source into a server-safe `WalletSnapshot`.
|
|
95
|
-
*
|
|
96
|
-
* Pure, sync, no `document`, no React; runnable in any environment
|
|
97
|
-
* (Server Component, route handler, edge middleware, even client
|
|
98
|
-
* code). Pair with `createCookieStorageDriver({ initialCookies })`
|
|
99
|
-
* and `<WalletManagerProvider initialSnapshot={…} />` to render a
|
|
100
|
-
* connected shell server-side without a hydration flash.
|
|
101
|
-
*
|
|
102
|
-
* **Stale-snapshot semantics.** The snapshot reflects whatever the
|
|
103
|
-
* browser most recently persisted. If the user has since uninstalled
|
|
104
|
-
* the wallet, switched accounts, or disconnected in another tab, the
|
|
105
|
-
* client-side hydration will reconcile reality and the live store
|
|
106
|
-
* will diverge from the snapshot. Treat the snapshot as an
|
|
107
|
-
* *optimistic* shell; accurate enough to avoid a paint flicker,
|
|
108
|
-
* authoritative only after `useIsHydrated()` is true.
|
|
109
|
-
*
|
|
110
|
-
* **Inputs.** Accepts the three shapes Next.js / Express / Hono /
|
|
111
|
-
* generic-Node cookie code naturally produces:
|
|
112
|
-
* - A plain object: `{ "butr-pool": "{...}", … }`
|
|
113
|
-
* - An array of `{ name, value }` (Next.js' `cookies().getAll()`)
|
|
114
|
-
* - An iterable of `[name, value]` tuples
|
|
115
|
-
*
|
|
116
|
-
* Malformed entries are dropped with a `logWarn` (same policy as
|
|
117
|
-
* `WalletStorage.getPool`); a cross-tab corruption shouldn't crash
|
|
118
|
-
* the server render.
|
|
119
|
-
*/
|
|
120
|
-
declare const readWalletSnapshot: (source: CookieSource, options?: SnapshotOptions) => WalletSnapshot;
|
|
121
|
-
//#endregion
|
|
122
|
-
//#region src/types/errors.d.ts
|
|
123
|
-
/**
|
|
124
|
-
* Tagged union of normalised connection errors.
|
|
125
|
-
*
|
|
126
|
-
* butr maps thrown values from connectors (which vary across wallet SDKs:
|
|
127
|
-
* MetaMask uses EIP-1193 codes, Phantom throws stringly-typed errors,
|
|
128
|
-
* embedded SDKs throw their own classes) into a small set of UX-meaningful
|
|
129
|
-
* variants. Consumers branch on `kind` instead of regexing message strings.
|
|
130
|
-
*
|
|
131
|
-
* `message` is always present and human-readable. `cause` preserves the
|
|
132
|
-
* original thrown value so callers can inspect raw connector errors when
|
|
133
|
-
* the variant is `Unknown`.
|
|
134
|
-
*/
|
|
135
|
-
type ConnectionError = {
|
|
136
|
-
kind: "UserRejected";
|
|
137
|
-
message: string;
|
|
138
|
-
} | {
|
|
139
|
-
kind: "RequestPending";
|
|
140
|
-
message: string;
|
|
141
|
-
} | {
|
|
142
|
-
kind: "WalletLocked";
|
|
143
|
-
message: string;
|
|
144
|
-
} | {
|
|
145
|
-
actualChain?: string;
|
|
146
|
-
expectedChain?: string;
|
|
147
|
-
kind: "ChainMismatch";
|
|
148
|
-
message: string;
|
|
149
|
-
} | {
|
|
150
|
-
kind: "NotConnected";
|
|
151
|
-
message: string;
|
|
152
|
-
} | {
|
|
153
|
-
kind: "Timeout";
|
|
154
|
-
message: string;
|
|
155
|
-
} | {
|
|
156
|
-
cause?: unknown;
|
|
157
|
-
kind: "Unknown";
|
|
158
|
-
message: string;
|
|
159
|
-
};
|
|
160
|
-
type ConnectionErrorKind = ConnectionError["kind"];
|
|
161
|
-
/**
|
|
162
|
-
* Normalise a thrown value into a `ConnectionError`.
|
|
163
|
-
*
|
|
164
|
-
* Recognises:
|
|
165
|
-
* - butr's own `Error("Connection timeout")` (from the 90s connect timeout)
|
|
166
|
-
* - butr's own `Error("Failed to get account")` (from the connect flow)
|
|
167
|
-
* - EIP-1193 numeric `code` properties (`4001` → UserRejected,
|
|
168
|
-
* `-32002` → RequestPending, `4100`/`4900`/`4901` → NotConnected:
|
|
169
|
-
* unauthorized / disconnected from all-or-one chains)
|
|
170
|
-
* - common message substrings: "user rejected" / "user denied",
|
|
171
|
-
* "locked", "chain", etc.
|
|
172
|
-
* - anything else → `Unknown` with `cause` set to the original value.
|
|
173
|
-
*/
|
|
174
|
-
declare const mapConnectionError: (raw: unknown) => ConnectionError;
|
|
175
|
-
//#endregion
|
|
176
|
-
//#region src/types/wallet.d.ts
|
|
177
|
-
/**
|
|
178
|
-
* Canonical list of supported chain platforms. The single runtime source
|
|
179
|
-
* of truth: `ChainPlatform` is derived from it, and storage validators
|
|
180
|
-
* build their allowlists from it, so the type and the runtime checks can
|
|
181
|
-
* never drift (a missing platform here was why Polkadot connections failed
|
|
182
|
-
* to persist).
|
|
183
|
-
*/
|
|
184
|
-
declare const CHAIN_PLATFORMS: readonly ["evm", "svm", "sui", "bitcoin", "polkadot"];
|
|
185
|
-
type ChainPlatform = (typeof CHAIN_PLATFORMS)[number];
|
|
20
|
+
//#region src/types/account.d.ts
|
|
186
21
|
type Account = {
|
|
187
22
|
chain: ChainBase;
|
|
188
23
|
id: string;
|
|
@@ -206,42 +41,8 @@ type Balance = {
|
|
|
206
41
|
/** Raw integer amount */
|
|
207
42
|
value: bigint;
|
|
208
43
|
};
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
*
|
|
212
|
-
* - `installed`: the wallet is available and `connect()` can be called.
|
|
213
|
-
* - `loadable`: the wallet's SDK can be loaded on demand (e.g. WalletConnect
|
|
214
|
-
* modal that pops a QR code without requiring a browser extension).
|
|
215
|
-
* - `not-installed`: the wallet isn't reachable. Consumers typically render
|
|
216
|
-
* a "download" affordance pointing at `meta.url`.
|
|
217
|
-
*/
|
|
218
|
-
type WalletAvailability = "installed" | "loadable" | "not-installed";
|
|
219
|
-
/**
|
|
220
|
-
* Events a connector can emit while connected. butr's runtime subscribes
|
|
221
|
-
* via `Connector.subscribe?` after a successful `connect()` and dispatches
|
|
222
|
-
* the equivalent reducer event:
|
|
223
|
-
*
|
|
224
|
-
* - `accountChanged` carries both the new active `account` AND the full
|
|
225
|
-
* `accounts` array the wallet currently exposes. The runtime mirrors
|
|
226
|
-
* that list verbatim into the pool entry. This handles two cases
|
|
227
|
-
* uniformly:
|
|
228
|
-
* - Multi-account wallets (MetaMask, Rabby, Brave): the user adds or
|
|
229
|
-
* removes accounts from the dapp's permission set; the array grows
|
|
230
|
-
* or shrinks to match.
|
|
231
|
-
* - Single-account-exposure wallets (Phantom EVM/SVM, MetaMask Snap):
|
|
232
|
-
* only the active account is ever in `accounts`; switching swaps it
|
|
233
|
-
* in place rather than appending.
|
|
234
|
-
* Also covers chain switches; the new chain lives inside `account.chain`.
|
|
235
|
-
* - `disconnected` → `DISCONNECTED` (wallet has gone away externally:
|
|
236
|
-
* user locked it, removed the extension, etc.).
|
|
237
|
-
*/
|
|
238
|
-
type ConnectorEvent = {
|
|
239
|
-
account: Account;
|
|
240
|
-
accounts: Array<Account>;
|
|
241
|
-
type: "accountChanged";
|
|
242
|
-
} | {
|
|
243
|
-
type: "disconnected";
|
|
244
|
-
};
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/types/capabilities.d.ts
|
|
245
46
|
/**
|
|
246
47
|
* Capability flags describing what an adapter can actually do at
|
|
247
48
|
* runtime. Populated by each adapter (the auto-built ones derive
|
|
@@ -296,6 +97,95 @@ type WalletCapabilities = {
|
|
|
296
97
|
* per-call `chain` input) when more than one chain is advertised. */
|
|
297
98
|
switchChain: boolean;
|
|
298
99
|
};
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/types/platform.d.ts
|
|
102
|
+
/**
|
|
103
|
+
* Canonical list of supported chain platforms. The single runtime source
|
|
104
|
+
* of truth: `ChainPlatform` is derived from it, and storage validators
|
|
105
|
+
* build their allowlists from it, so the type and the runtime checks can
|
|
106
|
+
* never drift (a missing platform here was why Polkadot connections failed
|
|
107
|
+
* to persist).
|
|
108
|
+
*/
|
|
109
|
+
declare const CHAIN_PLATFORMS: readonly ["evm", "svm", "sui", "bitcoin", "polkadot"];
|
|
110
|
+
type ChainPlatform = (typeof CHAIN_PLATFORMS)[number];
|
|
111
|
+
//#endregion
|
|
112
|
+
//#region src/types/chains-by-platform.d.ts
|
|
113
|
+
/**
|
|
114
|
+
* Map of every chain platform to the list of chains the consumer wants
|
|
115
|
+
* to expose to its UI (chain switcher, picker, etc).
|
|
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).
|
|
122
|
+
*/
|
|
123
|
+
type ChainsByPlatform = Readonly<Record<ChainPlatform, ReadonlyArray<ChainBase>>>;
|
|
124
|
+
/**
|
|
125
|
+
* Build a fully-populated `ChainsByPlatform` from a partial. Platforms
|
|
126
|
+
* the consumer doesn't specify default to an empty list.
|
|
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
|
+
* });
|
|
149
|
+
*/
|
|
150
|
+
declare const buildChainsByPlatform: (partial: Partial<ChainsByPlatform>) => ChainsByPlatform;
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/types/connector.d.ts
|
|
153
|
+
/**
|
|
154
|
+
* Whether a wallet is currently usable from the user's environment.
|
|
155
|
+
*
|
|
156
|
+
* - `installed`: the wallet is available and `connect()` can be called.
|
|
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`.
|
|
161
|
+
*/
|
|
162
|
+
type WalletAvailability = "installed" | "loadable" | "not-installed";
|
|
163
|
+
/**
|
|
164
|
+
* Events a connector can emit while connected. butr's runtime subscribes
|
|
165
|
+
* via `Connector.subscribe?` after a successful `connect()` and dispatches
|
|
166
|
+
* the equivalent reducer event:
|
|
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.).
|
|
181
|
+
*/
|
|
182
|
+
type ConnectorEvent = {
|
|
183
|
+
account: Account;
|
|
184
|
+
accounts: Array<Account>;
|
|
185
|
+
type: "accountChanged";
|
|
186
|
+
} | {
|
|
187
|
+
type: "disconnected";
|
|
188
|
+
};
|
|
299
189
|
/**
|
|
300
190
|
* Orchestration interface: what `butr` actually calls during the
|
|
301
191
|
* connect / disconnect / hydrate flow. This is the contract `butr`
|
|
@@ -358,6 +248,22 @@ type Connector<P extends ChainPlatform = ChainPlatform> = {
|
|
|
358
248
|
* themselves. */
|
|
359
249
|
subscribe?: (listener: (event: ConnectorEvent) => void) => () => void;
|
|
360
250
|
};
|
|
251
|
+
type ConnectorMeta = {
|
|
252
|
+
/** Optional. Sync probe that reports whether the wallet is currently
|
|
253
|
+
* available. Defaults to `"installed"` when omitted. Consumers call
|
|
254
|
+
* this at render time to gate the "Connect" button. */
|
|
255
|
+
availability?: () => WalletAvailability;
|
|
256
|
+
chainPlatform: ChainPlatform;
|
|
257
|
+
/** Optional image URL or data URI for wallet selection UIs. */
|
|
258
|
+
icon?: string;
|
|
259
|
+
id: string;
|
|
260
|
+
name: string;
|
|
261
|
+
/** Optional. Where to send users who don't have this wallet (download
|
|
262
|
+
* page, app store link, etc.). */
|
|
263
|
+
url?: string;
|
|
264
|
+
};
|
|
265
|
+
//#endregion
|
|
266
|
+
//#region src/types/wallet.d.ts
|
|
361
267
|
/**
|
|
362
268
|
* Methods every connected wallet supports regardless of chain. The
|
|
363
269
|
* per-platform `Wallet` types extend this with their platform-specific
|
|
@@ -458,67 +364,247 @@ type BitcoinWallet = WalletBase & {
|
|
|
458
364
|
signTransaction?: (tx: unknown, account?: Account) => Promise<Uint8Array>;
|
|
459
365
|
};
|
|
460
366
|
/**
|
|
461
|
-
* Polkadot/Substrate wallet surface. No standalone `signTransaction`:
|
|
462
|
-
* building an extrinsic needs chain metadata (an RPC round-trip butr
|
|
463
|
-
* doesn't ship), so transaction signing happens through the
|
|
464
|
-
* `getSigner()` handoff; the consumer builds and submits with the
|
|
465
|
-
* wallet's signer (e.g. polkadot-api). Message signing works via the
|
|
466
|
-
* injected `signer.signRaw`. Same shape as `EvmWallet`.
|
|
467
|
-
*/
|
|
468
|
-
type PolkadotWallet = WalletBase;
|
|
469
|
-
/** Per-platform full adapter shapes: `Connector` + the platform's
|
|
470
|
-
* `Wallet` surface. These are the discriminated-union variants of
|
|
471
|
-
* `WalletAdapter`. */
|
|
472
|
-
type EvmAdapter = Connector<"evm"> & EvmWallet;
|
|
473
|
-
type SvmAdapter = Connector<"svm"> & SvmWallet;
|
|
474
|
-
type SuiAdapter = Connector<"sui"> & SuiWallet;
|
|
475
|
-
type BitcoinAdapter = Connector<"bitcoin"> & BitcoinWallet;
|
|
476
|
-
type PolkadotAdapter = Connector<"polkadot"> & PolkadotWallet;
|
|
477
|
-
/**
|
|
478
|
-
* Full adapter interface; discriminated union by `chainPlatform`.
|
|
479
|
-
*
|
|
480
|
-
* Narrow on `wallet.connector.chainPlatform === "svm"` (etc.) to gain
|
|
481
|
-
* access to platform-specific methods like `signIn` (SVM) or
|
|
482
|
-
* `signTransaction` (SVM / Sui / Bitcoin). Calling those methods on a
|
|
483
|
-
* non-narrowed `WalletAdapter` is a TypeScript error; that's the
|
|
484
|
-
* point. The discriminant carries the type-level fact "this method
|
|
485
|
-
* doesn't exist on EVM" so consumers can't accidentally branch on
|
|
486
|
-
* `capabilities.signIn` and call a method that EVM adapters don't
|
|
487
|
-
* implement.
|
|
367
|
+
* Polkadot/Substrate wallet surface. No standalone `signTransaction`:
|
|
368
|
+
* building an extrinsic needs chain metadata (an RPC round-trip butr
|
|
369
|
+
* doesn't ship), so transaction signing happens through the
|
|
370
|
+
* `getSigner()` handoff; the consumer builds and submits with the
|
|
371
|
+
* wallet's signer (e.g. polkadot-api). Message signing works via the
|
|
372
|
+
* injected `signer.signRaw`. Same shape as `EvmWallet`.
|
|
373
|
+
*/
|
|
374
|
+
type PolkadotWallet = WalletBase;
|
|
375
|
+
/** Per-platform full adapter shapes: `Connector` + the platform's
|
|
376
|
+
* `Wallet` surface. These are the discriminated-union variants of
|
|
377
|
+
* `WalletAdapter`. */
|
|
378
|
+
type EvmAdapter = Connector<"evm"> & EvmWallet;
|
|
379
|
+
type SvmAdapter = Connector<"svm"> & SvmWallet;
|
|
380
|
+
type SuiAdapter = Connector<"sui"> & SuiWallet;
|
|
381
|
+
type BitcoinAdapter = Connector<"bitcoin"> & BitcoinWallet;
|
|
382
|
+
type PolkadotAdapter = Connector<"polkadot"> & PolkadotWallet;
|
|
383
|
+
/**
|
|
384
|
+
* Full adapter interface; discriminated union by `chainPlatform`.
|
|
385
|
+
*
|
|
386
|
+
* Narrow on `wallet.connector.chainPlatform === "svm"` (etc.) to gain
|
|
387
|
+
* access to platform-specific methods like `signIn` (SVM) or
|
|
388
|
+
* `signTransaction` (SVM / Sui / Bitcoin). Calling those methods on a
|
|
389
|
+
* non-narrowed `WalletAdapter` is a TypeScript error; that's the
|
|
390
|
+
* point. The discriminant carries the type-level fact "this method
|
|
391
|
+
* doesn't exist on EVM" so consumers can't accidentally branch on
|
|
392
|
+
* `capabilities.signIn` and call a method that EVM adapters don't
|
|
393
|
+
* implement.
|
|
394
|
+
*
|
|
395
|
+
* Runtime gating via `capabilities` still matters for the methods that
|
|
396
|
+
* are OPTIONAL within a platform (a Solana wallet might or might not
|
|
397
|
+
* advertise `solana:signTransaction`). Capabilities narrow "wallet
|
|
398
|
+
* supports this feature"; the discriminated union narrows "this
|
|
399
|
+
* platform has this concept at all".
|
|
400
|
+
*/
|
|
401
|
+
type WalletAdapter = EvmAdapter | SvmAdapter | SuiAdapter | BitcoinAdapter | PolkadotAdapter;
|
|
402
|
+
type ConnectedWallet = {
|
|
403
|
+
/** Currently-active account on this wallet. */
|
|
404
|
+
account: Account;
|
|
405
|
+
/** All accounts known on this wallet at the time of connect/refresh.
|
|
406
|
+
* Always contains at least `account`. Populated from `getAccounts()`
|
|
407
|
+
* if the connector implements it; otherwise `[account]`. */
|
|
408
|
+
accounts: Array<Account>;
|
|
409
|
+
connector: WalletAdapter;
|
|
410
|
+
};
|
|
411
|
+
//#endregion
|
|
412
|
+
//#region src/types/discoverer.d.ts
|
|
413
|
+
/**
|
|
414
|
+
* Self-describing discovery descriptor for a single chain platform.
|
|
415
|
+
*
|
|
416
|
+
* Each platform package (`@usebutr/evm`, `@usebutr/svm`, `@usebutr/sui`,
|
|
417
|
+
* `@usebutr/bitcoin`) exports one of these. The aggregator package
|
|
418
|
+
* (`@usebutr/wallets`) composes them into `autoDiscovery()` without
|
|
419
|
+
* needing to know per-platform defaults; the descriptor owns them.
|
|
420
|
+
*
|
|
421
|
+
* Adding a new chain platform means writing a `PlatformDiscoverer`
|
|
422
|
+
* inside the new package and adding one import to the aggregator's
|
|
423
|
+
* registry, which is keyed by `ChainPlatform`. The aggregator's logic
|
|
424
|
+
* doesn't need to grow.
|
|
425
|
+
*
|
|
426
|
+
* Two parts:
|
|
427
|
+
* - `subscribe`: the primary discovery channel (EIP-6963 / Wallet
|
|
428
|
+
* Standard / etc).
|
|
429
|
+
* - `fallback`: optional. The legacy-injected channel that should
|
|
430
|
+
* only emit if the primary channel hasn't produced an adapter for
|
|
431
|
+
* the same browser session by the settle deadline. `@usebutr/evm`
|
|
432
|
+
* has one (window.ethereum); `@usebutr/bitcoin` has one
|
|
433
|
+
* (window.unisat / sats-connect / window.btc); SVM and Sui don't.
|
|
434
|
+
*/
|
|
435
|
+
type PlatformDiscoverer = {
|
|
436
|
+
/**
|
|
437
|
+
* Optional legacy-injected fallback. Subscribes only when consumers
|
|
438
|
+
* haven't disabled it. The hook receives `hasAnyPrimaryAdapter` so
|
|
439
|
+
* the fallback can defer to standards-based discovery when an adapter
|
|
440
|
+
* for the same wallet has already announced through the primary path.
|
|
441
|
+
*/
|
|
442
|
+
fallback?: {
|
|
443
|
+
subscribe: (onAdapter: (adapter: WalletAdapter) => void, opts: {
|
|
444
|
+
hasAnyPrimaryAdapter: () => boolean;
|
|
445
|
+
}) => () => void;
|
|
446
|
+
};
|
|
447
|
+
/** Primary discovery subscription. */
|
|
448
|
+
subscribe: (onAdapter: (adapter: WalletAdapter) => void) => () => void;
|
|
449
|
+
};
|
|
450
|
+
//#endregion
|
|
451
|
+
//#region src/types/errors.d.ts
|
|
452
|
+
/**
|
|
453
|
+
* Tagged union of normalised connection errors.
|
|
454
|
+
*
|
|
455
|
+
* butr maps thrown values from connectors (which vary across wallet SDKs:
|
|
456
|
+
* MetaMask uses EIP-1193 codes, Phantom throws stringly-typed errors,
|
|
457
|
+
* embedded SDKs throw their own classes) into a small set of UX-meaningful
|
|
458
|
+
* variants. Consumers branch on `kind` instead of regexing message strings.
|
|
459
|
+
*
|
|
460
|
+
* `message` is always present and human-readable. `cause` preserves the
|
|
461
|
+
* original thrown value so callers can inspect raw connector errors when
|
|
462
|
+
* the variant is `Unknown`.
|
|
463
|
+
*/
|
|
464
|
+
type ConnectionError = {
|
|
465
|
+
kind: "UserRejected";
|
|
466
|
+
message: string;
|
|
467
|
+
} | {
|
|
468
|
+
kind: "RequestPending";
|
|
469
|
+
message: string;
|
|
470
|
+
} | {
|
|
471
|
+
kind: "WalletLocked";
|
|
472
|
+
message: string;
|
|
473
|
+
} | {
|
|
474
|
+
actualChain?: string;
|
|
475
|
+
expectedChain?: string;
|
|
476
|
+
kind: "ChainMismatch";
|
|
477
|
+
message: string;
|
|
478
|
+
} | {
|
|
479
|
+
kind: "NotConnected";
|
|
480
|
+
message: string;
|
|
481
|
+
} | {
|
|
482
|
+
kind: "Timeout";
|
|
483
|
+
message: string;
|
|
484
|
+
} | {
|
|
485
|
+
cause?: unknown;
|
|
486
|
+
kind: "Unknown";
|
|
487
|
+
message: string;
|
|
488
|
+
};
|
|
489
|
+
type ConnectionErrorKind = ConnectionError["kind"];
|
|
490
|
+
/**
|
|
491
|
+
* Normalise a thrown value into a `ConnectionError`.
|
|
488
492
|
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
*
|
|
493
|
-
*
|
|
493
|
+
* Recognises:
|
|
494
|
+
* - butr's own `Error("Connection timeout")` (from the 90s connect timeout)
|
|
495
|
+
* - butr's own `Error("Failed to get account")` (from the connect flow)
|
|
496
|
+
* - EIP-1193 numeric `code` properties (`4001` → UserRejected,
|
|
497
|
+
* `-32002` → RequestPending, `4100`/`4900`/`4901` → NotConnected:
|
|
498
|
+
* unauthorized / disconnected from all-or-one chains)
|
|
499
|
+
* - common message substrings: "user rejected" / "user denied",
|
|
500
|
+
* "locked", "chain", etc.
|
|
501
|
+
* - anything else → `Unknown` with `cause` set to the original value.
|
|
494
502
|
*/
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
type
|
|
499
|
-
|
|
500
|
-
|
|
503
|
+
declare const mapConnectionError: (raw: unknown) => ConnectionError;
|
|
504
|
+
//#endregion
|
|
505
|
+
//#region src/storage/persistence.d.ts
|
|
506
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
507
|
+
/** Low-level key/value driver. Sync on web (localStorage, MMKV),
|
|
508
|
+
* async on React Native (AsyncStorage). */
|
|
509
|
+
type StorageDriver = {
|
|
510
|
+
getItem: (key: string) => MaybePromise<string | null>;
|
|
511
|
+
removeItem: (key: string) => MaybePromise<void>;
|
|
512
|
+
setItem: (key: string, value: string) => MaybePromise<void>;
|
|
513
|
+
};
|
|
514
|
+
type StoredPoolEntry = {
|
|
501
515
|
account: Account;
|
|
502
|
-
/** All accounts
|
|
503
|
-
*
|
|
504
|
-
* if the connector implements it; otherwise `[account]`. */
|
|
516
|
+
/** All known accounts on the wallet at last persist. Always contains
|
|
517
|
+
* `account`. */
|
|
505
518
|
accounts: Array<Account>;
|
|
506
|
-
connector: WalletAdapter;
|
|
507
|
-
};
|
|
508
|
-
type ConnectorMeta = {
|
|
509
|
-
/** Optional. Sync probe that reports whether the wallet is currently
|
|
510
|
-
* available. Defaults to `"installed"` when omitted. Consumers call
|
|
511
|
-
* this at render time to gate the "Connect" button. */
|
|
512
|
-
availability?: () => WalletAvailability;
|
|
513
519
|
chainPlatform: ChainPlatform;
|
|
514
|
-
|
|
520
|
+
connectorId: string;
|
|
521
|
+
/** Wallet icon URL or data-URI captured at persist time. Lets the
|
|
522
|
+
* shadow adapter render the same icon the live adapter will when
|
|
523
|
+
* the store is seeded from a snapshot. Omitted when the adapter
|
|
524
|
+
* itself has no icon. */
|
|
515
525
|
icon?: string;
|
|
516
|
-
|
|
526
|
+
/** Human-facing wallet name (e.g. "MetaMask") captured at persist
|
|
527
|
+
* time. Required so the shadow adapter renders the same identity
|
|
528
|
+
* the live adapter will; no "metamask" → "MetaMask" swap at the
|
|
529
|
+
* hydration boundary. */
|
|
517
530
|
name: string;
|
|
518
|
-
/** Optional. Where to send users who don't have this wallet (download
|
|
519
|
-
* page, app store link, etc.). */
|
|
520
|
-
url?: string;
|
|
521
531
|
};
|
|
532
|
+
type StoredPoolRecord = Partial<Record<string, StoredPoolEntry>>;
|
|
533
|
+
type StoredSelectionRecord = Partial<Record<ChainPlatform, string>>;
|
|
534
|
+
type WalletPersistence = {
|
|
535
|
+
clearAll: () => Promise<void>;
|
|
536
|
+
clearPool: () => Promise<void>;
|
|
537
|
+
getActiveConnectorId: () => Promise<string | null>;
|
|
538
|
+
getPool: () => Promise<StoredPoolRecord>;
|
|
539
|
+
getSelection: () => Promise<StoredSelectionRecord>;
|
|
540
|
+
isUserDisconnected: () => Promise<boolean>;
|
|
541
|
+
markUserDisconnected: (value: boolean) => Promise<void>;
|
|
542
|
+
removePoolEntry: (connectorId: string) => Promise<void>;
|
|
543
|
+
setActiveConnectorId: (connectorId: string | null) => Promise<void>;
|
|
544
|
+
setPool: (pool: Map<string, ConnectedWallet>) => Promise<void>;
|
|
545
|
+
setSelection: (selection: Map<ChainPlatform, string>) => Promise<void>;
|
|
546
|
+
};
|
|
547
|
+
//#endregion
|
|
548
|
+
//#region src/storage/snapshot.d.ts
|
|
549
|
+
/**
|
|
550
|
+
* Server-safe view of a butr-persisted session; everything you can
|
|
551
|
+
* know about a user's connected wallets from the cookie payload alone,
|
|
552
|
+
* without instantiating a `Connector`.
|
|
553
|
+
*
|
|
554
|
+
* Notably absent: the `Connector` instance. A wallet extension exists
|
|
555
|
+
* only in the browser, so a server render can know *which* wallet was
|
|
556
|
+
* connected and *what address* it held, but cannot dispatch
|
|
557
|
+
* `signMessage`/`sendTransaction` on it. Splitting display from action
|
|
558
|
+
* along this seam keeps the impossibility expressed in the types
|
|
559
|
+
* rather than hidden inside a runtime check.
|
|
560
|
+
*/
|
|
561
|
+
type WalletSnapshot = {
|
|
562
|
+
activeConnectorId: string | null;
|
|
563
|
+
pool: StoredPoolRecord;
|
|
564
|
+
selection: StoredSelectionRecord;
|
|
565
|
+
};
|
|
566
|
+
type CookieSource = Iterable<{
|
|
567
|
+
name: string;
|
|
568
|
+
value: string;
|
|
569
|
+
}> | Iterable<[string, string]> | Readonly<Record<string, string>>;
|
|
570
|
+
type SnapshotOptions = {
|
|
571
|
+
/**
|
|
572
|
+
* Same prefix passed to `WalletManagerProvider` / `WalletStorage`.
|
|
573
|
+
* Defaults to `"butr"` to match the library default.
|
|
574
|
+
*/
|
|
575
|
+
keyPrefix?: string;
|
|
576
|
+
};
|
|
577
|
+
declare const EMPTY_SNAPSHOT: WalletSnapshot;
|
|
578
|
+
/**
|
|
579
|
+
* Parse a cookie source into a server-safe `WalletSnapshot`.
|
|
580
|
+
*
|
|
581
|
+
* Pure, sync, no `document`, no React; runnable in any environment
|
|
582
|
+
* (Server Component, route handler, edge middleware, even client
|
|
583
|
+
* code). Pair with `createCookieStorageDriver({ initialCookies })`
|
|
584
|
+
* and `<WalletManagerProvider initialSnapshot={…} />` to render a
|
|
585
|
+
* connected shell server-side without a hydration flash.
|
|
586
|
+
*
|
|
587
|
+
* **Stale-snapshot semantics.** The snapshot reflects whatever the
|
|
588
|
+
* browser most recently persisted. If the user has since uninstalled
|
|
589
|
+
* the wallet, switched accounts, or disconnected in another tab, the
|
|
590
|
+
* client-side hydration will reconcile reality and the live store
|
|
591
|
+
* will diverge from the snapshot. Treat the snapshot as an
|
|
592
|
+
* *optimistic* shell; accurate enough to avoid a paint flicker,
|
|
593
|
+
* authoritative only after `useIsHydrated()` is true.
|
|
594
|
+
*
|
|
595
|
+
* **Inputs.** Accepts the three shapes Next.js / Express / Hono /
|
|
596
|
+
* generic-Node cookie code naturally produces:
|
|
597
|
+
* - A plain object: `{ "butr-pool": "{...}", … }`
|
|
598
|
+
* - An array of `{ name, value }` (Next.js' `cookies().getAll()`)
|
|
599
|
+
* - An iterable of `[name, value]` tuples
|
|
600
|
+
*
|
|
601
|
+
* Malformed entries are dropped with a `logWarn` (same policy as
|
|
602
|
+
* `WalletStorage.getPool`); a cross-tab corruption shouldn't crash
|
|
603
|
+
* the server render.
|
|
604
|
+
*/
|
|
605
|
+
declare const readWalletSnapshot: (source: CookieSource, options?: SnapshotOptions) => WalletSnapshot;
|
|
606
|
+
//#endregion
|
|
607
|
+
//#region src/types/manager.d.ts
|
|
522
608
|
/**
|
|
523
609
|
* Outcome of butr's mount-time hydration pass. Passed to
|
|
524
610
|
* `WalletManagerConfig.onHydrated`. Three buckets:
|
|
@@ -616,86 +702,6 @@ type WalletManagerConfig = {
|
|
|
616
702
|
storageKeyPrefix?: string;
|
|
617
703
|
};
|
|
618
704
|
//#endregion
|
|
619
|
-
//#region src/types/chains-by-platform.d.ts
|
|
620
|
-
/**
|
|
621
|
-
* Map of every chain platform to the list of chains the consumer wants
|
|
622
|
-
* to expose to its UI (chain switcher, picker, etc).
|
|
623
|
-
*
|
|
624
|
-
* The platform key set is fixed by `ChainPlatform`. The value is the
|
|
625
|
-
* chain list; empty when the consumer doesn't want to support that
|
|
626
|
-
* platform's chains in this view. This is the only type that callers
|
|
627
|
-
* write down; the values come from per-platform packages
|
|
628
|
-
* (`EVM_CHAINS_LIST`, `SVM_CHAINS_LIST`, etc).
|
|
629
|
-
*/
|
|
630
|
-
type ChainsByPlatform = Readonly<Record<ChainPlatform, ReadonlyArray<ChainBase>>>;
|
|
631
|
-
/**
|
|
632
|
-
* Build a fully-populated `ChainsByPlatform` from a partial. Platforms
|
|
633
|
-
* the consumer doesn't specify default to an empty list.
|
|
634
|
-
*
|
|
635
|
-
* Use this in apps that target one or two chain platforms; importing
|
|
636
|
-
* only those packages keeps unused chain registries out of the bundle.
|
|
637
|
-
* Apps that want every chain reach for `CHAINS_BY_PLATFORM` from
|
|
638
|
-
* `@usebutr/wallets` instead.
|
|
639
|
-
*
|
|
640
|
-
* @example
|
|
641
|
-
* // EVM-only app: Solana/Sui/Bitcoin tables never enter the bundle
|
|
642
|
-
* import { EVM_CHAINS_LIST } from "@usebutr/evm";
|
|
643
|
-
* import { buildChainsByPlatform } from "@usebutr/core";
|
|
644
|
-
*
|
|
645
|
-
* const chains = buildChainsByPlatform({ evm: EVM_CHAINS_LIST });
|
|
646
|
-
*
|
|
647
|
-
* @example
|
|
648
|
-
* // Multi-chain app: pull from each package the app actually uses
|
|
649
|
-
* import { EVM_CHAINS_LIST } from "@usebutr/evm";
|
|
650
|
-
* import { SVM_CHAINS_LIST } from "@usebutr/svm";
|
|
651
|
-
*
|
|
652
|
-
* const chains = buildChainsByPlatform({
|
|
653
|
-
* evm: EVM_CHAINS_LIST,
|
|
654
|
-
* svm: SVM_CHAINS_LIST,
|
|
655
|
-
* });
|
|
656
|
-
*/
|
|
657
|
-
declare const buildChainsByPlatform: (partial: Partial<ChainsByPlatform>) => ChainsByPlatform;
|
|
658
|
-
//#endregion
|
|
659
|
-
//#region src/types/discoverer.d.ts
|
|
660
|
-
/**
|
|
661
|
-
* Self-describing discovery descriptor for a single chain platform.
|
|
662
|
-
*
|
|
663
|
-
* Each platform package (`@usebutr/evm`, `@usebutr/svm`, `@usebutr/sui`,
|
|
664
|
-
* `@usebutr/bitcoin`) exports one of these. The aggregator package
|
|
665
|
-
* (`@usebutr/wallets`) composes them into `autoDiscovery()` without
|
|
666
|
-
* needing to know per-platform defaults; the descriptor owns them.
|
|
667
|
-
*
|
|
668
|
-
* Adding a new chain platform means writing a `PlatformDiscoverer`
|
|
669
|
-
* inside the new package and adding one import to the aggregator's
|
|
670
|
-
* registry. The aggregator's logic doesn't need to grow.
|
|
671
|
-
*
|
|
672
|
-
* Two parts:
|
|
673
|
-
* - `subscribe`: the primary discovery channel (EIP-6963 / Wallet
|
|
674
|
-
* Standard / etc).
|
|
675
|
-
* - `fallback`: optional. The legacy-injected channel that should
|
|
676
|
-
* only emit if the primary channel hasn't produced an adapter for
|
|
677
|
-
* the same browser session by the settle deadline. `@usebutr/evm`
|
|
678
|
-
* has one (window.ethereum); `@usebutr/bitcoin` has one
|
|
679
|
-
* (window.unisat / sats-connect / window.btc); SVM and Sui don't.
|
|
680
|
-
*/
|
|
681
|
-
type PlatformDiscoverer = {
|
|
682
|
-
/**
|
|
683
|
-
* Optional legacy-injected fallback. Subscribes only when consumers
|
|
684
|
-
* haven't disabled it. The hook receives `hasAnyPrimaryAdapter` so
|
|
685
|
-
* the fallback can defer to standards-based discovery when an adapter
|
|
686
|
-
* for the same wallet has already announced through the primary path.
|
|
687
|
-
*/
|
|
688
|
-
fallback?: {
|
|
689
|
-
subscribe: (onAdapter: (adapter: WalletAdapter) => void, opts: {
|
|
690
|
-
hasAnyPrimaryAdapter: () => boolean;
|
|
691
|
-
}) => () => void;
|
|
692
|
-
};
|
|
693
|
-
/** Stable platform identifier. Used by the aggregator for keying. */
|
|
694
|
-
platform: ChainPlatform;
|
|
695
|
-
/** Primary discovery subscription. */
|
|
696
|
-
subscribe: (onAdapter: (adapter: WalletAdapter) => void) => () => void;
|
|
697
|
-
};
|
|
698
|
-
//#endregion
|
|
699
705
|
//#region src/types/signer.d.ts
|
|
700
706
|
/**
|
|
701
707
|
* Per-platform signer type registry.
|
|
@@ -805,6 +811,45 @@ type State = {
|
|
|
805
811
|
selection: Map<ChainPlatform, string>;
|
|
806
812
|
};
|
|
807
813
|
//#endregion
|
|
814
|
+
//#region src/store/shadow-adapter.d.ts
|
|
815
|
+
/**
|
|
816
|
+
* Error thrown when a method is called on a shadow adapter; the
|
|
817
|
+
* placeholder `WalletAdapter` that the store seeds into the pool when
|
|
818
|
+
* an `initialState` is provided (e.g. from a server-rendered cookie
|
|
819
|
+
* snapshot). Shadow adapters carry the identity and account data of a
|
|
820
|
+
* previously-connected wallet, but the live wallet extension hasn't
|
|
821
|
+
* been verified yet; the silent reconnect happens asynchronously
|
|
822
|
+
* after mount.
|
|
823
|
+
*
|
|
824
|
+
* UI code that gates affordances on `wallet.connector.capabilities.*`
|
|
825
|
+
* never reaches a shadow method (capabilities are all `false`). Code
|
|
826
|
+
* that calls through anyway hits this typed error, which is the
|
|
827
|
+
* correct loud failure: the consumer ignored the capability gate.
|
|
828
|
+
*
|
|
829
|
+
* Consumers wanting to wait out the reconnecting window should branch
|
|
830
|
+
* on whether `connectorId` is in `state.reconnectingIds`.
|
|
831
|
+
*/
|
|
832
|
+
declare class ShadowConnectorError extends Error {
|
|
833
|
+
readonly code = "BUTR_RECONNECTING";
|
|
834
|
+
readonly connectorId: string;
|
|
835
|
+
readonly method: string;
|
|
836
|
+
constructor(method: string, connectorId: string);
|
|
837
|
+
}
|
|
838
|
+
/**
|
|
839
|
+
* Type guard. Returns true when an adapter is a placeholder created
|
|
840
|
+
* by `createShadowAdapter`. Useful for the hydration coordinator
|
|
841
|
+
* (which needs to know which pool entries still need upgrading) and
|
|
842
|
+
* for consumers writing wagmi-style "is this connection verified yet"
|
|
843
|
+
* checks without subscribing to `reconnectingIds` directly.
|
|
844
|
+
*
|
|
845
|
+
* Detection is structural: a shadow has all capabilities set to false.
|
|
846
|
+
* Live adapters always advertise at least one capability (every wallet
|
|
847
|
+
* surface includes `getBalance`, `signMessage`, `switchChain` as
|
|
848
|
+
* required methods, and adapter constructors set their flags
|
|
849
|
+
* accordingly).
|
|
850
|
+
*/
|
|
851
|
+
declare const isShadowAdapter: (adapter: WalletAdapter) => boolean;
|
|
852
|
+
//#endregion
|
|
808
853
|
//#region src/storage/browser-storage-driver.d.ts
|
|
809
854
|
type BrowserStorageDrivers = {
|
|
810
855
|
/** Survives app restart (localStorage on web, AsyncStorage/MMKV on RN). */
|
|
@@ -977,10 +1022,16 @@ declare const createWalletStore: (config: WalletManagerConfig) => import("zustan
|
|
|
977
1022
|
//#region src/wallet-equal.d.ts
|
|
978
1023
|
/**
|
|
979
1024
|
* Two wallet snapshots are equivalent for selector purposes iff they
|
|
980
|
-
* share
|
|
981
|
-
* id. Used by `useStoreWithEqualityFn` consumers
|
|
982
|
-
* selected-wallet, useWalletEntry) to suppress spurious
|
|
983
|
-
* when the underlying Map churns but the resolved entry
|
|
1025
|
+
* share the same adapter instance, active account address, and active
|
|
1026
|
+
* account chain id. Used by `useStoreWithEqualityFn` consumers
|
|
1027
|
+
* (active-wallet, selected-wallet, useWalletEntry) to suppress spurious
|
|
1028
|
+
* re-renders when the underlying Map churns but the resolved entry
|
|
1029
|
+
* hasn't changed.
|
|
1030
|
+
*
|
|
1031
|
+
* The adapter is compared by reference, not by `connector.id`: hydration
|
|
1032
|
+
* replaces a shadow adapter with the live one under an unchanged id and
|
|
1033
|
+
* address, so an id comparison reports "equal" and leaves consumers
|
|
1034
|
+
* holding a placeholder whose every method throws ShadowConnectorError.
|
|
984
1035
|
*
|
|
985
1036
|
* Hoisted to its own module so the equivalence rule lives in one place;
|
|
986
1037
|
* if we ever extend the snapshot (e.g. to consider `accounts.length`),
|
|
@@ -1044,6 +1095,15 @@ declare const hexToBytes: (hex: string) => Uint8Array;
|
|
|
1044
1095
|
declare const base64ToBytes: (b64: string) => Uint8Array;
|
|
1045
1096
|
/** Cross-platform `Uint8Array` → base64. */
|
|
1046
1097
|
declare const bytesToBase64: (bytes: Uint8Array) => string;
|
|
1098
|
+
/**
|
|
1099
|
+
* `Uint8Array` → base58 (Solana addresses and signatures). Leading zero
|
|
1100
|
+
* bytes are significant in base58 and survive the BigInt round-trip only
|
|
1101
|
+
* because they're re-prefixed as `1`s afterwards.
|
|
1102
|
+
*/
|
|
1103
|
+
declare const bytesToBase58: (bytes: Uint8Array) => string;
|
|
1104
|
+
/** Decode base58 into raw bytes. Throws on characters outside the alphabet
|
|
1105
|
+
* rather than silently dropping them. */
|
|
1106
|
+
declare const base58ToBytes: (input: string) => Uint8Array;
|
|
1047
1107
|
//#endregion
|
|
1048
|
-
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, type SignerForPlatform, type SignerOf, type SnapshotOptions, type StorageDriver, type StoredPoolEntry, type StoredPoolRecord, type StoredSelectionRecord, type SuiAdapter, type SuiWallet, type SvmAdapter, type SvmWallet, type
|
|
1108
|
+
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 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, createWalletSource, createWalletStore, hexToBytes, isShadowAdapter, logError, logWarn, mapConnectionError, readWalletSnapshot, sanitizeIcon, walletEqual };
|
|
1049
1109
|
//# sourceMappingURL=index.d.ts.map
|