@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/CHANGELOG.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# @usebutr/core
|
|
2
|
+
|
|
3
|
+
## 2.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#179](https://github.com/pedroapfilho/usebutr/pull/179) [`bc5b58c`](https://github.com/pedroapfilho/usebutr/commit/bc5b58cd87601be38dbb77a14e16eaaa36e8f012) Thanks [@pedroapfilho](https://github.com/pedroapfilho)! - Include package READMEs, MIT licenses, and documentation and issue links on npm.
|
|
8
|
+
|
|
9
|
+
## 2.0.0
|
|
10
|
+
|
|
11
|
+
### Major Changes
|
|
12
|
+
|
|
13
|
+
- 9b1caa2: Correctness pass across the storage, hydration and connector layers. Several of
|
|
14
|
+
these change observable behaviour; the ones worth knowing about before upgrading:
|
|
15
|
+
|
|
16
|
+
**Breaking**
|
|
17
|
+
|
|
18
|
+
- `SuiWallet.signTransaction` now returns `{ bytes, signature }` instead of
|
|
19
|
+
`Uint8Array`. Sui's `executeTransactionBlock` needs both, and each connector
|
|
20
|
+
previously returned a different half, so the old value could not be broadcast
|
|
21
|
+
and a consumer could not tell which half they held. SVM and Bitcoin keep their
|
|
22
|
+
single-`Uint8Array` shape.
|
|
23
|
+
- `@usebutr/svm`'s `sendTx` returns the signature base58-encoded, matching the
|
|
24
|
+
WalletConnect namespace, the Ledger app, Solana explorers and
|
|
25
|
+
`getSignatureStatuses`. It previously returned base64.
|
|
26
|
+
- `@usebutr/sui`'s feature input types drop the `string` arm from
|
|
27
|
+
`transaction`; wallets only ever accepted the `toJSON()` form. Strings and BCS
|
|
28
|
+
bytes are now wrapped for you, so `sendTx` accepts strictly more than before.
|
|
29
|
+
|
|
30
|
+
**Behaviour fixes**
|
|
31
|
+
|
|
32
|
+
- `WalletStorage.setPool` and `removePoolEntry` could self-deadlock on a corrupt
|
|
33
|
+
pool payload, leaving `connectWallet` unresolved and every later pool write
|
|
34
|
+
jammed for the page's life. Both are fixed, and `readWalletSnapshot` now shares
|
|
35
|
+
one codec with `WalletStorage` so the server and client decodes cannot drift.
|
|
36
|
+
- A seeded (SSR) entry whose silent reconnect failed used to stay in the pool
|
|
37
|
+
backed by a placeholder connector forever, so `useSigner`/`useBalance`
|
|
38
|
+
reported an error and `useConnectionStatus` reported `"reconnecting"`
|
|
39
|
+
permanently. Those entries are now dropped.
|
|
40
|
+
- `useSigner` and `useBalance` stay `idle` for a wallet that is still
|
|
41
|
+
reconnecting instead of surfacing a placeholder rejection as `status: "error"`.
|
|
42
|
+
- `useConnectionStatus` lets a live `"connecting"`/`"error"` take precedence over
|
|
43
|
+
the derived `"reconnecting"`, so an in-flight attempt and a connection error
|
|
44
|
+
are no longer hidden. New `useIsReconnecting(connectorId?)` answers the
|
|
45
|
+
per-wallet question directly.
|
|
46
|
+
- A background restore no longer writes the connect-attempt status or steals
|
|
47
|
+
`activeConnectorId`, and a superseded `CONNECT_FAILED` no longer overwrites the
|
|
48
|
+
current attempt.
|
|
49
|
+
- An externally-disconnected connector is now torn down, not just dropped from
|
|
50
|
+
the pool, so a cached adapter is not reused while still holding a session.
|
|
51
|
+
- EVM: a malformed provider response is treated as absent rather than `""`, which
|
|
52
|
+
previously produced chain `eip155:0`, zero-length signatures, empty transaction
|
|
53
|
+
hashes and a confident `0 ETH`. `switchChain` gained the same-chain
|
|
54
|
+
short-circuit `sendTxToChain` already had.
|
|
55
|
+
- WalletConnect: accounts carry their own chain instead of all being stamped with
|
|
56
|
+
the active one, so a multi-chain session no longer returns a wrong-chain
|
|
57
|
+
address. One pairing now covers every configured namespace, the pairing URI
|
|
58
|
+
survives a reconnect, and concurrent connects share one pairing.
|
|
59
|
+
- Bitcoin: the sats-connect (Xverse) adapter honours `silent`, so a reload no
|
|
60
|
+
longer triggers an unsolicited approval prompt, and exposes the payment address
|
|
61
|
+
as its single account instead of also presenting the ordinals address as
|
|
62
|
+
spendable.
|
|
63
|
+
- Polkadot: the injected adapter actually delivers events to subscribers,
|
|
64
|
+
`switchChain` notifies like its Wallet Standard sibling, and chain resolution
|
|
65
|
+
prefers the mainnets rather than whatever the wallet listed first.
|
|
66
|
+
- Ledger: the device session is committed atomically, so a locked device no
|
|
67
|
+
longer leaves an open transport that reports itself connected, and concurrent
|
|
68
|
+
connects open one transport.
|
|
69
|
+
- SVM: `sendTxToChain` submits to the chain you asked for instead of the
|
|
70
|
+
adapter's current one, and rejects a chain the wallet does not advertise.
|
|
71
|
+
- `@usebutr/svm`'s `switchChain` capability now counts only `solana:` chains, so
|
|
72
|
+
a multi-namespace wallet no longer advertises a method that always throws.
|
|
73
|
+
|
|
74
|
+
**Testing**
|
|
75
|
+
|
|
76
|
+
- `createFakePersistence` is now the real `WalletStorage` over memory drivers
|
|
77
|
+
rather than a parallel implementation, so it inherits upsert semantics,
|
|
78
|
+
validation and JSON round-tripping. Two divergences are fixed as a result:
|
|
79
|
+
`setPool` upserts rather than replaces, and `clearAll` leaves the
|
|
80
|
+
user-disconnected flag alone.
|
|
81
|
+
- `createFakeConnectedWallet` rejects being given both an `adapter` and explicit
|
|
82
|
+
`addresses`/`accounts`, a combination whose halves could disagree.
|
|
83
|
+
|
|
84
|
+
## 1.1.0
|
|
85
|
+
|
|
86
|
+
### Minor Changes
|
|
87
|
+
|
|
88
|
+
- 8ecaf89: Close five gaps that made multi-chain integration harder than it needed to be.
|
|
89
|
+
|
|
90
|
+
**Group wallets by platform without writing the loop yourself.**
|
|
91
|
+
`groupByPlatform(items, getPlatform)` in `@usebutr/core` buckets any list into
|
|
92
|
+
a `Map<ChainPlatform, T[]>` keyed in `CHAIN_PLATFORMS` order with empty
|
|
93
|
+
platforms omitted, and `@usebutr/react` adds
|
|
94
|
+
`useDiscoveredWalletsByPlatform()` / `useConnectedWalletsByPlatform()` on top.
|
|
95
|
+
A multi-chain wallet announces one adapter per platform, so every app hitting
|
|
96
|
+
more than one chain was writing this bucketing by hand.
|
|
97
|
+
|
|
98
|
+
**`autoDiscovery` takes an allowlist array, and says something when it's empty.**
|
|
99
|
+
`autoDiscovery(["evm", "svm"])` now works alongside the object form and reads
|
|
100
|
+
as the allowlist it is. An options value that enables no platforms logs a
|
|
101
|
+
warning instead of silently discovering nothing: a list built at runtime that
|
|
102
|
+
comes back empty was otherwise indistinguishable from "no wallets installed".
|
|
103
|
+
The bare `autoDiscovery()` everything-path is unchanged and stays silent.
|
|
104
|
+
|
|
105
|
+
**`createFakeConnectedWallet` in `@usebutr/testing`.** Builds the
|
|
106
|
+
`{ account, accounts, connector }` pool entry that UI tests actually render,
|
|
107
|
+
with accounts constructed through `buildAccount` so the `<chain>:<address>` id
|
|
108
|
+
format is never restated in a fixture. Defaults to the platform's mainnet chain
|
|
109
|
+
and a deterministic address; pass `adapter` to wrap a connector you already
|
|
110
|
+
built.
|
|
111
|
+
|
|
112
|
+
**The icon sanitization contract is now on the type.** `Connector.icon` is
|
|
113
|
+
already run through `sanitizeIcon` at discovery, so it is a trimmed non-empty
|
|
114
|
+
string or `undefined`, safe to hand to `next/image` with no second call and no
|
|
115
|
+
`icon !== ""` guard. `ConnectorMeta.icon` documents the opposite: it is
|
|
116
|
+
consumer-supplied and not sanitized.
|
|
117
|
+
|
|
118
|
+
**`createSignInFlow` in `@usebutr/core`.** Wraps the nonce, capability gate,
|
|
119
|
+
signature, base64 encoding, and verification handshake that every wallet-auth
|
|
120
|
+
app writes identically. Solana wallets advertising `solana:signIn` take the
|
|
121
|
+
SIWS path automatically. It deliberately does not define a message format: pass
|
|
122
|
+
`buildMessage` to match your backend. Also re-exports the SVM SIWS types
|
|
123
|
+
(`SolanaSignInFeature`, `SolanaSignInInput`, `SolanaSignInOutput`) from
|
|
124
|
+
`@usebutr/svm`, which were defined but not exported.
|
|
125
|
+
|
|
126
|
+
## 1.0.0
|
|
127
|
+
|
|
128
|
+
### Major Changes
|
|
129
|
+
|
|
130
|
+
- f0a5116: **Breaking:** the `platform` field is gone from the `PlatformDiscoverer` type in `@usebutr/core`, and from the `evmDiscoverer`, `svmDiscoverer`, `suiDiscoverer`, `bitcoinDiscoverer` and `polkadotDiscoverer` objects that implement it. Nothing read it: the aggregator keys discoverers by `ChainPlatform` in its own registry, so the field only restated the key.
|
|
131
|
+
|
|
132
|
+
Migration: read the platform from the `KNOWN_DISCOVERERS` key in `@usebutr/wallets` (`Object.entries(KNOWN_DISCOVERERS)`), or from `adapter.chainPlatform` on a discovered adapter. Custom `PlatformDiscoverer` implementations must drop the `platform` property; keeping it is now an excess-property error.
|
|
133
|
+
|
|
134
|
+
- f0a5116: **Breaking:** the deprecated `Wallet` type alias is removed from `@usebutr/core`.
|
|
135
|
+
|
|
136
|
+
Migration: import `WalletBase` instead (`type Wallet = WalletBase` was all the alias ever was), or the per-platform surface you actually mean: `EvmWallet`, `SvmWallet`, `SuiWallet`, `BitcoinWallet`, `PolkadotWallet`.
|
|
137
|
+
|
|
138
|
+
### Minor Changes
|
|
139
|
+
|
|
140
|
+
- 7887cf0: Add `bytesToBase58` and `base58ToBytes` to the shared encoding module, alongside the existing hex and base64 helpers. Base58 was hand-rolled in eight places across the connector packages and the demo apps; a single tested implementation removes the drift surface on Solana addresses and signatures.
|
|
141
|
+
|
|
142
|
+
### Patch Changes
|
|
143
|
+
|
|
144
|
+
- 7887cf0: Split the 497-line `types/wallet.ts` into focused modules (platform, account, capabilities, connector, wallet, manager) behind the same barrel. Pure file motion: every exported name and type is unchanged.
|
|
145
|
+
|
|
146
|
+
## 0.5.0
|
|
147
|
+
|
|
148
|
+
### Minor Changes
|
|
149
|
+
|
|
150
|
+
- 4467a5e: Compare the adapter instance in `walletEqual` instead of `connector.id`, so selectors re-render when hydration swaps a shadow adapter for the live one. Previously an SSR consumer stayed pinned to the placeholder whose methods throw `ShadowConnectorError`.
|
|
151
|
+
|
|
152
|
+
`isShadowAdapter` and `ShadowConnectorError` are now exported from the package root.
|
|
153
|
+
|
|
154
|
+
## 0.4.2
|
|
155
|
+
|
|
156
|
+
### Patch Changes
|
|
157
|
+
|
|
158
|
+
- c1309ee: Validate persisted wallet data and WalletConnect responses with shared Zod schemas.
|
|
159
|
+
|
|
160
|
+
## 0.4.1
|
|
161
|
+
|
|
162
|
+
### Patch Changes
|
|
163
|
+
|
|
164
|
+
- 937dfae: Bump runtime dependency floors (`@wallet-standard/app` 1.1.1, `@ledgerhq/*` latest minors, `@walletconnect/universal-provider` 2.23.10) and modernize public type declarations from method signatures to property function types (oxlint `method-signature-style`). Type-level only — no runtime behavior change.
|
|
165
|
+
|
|
166
|
+
## 0.4.0
|
|
167
|
+
|
|
168
|
+
### Minor Changes
|
|
169
|
+
|
|
170
|
+
- b5322ae: Add shared byte-encoding utilities (`bytesToHex`, `bytesToHexPrefixed`,
|
|
171
|
+
`hexToBytes`, `base64ToBytes`, `bytesToBase64`) and consolidate the per-connector
|
|
172
|
+
copies onto them. Behavior preserved: prefixed (`0x`) and bare hex are distinct
|
|
173
|
+
variants so each chain keeps its existing output.
|
|
174
|
+
|
|
175
|
+
### Patch Changes
|
|
176
|
+
|
|
177
|
+
- d5f32c7: Fix Polkadot wallet connections failing to persist and reconnect on reload.
|
|
178
|
+
The storage validators' chain-platform allowlist was missing `polkadot`, so
|
|
179
|
+
Polkadot pool entries were rejected on write — and because the write rejects
|
|
180
|
+
the whole batch, a co-connected sibling (e.g. Solana) could be dropped too.
|
|
181
|
+
The allowlist is now derived from a single `CHAIN_PLATFORMS` source of truth
|
|
182
|
+
shared with the `ChainPlatform` type, so the runtime checks can't drift from
|
|
183
|
+
the type again.
|
|
184
|
+
- a46eecd: Ship unminified ESM so downstream bundlers (Vite/esbuild dep pre-bundling) process the package correctly; fixes a ReferenceError in consumer dev servers. The consuming app minifies once at its own build.
|
|
185
|
+
|
|
186
|
+
## 0.3.0
|
|
187
|
+
|
|
188
|
+
### Minor Changes
|
|
189
|
+
|
|
190
|
+
- 886ee1d: Add Polkadot/Substrate support. New `@usebutr/polkadot` package discovers wallets via injectedWeb3 (polkadot-js, Talisman, SubWallet, Nova, Enkrypt) with a Wallet Standard `polkadot:*` fallback. `ChainPlatform` widens to include `"polkadot"`; `autoDiscovery({ polkadot: true })` and `CHAINS_BY_PLATFORM` now cover it. Message signing works via the injected `signer.signRaw`; transaction signing is delegated to the consumer through `getSigner()` (e.g. polkadot-api), matching butr's no-RPC posture.
|
|
191
|
+
|
|
192
|
+
## 0.2.2
|
|
193
|
+
|
|
194
|
+
### Patch Changes
|
|
195
|
+
|
|
196
|
+
- db5d7e9: Fix intermittent wallet disconnect on page reload. Two storage-write bugs caused a remembered connection to be erased:
|
|
197
|
+
|
|
198
|
+
- An external `disconnected` event (EIP-1193 emits `accountsChanged: []`) fired on a simple wallet **auto-lock**, not just on permission revocation — and the store persisted the resulting empty pool, wiping the saved connection on every lock. The store now mirrors the disconnect into reducer state (so the UI hides the wallet) but leaves storage untouched; the next hydrate retries and self-heals once the wallet is unlocked. Explicit `disconnectWallet` still evicts via `removePoolEntry`.
|
|
199
|
+
- A transient `eth_accounts: []` during eager restore (a locked wallet) was treated as a permanent failure and the storage entry was deleted. Hydration now preserves storage on a failed restore and reports it as `dropped` for telemetry only, so a reload retries.
|
|
200
|
+
|
|
201
|
+
Additionally, `WalletStorage.setPool` is now **additive** and serialized through an internal mutation queue, so concurrent fire-and-forget writes can't interleave their read-modify-write phases and clobber each other's entries. `connectWallet` / `disconnectWallet` now await their storage writes so callers can trust persistence has landed on the next line.
|
|
202
|
+
|
|
203
|
+
## 0.2.1
|
|
204
|
+
|
|
205
|
+
### Patch Changes
|
|
206
|
+
|
|
207
|
+
- f846e77: Wallet-announced icons are trimmed of surrounding whitespace on ingestion. Some wallets ship data-URI icons with a leading newline, which strict consumers reject — Next.js's `<Image>` throws because `src` must not start with a control character. `@usebutr/core` exports a `sanitizeIcon` helper; the EIP-6963 and Wallet Standard adapters apply it, and an all-whitespace icon now resolves to `undefined` rather than a blank string.
|
|
208
|
+
|
|
209
|
+
## 0.2.0
|
|
210
|
+
|
|
211
|
+
### Minor Changes
|
|
212
|
+
|
|
213
|
+
- b77a477: Persisted pool entries now require the `accounts` field. Entries written by older versions without it are dropped on read with a warning.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pedro Filho
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# @usebutr/core
|
|
2
|
+
|
|
3
|
+
Core types, store, storage, and discovery seam for butr. No React, no protocols.
|
|
4
|
+
|
|
5
|
+
Part of [butr](https://www.usebutr.com), a multi-chain wallet discovery and
|
|
6
|
+
connection-state library. Your application owns the picker UI and chain client.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @usebutr/core zustand
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The store works outside React. Add a discovery source or your own connector factory when wiring real wallets.
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { createWalletStore } from "@usebutr/core";
|
|
20
|
+
|
|
21
|
+
export const store = createWalletStore({
|
|
22
|
+
connectors: [],
|
|
23
|
+
createConnector: () => null,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Read state from a non-React host.
|
|
27
|
+
const wallets = store.getState().pool;
|
|
28
|
+
console.log(wallets.size);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Documentation
|
|
32
|
+
|
|
33
|
+
- [Package reference](https://docs.usebutr.com/api/core)
|
|
34
|
+
- [Getting started](https://docs.usebutr.com/getting-started/quickstart)
|
|
35
|
+
- [Examples and source](https://github.com/pedroapfilho/usebutr)
|
|
36
|
+
- [Report an issue](https://github.com/pedroapfilho/usebutr/issues)
|
|
37
|
+
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
[MIT](./LICENSE), copyright 2026 Pedro Filho.
|