@usebutr/bitcoin 1.1.0 → 2.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/CHANGELOG.md ADDED
@@ -0,0 +1,255 @@
1
+ # @usebutr/bitcoin
2
+
3
+ ## 2.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [#203](https://github.com/pedroapfilho/usebutr/pull/203) [`1263f86`](https://github.com/pedroapfilho/usebutr/commit/1263f8666afd43b4f7dbf8df1763709c3edf09d9) Thanks [@pedroapfilho](https://github.com/pedroapfilho)! - Adapters now say what they can do by having the method: `capabilities` is gone, and an optional method (`sendTx`, `signMessage`, `getBalance`, `switchChain`, …) exists only when it works for that wallet. No adapter returns a placeholder balance or a receipt that stays pending anymore.
8
+
9
+ - `sendTx(tx, { account, chain })` replaces `sendTx` and `sendTxToChain`, and `signMessage`, `signTransaction` and `getBalance` take options objects. `chain` is a `ChainBase`. An adapter either routes the call to that chain, switches the wallet to it, or rejects; none ignores it.
10
+ - An `account` the wallet does not expose now rejects instead of signing with the first account. `chain.name` is the chain's name, never the wallet's.
11
+ - `getAccounts()` resolves the active account first. `getAccount` and `switchAccount` are removed.
12
+ - `getSigner()` resolves a tagged `WalletSigner` (`eip1193`, `wallet-standard`, `walletconnect`, `ledger-*`, …), so it can be narrowed with `switch (signer.kind)` instead of cast.
13
+ - `createWalletManager(config, { initialState })` owns discovery, hydration and persistence, and works without React. `config.sources` replaces the `discovery`, `connectors` and `createConnector` props. `fromAdapters` registers WalletConnect, Ledger and hand-built adapters, which now also appear in `useDiscoveredWallets()`.
14
+ - `WalletManagerProvider` takes `config` and `initialState`. `useSigner(wallet)` and `useBalance(wallet, { token, account })` take the wallet entry itself, and id-taking hooks read the active wallet only when the id is omitted (`null` reads none). The hooks are `useWalletManager`, `useWalletState`, `useConnect`, `useWallet`, `useSelectedWallet` (now typed per platform), `useAccounts`, `useConnectionStatus`, `useIsHydrated`, `useIsReconnecting`, `useDiscoveredWallets`, `useConnectedWallets`, the `…ByPlatform` groupings, `useBalance` and `useSigner`.
15
+ - `manager.connect()` and `useConnect().connectAsync()` resolve the `ConnectedWallet` and reject with a `ConnectionError`, now an `Error` subclass with a `kind` and a new `WalletNotFound` kind. `useConnect().connect()` never rejects: the failure lands in its `error`.
16
+ - `WalletPersistence` is `load()` / `save(state)`, and `createWalletStorage` replaces `new WalletStorage`. Storage keys are unchanged.
17
+ - Chain registries (`EVM_CHAINS`, `SVM_CHAINS`, …, `CHAINS_BY_PLATFORM`) move to `@usebutr/core`, and `BITCOIN_CHAINS` gains `testnet4`. `@usebutr/wallets` loads every platform's signer kinds, so an app that imports only it can narrow `signer.kind`.
18
+ - `@usebutr/react` requires React 19, which its `use()` call already needed.
19
+ - WalletConnect requests on Solana, Sui and Bitcoin now carry their chain, so they no longer fall through to the first namespace in a multi-namespace session. Solana takes `SVM_CHAINS` chains and maps them to the genesis-hash ids WalletConnect sessions use.
20
+ - Ledger's Solana `signTransaction` returns the full signed transaction, Sui signs the intent message, and Bitcoin `signMessage` returns a BIP-137 signature.
21
+ - `@usebutr/testing`'s fake adapter resolves a `signer` you pass instead of registering a test-only signer kind.
22
+ - `setAccount` selects an exposed account without changing any account's chain. Unknown accounts are ignored; chain changes come from the adapter.
23
+ - WalletConnect EVM events use the namespace in `session_event`, including empty account lists that end the connection. Local chain switches still update the manager.
24
+ - Failed persistence saves wait for every key write to finish before reporting failure, so delayed writes cannot overwrite a later disconnect.
25
+ - `@usebutr/svm/transaction` provides the shared legacy/v0 signing codec used by Ledger and WalletConnect, with consistent layout and signature validation.
26
+
27
+ See the migration guide at https://docs.usebutr.com/migration.
28
+
29
+ ### Patch Changes
30
+
31
+ - [#199](https://github.com/pedroapfilho/usebutr/pull/199) [`5d1f234`](https://github.com/pedroapfilho/usebutr/commit/5d1f23403263f7a1f8a48be061727972fe749b5f) Thanks [@pedroapfilho](https://github.com/pedroapfilho)! - Raise the zod dependency floor to 4.6.1.
32
+ - Updated dependencies [[`1263f86`](https://github.com/pedroapfilho/usebutr/commit/1263f8666afd43b4f7dbf8df1763709c3edf09d9), [`5d1f234`](https://github.com/pedroapfilho/usebutr/commit/5d1f23403263f7a1f8a48be061727972fe749b5f)]:
33
+ - @usebutr/core@3.0.0
34
+ - @usebutr/wallet-standard-shared@2.0.0
35
+
36
+ ## 1.1.2
37
+
38
+ ### Patch Changes
39
+
40
+ - Updated dependencies [[`bc5b58c`](https://github.com/pedroapfilho/usebutr/commit/bc5b58cd87601be38dbb77a14e16eaaa36e8f012), [`bc5b58c`](https://github.com/pedroapfilho/usebutr/commit/bc5b58cd87601be38dbb77a14e16eaaa36e8f012)]:
41
+ - @usebutr/wallet-standard-shared@1.0.0
42
+ - @usebutr/core@2.0.1
43
+
44
+ ## 1.1.1
45
+
46
+ ### Patch Changes
47
+
48
+ - Updated dependencies [302ae4a]
49
+ - @usebutr/wallet-standard-shared@0.5.1
50
+
51
+ ## 1.1.0
52
+
53
+ ### Minor Changes
54
+
55
+ - 9b1caa2: Correctness pass across the storage, hydration and connector layers. Several of
56
+ these change observable behaviour; the ones worth knowing about before upgrading:
57
+
58
+ **Breaking**
59
+
60
+ - `SuiWallet.signTransaction` now returns `{ bytes, signature }` instead of
61
+ `Uint8Array`. Sui's `executeTransactionBlock` needs both, and each connector
62
+ previously returned a different half, so the old value could not be broadcast
63
+ and a consumer could not tell which half they held. SVM and Bitcoin keep their
64
+ single-`Uint8Array` shape.
65
+ - `@usebutr/svm`'s `sendTx` returns the signature base58-encoded, matching the
66
+ WalletConnect namespace, the Ledger app, Solana explorers and
67
+ `getSignatureStatuses`. It previously returned base64.
68
+ - `@usebutr/sui`'s feature input types drop the `string` arm from
69
+ `transaction`; wallets only ever accepted the `toJSON()` form. Strings and BCS
70
+ bytes are now wrapped for you, so `sendTx` accepts strictly more than before.
71
+
72
+ **Behaviour fixes**
73
+
74
+ - `WalletStorage.setPool` and `removePoolEntry` could self-deadlock on a corrupt
75
+ pool payload, leaving `connectWallet` unresolved and every later pool write
76
+ jammed for the page's life. Both are fixed, and `readWalletSnapshot` now shares
77
+ one codec with `WalletStorage` so the server and client decodes cannot drift.
78
+ - A seeded (SSR) entry whose silent reconnect failed used to stay in the pool
79
+ backed by a placeholder connector forever, so `useSigner`/`useBalance`
80
+ reported an error and `useConnectionStatus` reported `"reconnecting"`
81
+ permanently. Those entries are now dropped.
82
+ - `useSigner` and `useBalance` stay `idle` for a wallet that is still
83
+ reconnecting instead of surfacing a placeholder rejection as `status: "error"`.
84
+ - `useConnectionStatus` lets a live `"connecting"`/`"error"` take precedence over
85
+ the derived `"reconnecting"`, so an in-flight attempt and a connection error
86
+ are no longer hidden. New `useIsReconnecting(connectorId?)` answers the
87
+ per-wallet question directly.
88
+ - A background restore no longer writes the connect-attempt status or steals
89
+ `activeConnectorId`, and a superseded `CONNECT_FAILED` no longer overwrites the
90
+ current attempt.
91
+ - An externally-disconnected connector is now torn down, not just dropped from
92
+ the pool, so a cached adapter is not reused while still holding a session.
93
+ - EVM: a malformed provider response is treated as absent rather than `""`, which
94
+ previously produced chain `eip155:0`, zero-length signatures, empty transaction
95
+ hashes and a confident `0 ETH`. `switchChain` gained the same-chain
96
+ short-circuit `sendTxToChain` already had.
97
+ - WalletConnect: accounts carry their own chain instead of all being stamped with
98
+ the active one, so a multi-chain session no longer returns a wrong-chain
99
+ address. One pairing now covers every configured namespace, the pairing URI
100
+ survives a reconnect, and concurrent connects share one pairing.
101
+ - Bitcoin: the sats-connect (Xverse) adapter honours `silent`, so a reload no
102
+ longer triggers an unsolicited approval prompt, and exposes the payment address
103
+ as its single account instead of also presenting the ordinals address as
104
+ spendable.
105
+ - Polkadot: the injected adapter actually delivers events to subscribers,
106
+ `switchChain` notifies like its Wallet Standard sibling, and chain resolution
107
+ prefers the mainnets rather than whatever the wallet listed first.
108
+ - Ledger: the device session is committed atomically, so a locked device no
109
+ longer leaves an open transport that reports itself connected, and concurrent
110
+ connects open one transport.
111
+ - SVM: `sendTxToChain` submits to the chain you asked for instead of the
112
+ adapter's current one, and rejects a chain the wallet does not advertise.
113
+ - `@usebutr/svm`'s `switchChain` capability now counts only `solana:` chains, so
114
+ a multi-namespace wallet no longer advertises a method that always throws.
115
+
116
+ **Testing**
117
+
118
+ - `createFakePersistence` is now the real `WalletStorage` over memory drivers
119
+ rather than a parallel implementation, so it inherits upsert semantics,
120
+ validation and JSON round-tripping. Two divergences are fixed as a result:
121
+ `setPool` upserts rather than replaces, and `clearAll` leaves the
122
+ user-disconnected flag alone.
123
+ - `createFakeConnectedWallet` rejects being given both an `adapter` and explicit
124
+ `addresses`/`accounts`, a combination whose halves could disagree.
125
+
126
+ ### Patch Changes
127
+
128
+ - Updated dependencies [9b1caa2]
129
+ - @usebutr/wallet-standard-shared@0.5.0
130
+ - @usebutr/core@2.0.0
131
+
132
+ ## 1.0.1
133
+
134
+ ### Patch Changes
135
+
136
+ - Updated dependencies [8ecaf89]
137
+ - @usebutr/core@1.1.0
138
+ - @usebutr/wallet-standard-shared@0.4.1
139
+
140
+ ## 1.0.0
141
+
142
+ ### Major Changes
143
+
144
+ - 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.
145
+
146
+ 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.
147
+
148
+ - f0a5116: **Breaking:** `slugify` is no longer exported from `@usebutr/svm`, `@usebutr/sui` or `@usebutr/bitcoin`. Each package exported a one-argument wrapper that only bound a platform prefix onto the canonical two-argument helper, so three names shadowed one implementation.
149
+
150
+ Migration: import `slugify` from `@usebutr/wallet-standard-shared` and pass the platform prefix as the first argument. `slugify(name)` from `@usebutr/svm` becomes `slugify("svm", name)`; the `@usebutr/sui` prefix is `"sui"` and the `@usebutr/bitcoin` prefix is `"btc"`. Adapter ids are byte-for-byte the same.
151
+
152
+ ### Patch Changes
153
+
154
+ - 7887cf0: Resolve capabilities through `buildWalletCapabilities` from `@usebutr/wallet-standard-shared` instead of a per-package copy of the same object literal. Resolver names, input types and returned flags are unchanged. The injected Polkadot profile now derives its chain count from `POLKADOT_CHAINS_LIST` rather than asserting `switchChain: true` directly; the result is the same.
155
+ - 7887cf0: Move each package's `discover*Adapters` function next to the adapter builder it wraps and drop the single-function `wallet-standard.ts` module. The functions are still exported from the package root under the same names; only an internal file boundary went away.
156
+ - Updated dependencies [7887cf0]
157
+ - Updated dependencies [7887cf0]
158
+ - Updated dependencies [f0a5116]
159
+ - Updated dependencies [f0a5116]
160
+ - Updated dependencies [7887cf0]
161
+ - @usebutr/core@1.0.0
162
+ - @usebutr/wallet-standard-shared@0.4.0
163
+
164
+ ## 0.2.7
165
+
166
+ ### Patch Changes
167
+
168
+ - efe4550: Share the session plumbing behind the Wallet Standard and WalletConnect CAIP adapters. `@usebutr/wallet-standard-shared` now exports `createWalletStandardCore`, which the Bitcoin, Polkadot, Sui and SVM adapters build on; the WalletConnect Bitcoin, Sui and SVM namespaces share an equivalent CAIP core. Every package's public API is unchanged. The one visible difference is a dev-console warning: a failed SVM disconnect now logs `[butr] SVM Wallet Standard disconnect threw:` instead of `[butr] Wallet Standard disconnect threw:`.
169
+ - Updated dependencies [efe4550]
170
+ - Updated dependencies [4467a5e]
171
+ - @usebutr/wallet-standard-shared@0.3.0
172
+ - @usebutr/core@0.5.0
173
+
174
+ ## 0.2.6
175
+
176
+ ### Patch Changes
177
+
178
+ - 99eaef0: Restore guards that the type-aware lint pass narrowed away.
179
+
180
+ - `@usebutr/bitcoin`: the sats-connect `getAccounts` reader dropped its optional
181
+ chain on the RPC payload. The declared shape is an assertion over an untyped
182
+ bridge, so a wallet answering without a `result` threw a `TypeError` instead
183
+ of reporting no accounts.
184
+ - `@usebutr/walletconnect`: the Sui and Solana signing paths treated an
185
+ empty-string `transaction` / `transactionBytes` / `bytes` field as a real
186
+ value and decoded it to zero bytes. They now fall through to the signature
187
+ path (Sui `signPersonalMessage`) or the original message, matching the
188
+ previous truthiness checks.
189
+ - `@usebutr/ledger`: the unknown-platform rejection lost the platform name from
190
+ its message, which is the only detail that made the error actionable.
191
+
192
+ - Updated dependencies [c1309ee]
193
+ - @usebutr/core@0.4.2
194
+ - @usebutr/wallet-standard-shared@0.2.6
195
+
196
+ ## 0.2.5
197
+
198
+ ### Patch Changes
199
+
200
+ - 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.
201
+ - Updated dependencies [937dfae]
202
+ - @usebutr/core@0.4.1
203
+ - @usebutr/wallet-standard-shared@0.2.5
204
+
205
+ ## 0.2.4
206
+
207
+ ### Patch Changes
208
+
209
+ - 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.
210
+ - Updated dependencies [b5322ae]
211
+ - Updated dependencies [d5f32c7]
212
+ - Updated dependencies [a46eecd]
213
+ - Updated dependencies [3f26776]
214
+ - @usebutr/core@0.4.0
215
+ - @usebutr/wallet-standard-shared@0.2.4
216
+
217
+ ## 0.2.3
218
+
219
+ ### Patch Changes
220
+
221
+ - Updated dependencies [886ee1d]
222
+ - @usebutr/core@0.3.0
223
+ - @usebutr/wallet-standard-shared@0.2.3
224
+
225
+ ## 0.2.2
226
+
227
+ ### Patch Changes
228
+
229
+ - Updated dependencies [db5d7e9]
230
+ - @usebutr/core@0.2.2
231
+ - @usebutr/wallet-standard-shared@0.2.2
232
+
233
+ ## 0.2.1
234
+
235
+ ### Patch Changes
236
+
237
+ - 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.
238
+ - Updated dependencies [f846e77]
239
+ - @usebutr/core@0.2.1
240
+ - @usebutr/wallet-standard-shared@0.2.1
241
+
242
+ ## 0.2.0
243
+
244
+ ### Minor Changes
245
+
246
+ - b77a477: Shared Wallet Standard protocol types (`WalletStandardWallet`, `WalletStandardWalletAccount`, `WalletStandardAppModule`, `WalletsApp`, `StandardConnectFeature`, `StandardDisconnectFeature`, `StandardEventsFeature`, `StandardEventsListener`) are imported from `@usebutr/wallet-standard-shared` directly — they are no longer re-exported from `@usebutr/svm`, `@usebutr/sui`, or `@usebutr/bitcoin`. Platform-specific feature shapes still ship from their own packages.
247
+
248
+ `@usebutr/svm` adapter ids are now platform-prefixed (`wallet-standard:svm-<slug>`), consistent with the `sui-` and `btc-` prefixes. `slugify` in `@usebutr/wallet-standard-shared` requires a non-empty platform prefix.
249
+
250
+ ### Patch Changes
251
+
252
+ - Updated dependencies [b77a477]
253
+ - Updated dependencies [b77a477]
254
+ - @usebutr/core@0.2.0
255
+ - @usebutr/wallet-standard-shared@0.2.0
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,91 @@
1
+ # @usebutr/bitcoin
2
+
3
+ Wallet Standard + injected (sats-connect / Unisat / OKX) wallet discovery and adapters for butr (Bitcoin).
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/react @usebutr/core @usebutr/bitcoin zustand @wallet-standard/app
12
+ ```
13
+
14
+ React 19 is a peer dependency of the provider. Discovery does not render a connect modal; add your picker as the provider child. `@wallet-standard/app` is required for Wallet Standard discovery.
15
+
16
+ ## Usage
17
+
18
+ ```tsx
19
+ import type { ReactNode } from "react";
20
+ import type { WalletManagerConfig } from "@usebutr/core";
21
+ import { discoverBitcoinAdapters } from "@usebutr/bitcoin";
22
+ import { WalletManagerProvider } from "@usebutr/react";
23
+
24
+ const config: WalletManagerConfig = { sources: [discoverBitcoinAdapters] };
25
+
26
+ export const WalletProvider = ({ children }: { children: ReactNode }) => (
27
+ <WalletManagerProvider config={config}>{children}</WalletManagerProvider>
28
+ );
29
+ ```
30
+
31
+ `discoverInjectedBitcoinAdapter` covers wallets that never announce through
32
+ Wallet Standard (`window.unisat`, `window.okxwallet.bitcoin`, Xverse's
33
+ sats-connect provider, `window.btc`). `bitcoinDiscoverer` pairs both channels
34
+ so the injected one stays quiet once Wallet Standard found a Bitcoin wallet;
35
+ `autoDiscovery(["bitcoin"])` from `@usebutr/wallets` wires it for you.
36
+
37
+ ## Transactions
38
+
39
+ A method exists only when the wallet can back it, so check before calling:
40
+
41
+ ```ts
42
+ import { BITCOIN_CHAINS } from "@usebutr/core";
43
+
44
+ if (wallet.connector.sendTx) {
45
+ const txid = await wallet.connector.sendTx(
46
+ { amount: 10_000n, recipient: "tb1q…" }, // satoshis
47
+ { account: wallet.account, chain: BITCOIN_CHAINS.testnet },
48
+ );
49
+ }
50
+ ```
51
+
52
+ - `sendTx(transfer, { account?, chain? })` asks the wallet to build, sign and
53
+ broadcast a transfer and resolves the txid.
54
+ - `signTransaction(psbt, { account?, chain? })` signs PSBT bytes
55
+ (`psbt.toBuffer()`) without broadcasting them.
56
+ - `signMessage(message, { account? })` signs a UTF-8 message.
57
+
58
+ Wallet Standard wallets route `chain` per call and gain `switchChain` when they
59
+ advertise more than one Bitcoin network. Injected wallets have one network for
60
+ the whole wallet: they switch it before acting (Unisat through
61
+ `switchNetwork`, Xverse through `wallet_changeNetwork`), or reject with a
62
+ `ChainMismatch` `ConnectionError` when the provider cannot switch (OKX,
63
+ `window.btc`). Unisat-style wallets sign with their active account only, and
64
+ Xverse sends from its payment address only; any other `account` rejects.
65
+
66
+ Balances and receipts need an Esplora or Electrum client, which butr does not
67
+ ship, so these adapters define neither.
68
+
69
+ ## Signers
70
+
71
+ `getSigner()` resolves the object the adapter drives, tagged by transport:
72
+
73
+ ```ts
74
+ const signer = await wallet.connector.getSigner();
75
+ switch (signer.kind) {
76
+ case "wallet-standard": // signer.wallet
77
+ case "unisat": // signer.provider, the UniSat-style provider
78
+ case "sats-connect": // signer.provider, Xverse's BitcoinProvider
79
+ }
80
+ ```
81
+
82
+ ## Documentation
83
+
84
+ - [Package reference](https://docs.usebutr.com/api/bitcoin)
85
+ - [Getting started](https://docs.usebutr.com/getting-started/quickstart)
86
+ - [Examples and source](https://github.com/pedroapfilho/usebutr)
87
+ - [Report an issue](https://github.com/pedroapfilho/usebutr/issues)
88
+
89
+ ## License
90
+
91
+ [MIT](./LICENSE), copyright 2026 Pedro Filho.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
+ import { BitcoinAdapter, PlatformDiscoverer, WalletAdapter } from "@usebutr/core";
1
2
  import { WalletStandardWallet, WalletStandardWalletAccount } from "@usebutr/wallet-standard-shared";
2
- import { ChainBase, PlatformDiscoverer, WalletAdapter, WalletCapabilities } from "@usebutr/core";
3
3
  //#region src/wallet-standard-types.d.ts
4
4
  type BitcoinSignMessageInput = {
5
5
  account: WalletStandardWalletAccount;
@@ -11,6 +11,7 @@ type BitcoinSignMessageOutput = {
11
11
  };
12
12
  type BitcoinSignMessageFeature = {
13
13
  signMessage: (input: BitcoinSignMessageInput) => Promise<BitcoinSignMessageOutput>;
14
+ version?: string;
14
15
  };
15
16
  type BitcoinSignPsbtInput = {
16
17
  account: WalletStandardWalletAccount;
@@ -29,6 +30,7 @@ type BitcoinSignPsbtOutput = {
29
30
  };
30
31
  type BitcoinSignPsbtFeature = {
31
32
  signPsbt: (input: BitcoinSignPsbtInput) => Promise<BitcoinSignPsbtOutput>;
33
+ version?: string;
32
34
  };
33
35
  type BitcoinSendTransferInput = {
34
36
  account: WalletStandardWalletAccount;
@@ -42,92 +44,61 @@ type BitcoinSendTransferOutput = {
42
44
  };
43
45
  type BitcoinSendTransferFeature = {
44
46
  sendTransfer: (input: BitcoinSendTransferInput) => Promise<BitcoinSendTransferOutput>;
47
+ version?: string;
45
48
  };
46
49
  //#endregion
47
50
  //#region src/wallet-standard-adapter.d.ts
48
51
  /**
49
- * `sendTx` takes `{ amount, recipient }` for `bitcoin:sendTransfer` and
50
- * `signTransaction` takes raw PSBT bytes for `bitcoin:signPsbt`. Balance
51
- * and receipt reads would need an Esplora/Electrum client butr doesn't ship.
52
+ * `bitcoin:sendTransfer` backs `sendTx` and `bitcoin:signPsbt` backs
53
+ * `signTransaction`, both routing `options.chain` per call. Balance and
54
+ * receipt reads would need an Esplora/Electrum client butr doesn't ship.
52
55
  */
53
56
  declare const buildBitcoinAdapter: (wallet: WalletStandardWallet,
54
57
  /** Optional. Called with a function that pushes a synthetic
55
58
  * `disconnected` event to all current subscribers. The discovery
56
59
  * layer invokes it on Wallet Standard `unregister`. */
57
- registerDisconnector?: (emit: () => void) => void) => WalletAdapter | null;
60
+ registerDisconnector?: (emit: () => void) => void) => BitcoinAdapter | null;
58
61
  /** Requires the optional `@wallet-standard/app` peer dep. */
59
62
  declare const discoverBitcoinAdapters: (onAdapter: (adapter: WalletAdapter) => void) => (() => void);
60
63
  //#endregion
61
- //#region src/chains.d.ts
62
- /**
63
- * CAIP-2 Bitcoin references are the first 8 bytes of each network's
64
- * genesis block hash, which is what wallets advertise in `wallet.chains`.
65
- * No major wallet exposes a switch-chain RPC, so chain stays local state.
66
- */
67
- declare const BITCOIN_CHAINS: {
68
- readonly mainnet: {
69
- readonly id: "bip122:000000000019d6689c085ae165831e93";
70
- readonly name: "Bitcoin";
71
- readonly namespace: "bip122";
72
- readonly reference: "000000000019d6689c085ae165831e93";
73
- };
74
- readonly signet: {
75
- readonly id: "bip122:00000008819873e925422c1ff0f99f7c";
76
- readonly name: "Bitcoin Signet";
77
- readonly namespace: "bip122";
78
- readonly reference: "00000008819873e925422c1ff0f99f7c";
79
- };
80
- readonly testnet: {
81
- readonly id: "bip122:000000000933ea01ad0ee984209779ba";
82
- readonly name: "Bitcoin Testnet";
83
- readonly namespace: "bip122";
84
- readonly reference: "000000000933ea01ad0ee984209779ba";
85
- };
86
- };
87
- declare const BITCOIN_CHAINS_LIST: ReadonlyArray<ChainBase>;
88
- //#endregion
89
- //#region src/capabilities.d.ts
90
- type BitcoinCapabilityInput = {
91
- chainCount: number;
92
- features: {
93
- events: boolean;
94
- sendTransfer: boolean;
95
- signMessage: boolean;
96
- signPsbt: boolean;
97
- };
98
- };
99
- /**
100
- * `signIn` is false: there is no Sign-In-With-Bitcoin standard, and BIP-322
101
- * is message-signing oriented rather than auth. `sendTransfer` leaves UTXO
102
- * selection, fees and broadcast to the wallet; `signPsbt` is sign-only.
103
- */
104
- declare const resolveBitcoinCapabilities: (input: BitcoinCapabilityInput) => WalletCapabilities;
105
- //#endregion
106
64
  //#region src/injected/sats-connect.d.ts
107
65
  /** sats-connect (Xverse) shape; a JSON-RPC-ish `request(method, params)`. */
66
+ type RpcValue = boolean | number | string | null | ReadonlyArray<RpcValue> | {
67
+ readonly [key: string]: RpcValue | undefined;
68
+ };
108
69
  type SatsConnectProvider = {
109
- request: (method: string, params?: Record<string, unknown>) => Promise<{
70
+ request: (method: string, params?: Readonly<Record<string, RpcValue>>) => Promise<{
110
71
  error?: {
111
72
  message: string;
112
73
  };
113
- result?: unknown;
74
+ result?: RpcValue;
114
75
  }>;
115
76
  };
116
77
  //#endregion
117
78
  //#region src/injected/unisat.d.ts
79
+ type UnisatNetwork = "livenet" | "mainnet" | "signet" | "testnet";
80
+ /** The only networks UniSat's `switchNetwork` accepts. */
81
+ type SwitchableNetwork = "livenet" | "testnet";
118
82
  /** UniSat-style provider: a single object on `window.unisat` with the
119
83
  * same four methods every UniSat-derivative wallet exposes (UniSat
120
84
  * itself, OKX Wallet's Bitcoin path at `window.okxwallet.bitcoin`). */
121
85
  type UnisatProvider = {
122
86
  getAccounts: () => Promise<ReadonlyArray<string>>;
123
- getNetwork?: () => Promise<"livenet" | "mainnet" | "testnet" | "signet">;
124
- on?: (event: "accountsChanged" | "networkChanged", listener: (...args: Array<unknown>) => void) => void;
87
+ getNetwork?: () => Promise<UnisatNetwork>;
88
+ on?: (event: "accountsChanged" | "networkChanged", listener: (...args: Array<UnisatEventValue>) => void) => void;
125
89
  pushPsbt?: (psbtHex: string) => Promise<string>;
126
- removeListener?: (event: "accountsChanged" | "networkChanged", listener: (...args: Array<unknown>) => void) => void;
90
+ removeListener?: (event: "accountsChanged" | "networkChanged", listener: (...args: Array<UnisatEventValue>) => void) => void;
127
91
  requestAccounts: () => Promise<ReadonlyArray<string>>;
128
92
  sendBitcoin?: (recipient: string, amount: number) => Promise<string>;
129
93
  signMessage: (message: string, type?: "ecdsa" | "bip322-simple") => Promise<string>;
130
- signPsbt: (psbtHex: string, options?: Record<string, unknown>) => Promise<string>;
94
+ signPsbt: (psbtHex: string, options?: UnisatSignPsbtOptions) => Promise<string>;
95
+ /** UniSat has it; OKX's `window.okxwallet.bitcoin` is pinned to mainnet. */
96
+ switchNetwork?: (network: SwitchableNetwork) => Promise<void>;
97
+ };
98
+ type UnisatEventItem = number | string | null;
99
+ type UnisatEventValue = ReadonlyArray<UnisatEventItem> | string | undefined;
100
+ type UnisatSignPsbtOptions = {
101
+ autoFinalized?: boolean;
131
102
  };
132
103
  //#endregion
133
104
  //#region src/injected/icon.d.ts
@@ -148,6 +119,18 @@ type InjectedHost = {
148
119
  BitcoinProvider?: SatsConnectProvider;
149
120
  };
150
121
  };
122
+ declare global {
123
+ interface Window {
124
+ btc?: UnisatProvider;
125
+ okxwallet?: {
126
+ bitcoin?: UnisatProvider;
127
+ };
128
+ unisat?: UnisatProvider;
129
+ XverseProviders?: {
130
+ BitcoinProvider?: SatsConnectProvider;
131
+ };
132
+ }
133
+ }
151
134
  type InjectedBitcoinDiscoveryOptions = {
152
135
  /** Suppresses emission when Wallet Standard discovery has already
153
136
  * registered a Bitcoin adapter for the same browser session. */
@@ -175,29 +158,20 @@ declare const bitcoinDiscoverer: PlatformDiscoverer;
175
158
  //#endregion
176
159
  //#region src/signer-augmentation.d.ts
177
160
  /**
178
- * Bitcoin's signer surface is fragmented: `getSigner()` returns a
179
- * `WalletStandardWallet`, a UniSat-shaped provider, or a sats-connect
180
- * `BitcoinProvider` depending on which adapter discovered the wallet.
161
+ * The injected adapters hand back the raw provider they drive. Wallet
162
+ * Standard adapters register `"wallet-standard"` through
163
+ * `@usebutr/wallet-standard-shared`.
181
164
  */
182
- type UnisatLike = {
183
- getAccounts: () => Promise<ReadonlyArray<string>>;
184
- requestAccounts: () => Promise<ReadonlyArray<string>>;
185
- signMessage: (message: string, type?: string) => Promise<string>;
186
- signPsbt: (psbtHex: string, options?: Record<string, unknown>) => Promise<string>;
187
- };
188
- type SatsConnectLike = {
189
- request: (method: string, params?: Record<string, unknown>) => Promise<{
190
- error?: {
191
- message: string;
192
- };
193
- result?: unknown;
194
- }>;
195
- };
196
165
  declare module "@usebutr/core" {
197
- interface SignerForPlatform {
198
- bitcoin: SatsConnectLike | UnisatLike | WalletStandardWallet;
166
+ interface WalletSignerRegistry {
167
+ "sats-connect": {
168
+ provider: SatsConnectProvider;
169
+ };
170
+ unisat: {
171
+ provider: UnisatProvider;
172
+ };
199
173
  }
200
174
  }
201
175
  //#endregion
202
- export { BITCOIN_CHAINS, BITCOIN_CHAINS_LIST, type BitcoinCapabilityInput, type BitcoinSendTransferFeature, type BitcoinSendTransferInput, type BitcoinSendTransferOutput, type BitcoinSignMessageFeature, type BitcoinSignMessageInput, type BitcoinSignMessageOutput, type BitcoinSignPsbtFeature, type BitcoinSignPsbtInput, type BitcoinSignPsbtOutput, GENERIC_BITCOIN_ICON, type InjectedBitcoinDiscoveryOptions, bitcoinDiscoverer, buildBitcoinAdapter, discoverBitcoinAdapters, discoverInjectedBitcoinAdapter, resolveBitcoinCapabilities };
176
+ export { type BitcoinSendTransferFeature, type BitcoinSendTransferInput, type BitcoinSendTransferOutput, type BitcoinSignMessageFeature, type BitcoinSignMessageInput, type BitcoinSignMessageOutput, type BitcoinSignPsbtFeature, type BitcoinSignPsbtInput, type BitcoinSignPsbtOutput, GENERIC_BITCOIN_ICON, type InjectedBitcoinDiscoveryOptions, bitcoinDiscoverer, buildBitcoinAdapter, discoverBitcoinAdapters, discoverInjectedBitcoinAdapter };
203
177
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/wallet-standard-types.ts","../src/wallet-standard-adapter.ts","../src/chains.ts","../src/capabilities.ts","../src/injected/sats-connect.ts","../src/injected/unisat.ts","../src/injected/icon.ts","../src/injected/index.ts","../src/discoverer.ts","../src/signer-augmentation.ts"],"mappings":";;;KAQK;EACH,SAAS;EACT,SAAS;;KAGN;EACH,WAAW;EACX,eAAe;;KAGZ;EACH,cAAc,OAAO,4BAA4B,QAAQ;;KAGtD;EACH,SAAS;;EAET;;EAEA,MAAM;;;EAGN,aAAa;;KAGV;;;EAGH,YAAY;;KAGT;EACH,WAAW,OAAO,yBAAyB,QAAQ;;KAGhD;EACH,SAAS;EACT;EACA;EACA;;KAGG;;EAEH;;KAGG;EACH,eAAe,OAAO,6BAA6B,QAAQ;;;;;;;;;cC/BvD,sBACJ,QAAQ,sBAIR;;;;AAAA,wBAAwB,8BACvB;;cAyIG,0BAA2B,YAAY,SAAS;;;;;;;;cCjKhD;;;;;;;;;;;;;;;;;;;;cAqBA,qBAAqB,cAAc;;;KCzBpC;EACH;EACA;IACE;IACA;IACA;IACA;;;;;;;;cASE,6BAA8B,OAAO,2BAAyB;;;;KCT/D;EACH,UACE,gBACA,SAAS,4BACN;IAAU;MAAU;;IAAmB;;;;;;;;KCFzC;EACH,mBAAmB,QAAQ;EAC3B,mBAAmB;EACnB,MACE,6CACA,cAAc,MAAM;EAEtB,YAAY,oBAAoB;EAChC,kBACE,6CACA,cAAc,MAAM;EAEtB,uBAAuB,QAAQ;EAC/B,eAAe,mBAAmB,mBAAmB;EACrD,cAAc,iBAAiB,qCAAqC;EACpE,WAAW,iBAAiB,UAAU,4BAA4B;;;;;;;;cCtB9D;;;KCKD;EACH,MAAM;EACN;IAAc,UAAU;;EACxB,SAAS;EACT;IAAoB,kBAAkB;;;KAGnC;;;EAGH;;;EAGA;;EAEA,SAAS;;;;;;;cAqDL,iCACJ,YAAY,SAAS,wBACrB,UAAS;;;;;;;;cCrEL,mBAAmB;;;;;;;;KCHpB;EACH,mBAAmB,QAAQ;EAC3B,uBAAuB,QAAQ;EAC/B,cAAc,iBAAiB,kBAAkB;EACjD,WAAW,iBAAiB,UAAU,4BAA4B;;KAG/D;EACH,UACE,gBACA,SAAS,4BACN;IAAU;MAAU;;IAAmB;;;;YAKlC;IACR,SAAS,kBAAkB,aAAa"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/wallet-standard-types.ts","../src/wallet-standard-adapter.ts","../src/injected/sats-connect.ts","../src/injected/unisat.ts","../src/injected/icon.ts","../src/injected/index.ts","../src/discoverer.ts","../src/signer-augmentation.ts"],"mappings":";;;KAQK;EACH,SAAS;EACT,SAAS;;KAGN;EACH,WAAW;EACX,eAAe;;KAGZ;EACH,cAAc,OAAO,4BAA4B,QAAQ;EACzD;;KAGG;EACH,SAAS;;EAET;;EAEA,MAAM;;;EAGN,aAAa;;KAGV;;;EAGH,YAAY;;KAGT;EACH,WAAW,OAAO,yBAAyB,QAAQ;EACnD;;KAGG;EACH,SAAS;EACT;EACA;EACA;;KAGG;;EAEH;;KAGG;EACH,eAAe,OAAO,6BAA6B,QAAQ;EAC3D;;;;;;;;;cChCI,sBAAmB,QACf,sBAIe;;;;AAAA,wBAAC,8BACvB;;cAgEG,0BAAuB,YAAgB,SAAS;;;;KC3EjD,8CAKD,cAAc;YACF,cAAc;;KAEzB;EACH,UACE,gBACA,SAAS,SAAS,eAAe,eAC9B;IAAU;MAAU;;IAAmB,SAAS;;;;;KCZlD;;KAGA;;;;KAKA;EACH,mBAAmB,QAAQ;EAC3B,mBAAmB,QAAQ;EAC3B,MACE,6CACA,cAAc,MAAM,MAAM;EAE5B,YAAY,oBAAoB;EAChC,kBACE,6CACA,cAAc,MAAM,MAAM;EAE5B,uBAAuB,QAAQ;EAC/B,eAAe,mBAAmB,mBAAmB;EACrD,cAAc,iBAAiB,qCAAqC;EACpE,WAAW,iBAAiB,UAAU,0BAA0B;;EAEhE,iBAAiB,SAAS,sBAAsB;;KAG7C;KACA,mBAAmB,cAAc;KAEjC;EACH;;;;;;;;cClDI;;;KCKD;EACH,MAAM;EACN;IAAc,UAAU;;EACxB,SAAS;EACT;IAAoB,kBAAkB;;;QAGhC;YAEI;IACR,MAAM;IACN;MAAc,UAAU;;IACxB,SAAS;IACT;MAAoB,kBAAkB;;;;KAIrC;;;EAGH;;;EAGA;;EAEA,SAAS;;;;;;;cAiDL,iCAA8B,YACtB,SAAS,wBAAsB,UAClC;;;;;;;;cC3EL,mBAAmB;;;;;;;;;YCAb;IACR;MAAkB,UAAU;;IAC5B;MAAU,UAAU"}