@usebutr/bitcoin 0.2.4 → 0.2.6

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 CHANGED
@@ -1,6 +1,5 @@
1
1
  import { ChainBase, PlatformDiscoverer, WalletAdapter, WalletCapabilities } from "@usebutr/core";
2
2
  import { WalletStandardWallet, WalletStandardWalletAccount } from "@usebutr/wallet-standard-shared";
3
-
4
3
  //#region src/wallet-standard-types.d.ts
5
4
  type BitcoinSignMessageInput = {
6
5
  account: WalletStandardWalletAccount;
@@ -11,11 +10,13 @@ type BitcoinSignMessageOutput = {
11
10
  signedMessage: Uint8Array;
12
11
  };
13
12
  type BitcoinSignMessageFeature = {
14
- signMessage(input: BitcoinSignMessageInput): Promise<BitcoinSignMessageOutput>;
13
+ signMessage: (input: BitcoinSignMessageInput) => Promise<BitcoinSignMessageOutput>;
15
14
  };
16
15
  type BitcoinSignPsbtInput = {
17
- account: WalletStandardWalletAccount; /** Network chain id (`bip122:…`). */
18
- chain: string; /** Base64- or hex-encoded PSBT bytes. */
16
+ account: WalletStandardWalletAccount;
17
+ /** Network chain id (`bip122:…`). */
18
+ chain: string;
19
+ /** Base64- or hex-encoded PSBT bytes. */
19
20
  psbt: Uint8Array;
20
21
  /** Optional input indexes to sign; omit to sign every input the wallet
21
22
  * controls. */
@@ -27,7 +28,7 @@ type BitcoinSignPsbtOutput = {
27
28
  signedPsbt: Uint8Array;
28
29
  };
29
30
  type BitcoinSignPsbtFeature = {
30
- signPsbt(input: BitcoinSignPsbtInput): Promise<BitcoinSignPsbtOutput>;
31
+ signPsbt: (input: BitcoinSignPsbtInput) => Promise<BitcoinSignPsbtOutput>;
31
32
  };
32
33
  type BitcoinSendTransferInput = {
33
34
  account: WalletStandardWalletAccount;
@@ -36,10 +37,11 @@ type BitcoinSendTransferInput = {
36
37
  recipient: string;
37
38
  };
38
39
  type BitcoinSendTransferOutput = {
39
- /** Broadcast txid. */txid: string;
40
+ /** Broadcast txid. */
41
+ txid: string;
40
42
  };
41
43
  type BitcoinSendTransferFeature = {
42
- sendTransfer(input: BitcoinSendTransferInput): Promise<BitcoinSendTransferOutput>;
44
+ sendTransfer: (input: BitcoinSendTransferInput) => Promise<BitcoinSendTransferOutput>;
43
45
  };
44
46
  //#endregion
45
47
  //#region src/wallet-standard-adapter.d.ts
@@ -60,10 +62,10 @@ declare const slugify: (name: string) => string;
60
62
  * butr's scope.
61
63
  * - `getTransactionReceipt` returns `"Pending"` for the same reason.
62
64
  * - `sendTx` expects the consumer to pass `{ amount: bigint, recipient: string }`
63
- * via butr's `unknown` tx parameter — the simplest mental model that
65
+ * via butr's `unknown` tx parameter; the simplest mental model that
64
66
  * maps onto `bitcoin:sendTransfer`. PSBT-shaped flows go through
65
67
  * `signTransaction`.
66
- * - `signTransaction` expects a `Uint8Array` PSBT (raw bytes) — the
68
+ * - `signTransaction` expects a `Uint8Array` PSBT (raw bytes); the
67
69
  * same shape `bitcoin:signPsbt` accepts. Consumers building with
68
70
  * `bitcoinjs-lib` get bytes via `psbt.toBuffer()`.
69
71
  * - `switchChain` is local-state-only; the capability flag is `false`
@@ -74,7 +76,6 @@ declare const buildBitcoinAdapter: (wallet: WalletStandardWallet,
74
76
  /** Optional. Called with a function that pushes a synthetic
75
77
  * `disconnected` event to all current subscribers. The discovery
76
78
  * layer invokes it on Wallet Standard `unregister`. */
77
-
78
79
  registerDisconnector?: (emit: () => void) => void) => WalletAdapter | null;
79
80
  //#endregion
80
81
  //#region src/wallet-standard.d.ts
@@ -106,7 +107,7 @@ declare const discoverBitcoinAdapters: (onAdapter: (adapter: WalletAdapter) => v
106
107
  * - Signet: `bip122:00000008819873e925422c1ff0f99f7c`
107
108
  *
108
109
  * Bitcoin has no per-call "switch chain" RPC across the major wallets,
109
- * so butr's adapter treats chain as a wallet-side configuration —
110
+ * so butr's adapter treats chain as a wallet-side configuration;
110
111
  * `switchChain` updates local state to influence subsequent calls (same
111
112
  * posture as SVM). Bitcoin's `switchChain` capability is `false` by
112
113
  * default; consumers building on top can opt in if their wallet exposes
@@ -157,66 +158,51 @@ type BitcoinCapabilityInput = {
157
158
  * message-signing oriented, not auth).
158
159
  * - `subscribe = events present`. Most Bitcoin wallets don't emit
159
160
  * change events portably; capabilities admits the truth.
160
- * - `switchChain = false`. No portable per-call switch RPC across
161
- * Bitcoin wallets — Xverse/Unisat/Phantom each pick their own network.
161
+ * - `switchChain = chainCount > 1`. No portable switch RPC across
162
+ * Bitcoin wallets (Xverse/Unisat/Phantom each pick their own
163
+ * network), so the switch is local-state-only and advertised only
164
+ * when the wallet exposes more than one chain to switch between.
162
165
  */
163
166
  declare const resolveBitcoinCapabilities: (input: BitcoinCapabilityInput) => WalletCapabilities;
164
167
  //#endregion
165
- //#region src/injected/icon.d.ts
166
- /**
167
- * Generic Bitcoin wallet icon — same purse SVG style as the EVM
168
- * package, recoloured. Inline so the picker doesn't flash.
169
- *
170
- * Lives in its own file because both injected adapters (UniSat-shape
171
- * and sats-connect) need the same fallback when the wallet doesn't
172
- * advertise its own icon, and there's no other "shared" thing they
173
- * both want — a one-line module beats a grab-bag.
174
- */
175
- declare const GENERIC_BITCOIN_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2Y3OTMxYSIgc3Ryb2tlPSJub25lIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIvPjx0ZXh0IHg9IjEyIiB5PSIxNyIgZm9udC1mYW1pbHk9InNlcmlmIiBmb250LXNpemU9IjE0IiBmb250LXdlaWdodD0iYm9sZCIgZmlsbD0iI2ZmZiIgdGV4dC1hbmNob3I9Im1pZGRsZSI+QjwvdGV4dD48L3N2Zz4=";
176
- //#endregion
177
168
  //#region src/injected/sats-connect.d.ts
178
- /** sats-connect (Xverse) shape — a JSON-RPC-ish `request(method, params)`. */
169
+ /** sats-connect (Xverse) shape; a JSON-RPC-ish `request(method, params)`. */
179
170
  type SatsConnectProvider = {
180
- request(method: string, params?: Record<string, unknown>): Promise<{
171
+ request: (method: string, params?: Record<string, unknown>) => Promise<{
181
172
  error?: {
182
173
  message: string;
183
174
  };
184
175
  result?: unknown;
185
176
  }>;
186
177
  };
187
- /**
188
- * Wrap an Xverse-style `BitcoinProvider` (sats-connect) into a butr
189
- * `WalletAdapter`. sats-connect routes everything through a single
190
- * `request(method, params)` RPC; we shim each butr capability onto the
191
- * corresponding sats-connect method.
192
- *
193
- * Tested against Xverse's `getAccounts`, `signMessage`, `signPsbt`,
194
- * `sendTransfer` methods.
195
- */
196
178
  //#endregion
197
179
  //#region src/injected/unisat.d.ts
198
180
  /** UniSat-style provider: a single object on `window.unisat` with the
199
181
  * same four methods every UniSat-derivative wallet exposes (UniSat
200
182
  * itself, OKX Wallet's Bitcoin path at `window.okxwallet.bitcoin`). */
201
183
  type UnisatProvider = {
202
- getAccounts(): Promise<ReadonlyArray<string>>;
203
- getNetwork?(): Promise<"livenet" | "mainnet" | "testnet" | "signet">;
204
- on?(event: "accountsChanged" | "networkChanged", listener: (...args: Array<unknown>) => void): void;
205
- pushPsbt?(psbtHex: string): Promise<string>;
206
- removeListener?(event: "accountsChanged" | "networkChanged", listener: (...args: Array<unknown>) => void): void;
207
- requestAccounts(): Promise<ReadonlyArray<string>>;
208
- sendBitcoin?(recipient: string, amount: number): Promise<string>;
209
- signMessage(message: string, type?: "ecdsa" | "bip322-simple"): Promise<string>;
210
- signPsbt(psbtHex: string, options?: Record<string, unknown>): Promise<string>;
184
+ getAccounts: () => Promise<ReadonlyArray<string>>;
185
+ getNetwork?: () => Promise<"livenet" | "mainnet" | "testnet" | "signet">;
186
+ on?: (event: "accountsChanged" | "networkChanged", listener: (...args: Array<unknown>) => void) => void;
187
+ pushPsbt?: (psbtHex: string) => Promise<string>;
188
+ removeListener?: (event: "accountsChanged" | "networkChanged", listener: (...args: Array<unknown>) => void) => void;
189
+ requestAccounts: () => Promise<ReadonlyArray<string>>;
190
+ sendBitcoin?: (recipient: string, amount: number) => Promise<string>;
191
+ signMessage: (message: string, type?: "ecdsa" | "bip322-simple") => Promise<string>;
192
+ signPsbt: (psbtHex: string, options?: Record<string, unknown>) => Promise<string>;
211
193
  };
194
+ //#endregion
195
+ //#region src/injected/icon.d.ts
212
196
  /**
213
- * Wrap a UniSat-style provider (`window.unisat`, `window.okxwallet.bitcoin`,
214
- * `window.btc`) into a butr `WalletAdapter`.
197
+ * Generic Bitcoin wallet icon, same purse SVG style as the EVM
198
+ * package, recoloured. Inline so the picker doesn't flash.
215
199
  *
216
- * The UniSat shape is consistent enough that one adapter handles every
217
- * derivative. Differences (network names, `sendBitcoin` presence) are
218
- * gated by feature detection per call.
200
+ * Lives in its own file because both injected adapters (UniSat-shape
201
+ * and sats-connect) need the same fallback when the wallet doesn't
202
+ * advertise its own icon, and there's no other "shared" thing they
203
+ * both want; a one-line module beats a grab-bag.
219
204
  */
205
+ declare const GENERIC_BITCOIN_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2Y3OTMxYSIgc3Ryb2tlPSJub25lIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIvPjx0ZXh0IHg9IjEyIiB5PSIxNyIgZm9udC1mYW1pbHk9InNlcmlmIiBmb250LXNpemU9IjE0IiBmb250LXdlaWdodD0iYm9sZCIgZmlsbD0iI2ZmZiIgdGV4dC1hbmNob3I9Im1pZGRsZSI+QjwvdGV4dD48L3N2Zz4=";
220
206
  //#endregion
221
207
  //#region src/injected/index.d.ts
222
208
  type InjectedHost = {
@@ -235,7 +221,8 @@ type InjectedBitcoinDiscoveryOptions = {
235
221
  hasAnyWalletStandardAdapter?: () => boolean;
236
222
  /** Settle deadline in ms before the fallback fires. Same default and
237
223
  * intent as the EVM injected fallback. */
238
- settleMs?: number; /** Override the global host (tests, iframes). */
224
+ settleMs?: number;
225
+ /** Override the global host (tests, iframes). */
239
226
  target?: InjectedHost | null;
240
227
  };
241
228
  /**
@@ -267,27 +254,27 @@ declare const bitcoinDiscoverer: PlatformDiscoverer;
267
254
  //#region src/signer-augmentation.d.ts
268
255
  /**
269
256
  * Augment `@usebutr/core`'s `SignerForPlatform` registry with the Bitcoin
270
- * entry. Bitcoin's signer surface is fragmented — `getSigner()` may
257
+ * entry. Bitcoin's signer surface is fragmented: `getSigner()` may
271
258
  * return one of three shapes depending on which adapter discovered the
272
259
  * wallet:
273
260
  *
274
- * - `WalletStandardWallet` — for Phantom, Magic Eden, Leather, OKX
261
+ * - `WalletStandardWallet`: for Phantom, Magic Eden, Leather, OKX
275
262
  * (modern Wallet Standard path).
276
- * - A UniSat-shaped provider — for Unisat, OKX legacy, `window.btc`
263
+ * - A UniSat-shaped provider; for Unisat, OKX legacy, `window.btc`
277
264
  * (injected path).
278
- * - A sats-connect `BitcoinProvider` — for Xverse (sats-connect path).
265
+ * - A sats-connect `BitcoinProvider`; for Xverse (sats-connect path).
279
266
  *
280
267
  * The registry surfaces the union honestly so consumers know they need
281
268
  * to runtime-narrow.
282
269
  */
283
270
  type UnisatLike = {
284
- getAccounts(): Promise<ReadonlyArray<string>>;
285
- requestAccounts(): Promise<ReadonlyArray<string>>;
286
- signMessage(message: string, type?: string): Promise<string>;
287
- signPsbt(psbtHex: string, options?: Record<string, unknown>): Promise<string>;
271
+ getAccounts: () => Promise<ReadonlyArray<string>>;
272
+ requestAccounts: () => Promise<ReadonlyArray<string>>;
273
+ signMessage: (message: string, type?: string) => Promise<string>;
274
+ signPsbt: (psbtHex: string, options?: Record<string, unknown>) => Promise<string>;
288
275
  };
289
276
  type SatsConnectLike = {
290
- request(method: string, params?: Record<string, unknown>): Promise<{
277
+ request: (method: string, params?: Record<string, unknown>) => Promise<{
291
278
  error?: {
292
279
  message: string;
293
280
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/wallet-standard-types.ts","../src/wallet-standard-adapter.ts","../src/wallet-standard.ts","../src/chains.ts","../src/capabilities.ts","../src/injected/icon.ts","../src/injected/sats-connect.ts","../src/injected/unisat.ts","../src/injected/index.ts","../src/discoverer.ts","../src/signer-augmentation.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/wallet-standard-types.ts","../src/wallet-standard-adapter.ts","../src/wallet-standard.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":";;;KAgBK;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;;;;cCrCvD,UAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;cA2CX,sBACJ,QAAQ,sBAIR;;;;AAAA,wBAAwB,8BACvB;;;;;;;;;;;;;;;;;cCzDG,0BAA2B,YAAY,SAAS;;;;;;;;;;;;;;;;;;;;cCAhD;;;;;;;;;;;;;;;;;;;;cAqBA,qBAAqB,cAAc;;;KCtCpC;EACH;EACA;IACE;IACA;IACA;IACA;;;;;;;;;;;;;;;;;;;;;cAsBE,6BAA8B,OAAO,2BAAyB;;;;KCrB/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;;;;;;;;;;;;;cCjB9D;;;KCAD;EACH,MAAM;EACN;IAAc,UAAU;;EACxB,SAAS;EACT;IAAoB,kBAAkB;;;KAGnC;;;EAGH;;;EAGA;;EAEA,SAAS;;;;;;;;;;;;;;;;;cA+DL,iCACJ,YAAY,SAAS,wBACrB,UAAS;;;;;;;;;cC9EL,mBAAmB;;;;;;;;;;;;;;;;;;KCMpB;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"}
package/dist/index.js CHANGED
@@ -15,8 +15,10 @@ import { buildAccount, discoverWalletStandard, getFeature, pickAccountByAddress,
15
15
  * message-signing oriented, not auth).
16
16
  * - `subscribe = events present`. Most Bitcoin wallets don't emit
17
17
  * change events portably; capabilities admits the truth.
18
- * - `switchChain = false`. No portable per-call switch RPC across
19
- * Bitcoin wallets — Xverse/Unisat/Phantom each pick their own network.
18
+ * - `switchChain = chainCount > 1`. No portable switch RPC across
19
+ * Bitcoin wallets (Xverse/Unisat/Phantom each pick their own
20
+ * network), so the switch is local-state-only and advertised only
21
+ * when the wallet exposes more than one chain to switch between.
20
22
  */
21
23
  const resolveBitcoinCapabilities = (input) => ({
22
24
  getBalance: false,
@@ -48,7 +50,6 @@ const buildBitcoinChain = (chainId, walletName) => ({
48
50
  namespace: "bip122",
49
51
  reference: chainId.slice(7)
50
52
  });
51
- const buildBitcoinAccount = (address, chain) => buildAccount(address, chain);
52
53
  /**
53
54
  * Adapt a Bitcoin Wallet Standard `Wallet` into a butr `WalletAdapter`.
54
55
  *
@@ -65,10 +66,10 @@ const buildBitcoinAccount = (address, chain) => buildAccount(address, chain);
65
66
  * butr's scope.
66
67
  * - `getTransactionReceipt` returns `"Pending"` for the same reason.
67
68
  * - `sendTx` expects the consumer to pass `{ amount: bigint, recipient: string }`
68
- * via butr's `unknown` tx parameter — the simplest mental model that
69
+ * via butr's `unknown` tx parameter; the simplest mental model that
69
70
  * maps onto `bitcoin:sendTransfer`. PSBT-shaped flows go through
70
71
  * `signTransaction`.
71
- * - `signTransaction` expects a `Uint8Array` PSBT (raw bytes) — the
72
+ * - `signTransaction` expects a `Uint8Array` PSBT (raw bytes); the
72
73
  * same shape `bitcoin:signPsbt` accepts. Consumers building with
73
74
  * `bitcoinjs-lib` get bytes via `psbt.toBuffer()`.
74
75
  * - `switchChain` is local-state-only; the capability flag is `false`
@@ -77,9 +78,9 @@ const buildBitcoinAccount = (address, chain) => buildAccount(address, chain);
77
78
  */
78
79
  const buildBitcoinAdapter = (wallet, registerDisconnector) => {
79
80
  const bitcoinChainId = pickBitcoinChain(wallet);
80
- if (!bitcoinChainId) return null;
81
+ if (bitcoinChainId === null) return null;
81
82
  const connect = getFeature(wallet, "standard:connect");
82
- if (!connect) return null;
83
+ if (connect === void 0) return null;
83
84
  const disconnect = getFeature(wallet, "standard:disconnect");
84
85
  const events = getFeature(wallet, "standard:events");
85
86
  const signMessage = getFeature(wallet, "bitcoin:signMessage");
@@ -91,9 +92,9 @@ const buildBitcoinAdapter = (wallet, registerDisconnector) => {
91
92
  const notifyAccountChanged = () => {
92
93
  if (wallet.accounts.length === 0) return;
93
94
  const chain = currentChain();
94
- const built = wallet.accounts.map((a) => buildBitcoinAccount(a.address, chain));
95
+ const built = wallet.accounts.map((a) => buildAccount(a.address, chain));
95
96
  const first = built[0];
96
- if (!first) return;
97
+ if (first === void 0) return;
97
98
  for (const listener of listeners) listener({
98
99
  account: first,
99
100
  accounts: built,
@@ -103,6 +104,19 @@ const buildBitcoinAdapter = (wallet, registerDisconnector) => {
103
104
  registerDisconnector?.(() => {
104
105
  for (const listener of listeners) listener({ type: "disconnected" });
105
106
  });
107
+ const sendTransferTx = async (tx, account) => {
108
+ if (sendTransfer === void 0) throw new Error(`Wallet ${wallet.name} does not advertise bitcoin:sendTransfer`);
109
+ if (typeof tx !== "object" || tx === null || !("amount" in tx) || typeof tx.amount !== "bigint" || !("recipient" in tx) || typeof tx.recipient !== "string") throw new TypeError("Bitcoin sendTx expects { amount: bigint, recipient: string }: pass the recipient address and an amount in satoshis");
110
+ const { amount, recipient } = tx;
111
+ const wsAccount = account ? pickAccountByAddress(wallet.accounts, account.walletAddress) : wallet.accounts[0];
112
+ if (wsAccount === void 0) throw new Error("No connected account");
113
+ return (await sendTransfer.sendTransfer({
114
+ account: wsAccount,
115
+ amount,
116
+ chain: currentChainId,
117
+ recipient
118
+ })).txid;
119
+ };
106
120
  return {
107
121
  capabilities: resolveBitcoinCapabilities({
108
122
  chainCount: wallet.chains.filter((c) => c.startsWith(BITCOIN_PREFIX)).length,
@@ -115,65 +129,47 @@ const buildBitcoinAdapter = (wallet, registerDisconnector) => {
115
129
  }),
116
130
  chainPlatform: "bitcoin",
117
131
  async connect(opts) {
118
- await connect.connect(opts?.silent ? { silent: true } : void 0);
132
+ await connect.connect(opts?.silent === true ? { silent: true } : void 0);
119
133
  },
120
134
  async disconnect() {
121
- if (disconnect) try {
135
+ if (disconnect !== void 0) try {
122
136
  await disconnect.disconnect();
123
137
  } catch (error) {
124
138
  logWarn("[butr] Bitcoin Wallet Standard disconnect threw:", error);
125
139
  }
126
140
  },
127
- getAccount() {
141
+ getAccount: () => {
128
142
  const address = pickFirstAddress(wallet.accounts);
129
- if (!address) return Promise.resolve(null);
130
- return Promise.resolve(buildBitcoinAccount(address, currentChain()));
143
+ if (address === null) return Promise.resolve(null);
144
+ return Promise.resolve(buildAccount(address, currentChain()));
131
145
  },
132
- getAccounts() {
146
+ getAccounts: () => {
133
147
  const chain = currentChain();
134
- return Promise.resolve(wallet.accounts.map((a) => buildBitcoinAccount(a.address, chain)));
135
- },
136
- getBalance() {
137
- return Promise.resolve({
138
- decimals: BITCOIN_DECIMALS,
139
- formatted: "0",
140
- symbol: "BTC",
141
- value: 0n
142
- });
143
- },
144
- getSigner() {
145
- return Promise.resolve(wallet);
146
- },
147
- getTransactionReceipt() {
148
- return Promise.resolve({ status: "Pending" });
148
+ return Promise.resolve(wallet.accounts.map((a) => buildAccount(a.address, chain)));
149
149
  },
150
+ getBalance: () => Promise.resolve({
151
+ decimals: BITCOIN_DECIMALS,
152
+ formatted: "0",
153
+ symbol: "BTC",
154
+ value: 0n
155
+ }),
156
+ getSigner: () => Promise.resolve(wallet),
157
+ getTransactionReceipt: () => Promise.resolve({ status: "Pending" }),
150
158
  icon: sanitizeIcon(wallet.icon),
151
159
  id: slugify(wallet.name),
152
160
  name: wallet.name,
153
161
  async requestAccounts() {
154
162
  await connect.connect();
155
163
  },
156
- async sendTx(tx, account) {
157
- if (!sendTransfer) throw new Error(`Wallet ${wallet.name} does not advertise bitcoin:sendTransfer`);
158
- if (!tx || typeof tx !== "object" || typeof tx.amount !== "bigint" || typeof tx.recipient !== "string") throw new TypeError("Bitcoin sendTx expects { amount: bigint, recipient: string } — pass the recipient address and an amount in satoshis");
159
- const { amount, recipient } = tx;
160
- const wsAccount = account ? pickAccountByAddress(wallet.accounts, account.walletAddress) : wallet.accounts[0] ?? null;
161
- if (!wsAccount) throw new Error("No connected account");
162
- return (await sendTransfer.sendTransfer({
163
- account: wsAccount,
164
- amount,
165
- chain: currentChainId,
166
- recipient
167
- })).txid;
168
- },
169
- sendTxToChain(tx, _targetChainId, account, cb) {
164
+ sendTx: (tx, account) => sendTransferTx(tx, account),
165
+ sendTxToChain: (tx, _targetChainId, account, cb) => {
170
166
  cb?.();
171
- return this.sendTx(tx, account);
167
+ return sendTransferTx(tx, account);
172
168
  },
173
169
  async signMessage(msg, account) {
174
- if (!signMessage) throw new Error(`Wallet ${wallet.name} does not advertise bitcoin:signMessage`);
175
- const wsAccount = account ? pickAccountByAddress(wallet.accounts, account.walletAddress) : wallet.accounts[0] ?? null;
176
- if (!wsAccount) throw new Error("No connected account");
170
+ if (signMessage === void 0) throw new Error(`Wallet ${wallet.name} does not advertise bitcoin:signMessage`);
171
+ const wsAccount = account ? pickAccountByAddress(wallet.accounts, account.walletAddress) : wallet.accounts[0];
172
+ if (wsAccount === void 0) throw new Error("No connected account");
177
173
  const output = await signMessage.signMessage({
178
174
  account: wsAccount,
179
175
  message: msg
@@ -183,34 +179,34 @@ const buildBitcoinAdapter = (wallet, registerDisconnector) => {
183
179
  signedMessage: output.signedMessage
184
180
  };
185
181
  },
186
- ...signPsbt ? { async signTransaction(tx, account) {
187
- const wsAccount = account ? pickAccountByAddress(wallet.accounts, account.walletAddress) : wallet.accounts[0] ?? null;
188
- if (!wsAccount) throw new Error("No connected account");
182
+ ...signPsbt === void 0 ? {} : { async signTransaction(tx, account) {
183
+ const wsAccount = account ? pickAccountByAddress(wallet.accounts, account.walletAddress) : wallet.accounts[0];
184
+ if (wsAccount === void 0) throw new Error("No connected account");
189
185
  if (!(tx instanceof Uint8Array)) throw new TypeError("Bitcoin signTransaction expects a PSBT as Uint8Array (e.g. psbt.toBuffer())");
190
186
  return (await signPsbt.signPsbt({
191
187
  account: wsAccount,
192
188
  chain: currentChainId,
193
189
  psbt: tx
194
190
  })).signedPsbt;
195
- } } : {},
191
+ } },
196
192
  subscribe(listener) {
197
193
  listeners.add(listener);
198
194
  let unsubWallet = null;
199
- if (events) {
195
+ if (events !== void 0) {
200
196
  const unsub = events.on("change", (changes) => {
201
- if (changes.chains) {
197
+ if (changes.chains !== void 0) {
202
198
  const next = changes.chains.find((c) => c === BITCOIN_MAINNET_ID) ?? changes.chains.find((c) => c.startsWith(BITCOIN_PREFIX));
203
- if (next) currentChainId = next;
199
+ if (next !== void 0) currentChainId = next;
204
200
  }
205
- if (changes.accounts) {
201
+ if (changes.accounts !== void 0) {
206
202
  if (changes.accounts.length === 0) {
207
203
  listener({ type: "disconnected" });
208
204
  return;
209
205
  }
210
206
  const chain = currentChain();
211
- const built = changes.accounts.map((a) => buildBitcoinAccount(a.address, chain));
207
+ const built = changes.accounts.map((a) => buildAccount(a.address, chain));
212
208
  const first = built[0];
213
- if (!first) return;
209
+ if (first === void 0) return;
214
210
  listener({
215
211
  account: first,
216
212
  accounts: built,
@@ -218,16 +214,18 @@ const buildBitcoinAdapter = (wallet, registerDisconnector) => {
218
214
  });
219
215
  return;
220
216
  }
221
- if (changes.chains) notifyAccountChanged();
217
+ if (changes.chains !== void 0) notifyAccountChanged();
222
218
  });
223
- unsubWallet = () => unsub();
219
+ unsubWallet = () => {
220
+ unsub();
221
+ };
224
222
  }
225
223
  return () => {
226
224
  listeners.delete(listener);
227
225
  unsubWallet?.();
228
226
  };
229
227
  },
230
- switchChain(chain) {
228
+ switchChain: (chain) => {
231
229
  if (chain.namespace !== "bip122") throw new Error(`Bitcoin adapter received non-Bitcoin chain "${chain.id}". Pass a chain with namespace "bip122".`);
232
230
  if (!wallet.chains.includes(chain.id)) throw new Error(`Wallet ${wallet.name} does not advertise chain "${chain.id}". Available: ${wallet.chains.join(", ")}`);
233
231
  currentChainId = chain.id;
@@ -268,7 +266,7 @@ const discoverBitcoinAdapters = (onAdapter) => discoverWalletStandard(onAdapter,
268
266
  * - Signet: `bip122:00000008819873e925422c1ff0f99f7c`
269
267
  *
270
268
  * Bitcoin has no per-call "switch chain" RPC across the major wallets,
271
- * so butr's adapter treats chain as a wallet-side configuration —
269
+ * so butr's adapter treats chain as a wallet-side configuration;
272
270
  * `switchChain` updates local state to influence subsequent calls (same
273
271
  * posture as SVM). Bitcoin's `switchChain` capability is `false` by
274
272
  * default; consumers building on top can opt in if their wallet exposes
@@ -299,13 +297,13 @@ const BITCOIN_CHAINS_LIST = Object.values(BITCOIN_CHAINS);
299
297
  //#endregion
300
298
  //#region src/injected/icon.ts
301
299
  /**
302
- * Generic Bitcoin wallet icon — same purse SVG style as the EVM
300
+ * Generic Bitcoin wallet icon, same purse SVG style as the EVM
303
301
  * package, recoloured. Inline so the picker doesn't flash.
304
302
  *
305
303
  * Lives in its own file because both injected adapters (UniSat-shape
306
304
  * and sats-connect) need the same fallback when the wallet doesn't
307
305
  * advertise its own icon, and there's no other "shared" thing they
308
- * both want — a one-line module beats a grab-bag.
306
+ * both want; a one-line module beats a grab-bag.
309
307
  */
310
308
  const GENERIC_BITCOIN_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2Y3OTMxYSIgc3Ryb2tlPSJub25lIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIvPjx0ZXh0IHg9IjEyIiB5PSIxNyIgZm9udC1mYW1pbHk9InNlcmlmIiBmb250LXNpemU9IjE0IiBmb250LXdlaWdodD0iYm9sZCIgZmlsbD0iI2ZmZiIgdGV4dC1hbmNob3I9Im1pZGRsZSI+QjwvdGV4dD48L3N2Zz4=";
311
309
 
@@ -345,65 +343,60 @@ const buildSatsConnectAdapter = (id, name, provider) => {
345
343
  message: "Connect to butr",
346
344
  purposes: ["payment", "ordinals"]
347
345
  });
348
- if (!result?.addresses) return [];
346
+ if (result?.addresses === void 0) return [];
349
347
  const addresses = result.addresses.map((a) => a.address);
350
348
  cachedAccounts = addresses;
351
349
  return addresses;
352
350
  };
351
+ const sendTransferTx = async (tx) => {
352
+ if (typeof tx !== "object" || tx === null || !("recipient" in tx) || typeof tx.recipient !== "string" || !("amount" in tx) || typeof tx.amount !== "bigint") throw new TypeError("Bitcoin sendTx expects { amount: bigint, recipient: string }: amount in satoshis");
353
+ const { amount, recipient } = tx;
354
+ return (await callRequest("sendTransfer", { recipients: [{
355
+ address: recipient,
356
+ amount: amount.toString()
357
+ }] })).txid;
358
+ };
353
359
  return {
354
360
  capabilities: CAPS_SATS_CONNECT,
355
361
  chainPlatform: "bitcoin",
356
362
  async connect() {
357
363
  await loadAccounts();
358
364
  },
359
- disconnect() {
365
+ disconnect: () => {
360
366
  cachedAccounts = [];
361
367
  return Promise.resolve();
362
368
  },
363
369
  async getAccount() {
364
370
  const first = cachedAccounts[0];
365
- if (first) return buildAccount(first, chain);
371
+ if (first !== void 0) return buildAccount(first, chain);
366
372
  const firstFresh = (await loadAccounts())[0];
367
- return firstFresh ? buildAccount(firstFresh, chain) : null;
373
+ return firstFresh === void 0 ? null : buildAccount(firstFresh, chain);
368
374
  },
369
375
  async getAccounts() {
370
376
  return (cachedAccounts.length > 0 ? cachedAccounts : await loadAccounts()).map((a) => buildAccount(a, chain));
371
377
  },
372
- getBalance() {
373
- return Promise.resolve({
374
- decimals: 8,
375
- formatted: "0",
376
- symbol: "BTC",
377
- value: 0n
378
- });
379
- },
380
- getSigner() {
381
- return Promise.resolve(provider);
382
- },
383
- getTransactionReceipt() {
384
- return Promise.resolve({ status: "Pending" });
385
- },
378
+ getBalance: () => Promise.resolve({
379
+ decimals: 8,
380
+ formatted: "0",
381
+ symbol: "BTC",
382
+ value: 0n
383
+ }),
384
+ getSigner: () => Promise.resolve(provider),
385
+ getTransactionReceipt: () => Promise.resolve({ status: "Pending" }),
386
386
  icon: GENERIC_BITCOIN_ICON,
387
387
  id,
388
388
  name,
389
389
  async requestAccounts() {
390
390
  await loadAccounts();
391
391
  },
392
- async sendTx(tx) {
393
- if (!tx || typeof tx !== "object" || typeof tx.recipient !== "string" || typeof tx.amount !== "bigint") throw new TypeError("Bitcoin sendTx expects { amount: bigint, recipient: string } — amount in satoshis");
394
- const { amount, recipient } = tx;
395
- return (await callRequest("sendTransfer", { recipients: [{
396
- address: recipient,
397
- amount: amount.toString()
398
- }] })).txid;
399
- },
400
- sendTxToChain(tx, _targetChainId, _account, cb) {
392
+ sendTx: (tx) => sendTransferTx(tx),
393
+ sendTxToChain: (tx, _targetChainId, _account, cb) => {
401
394
  cb?.();
402
- return this.sendTx(tx);
395
+ return sendTransferTx(tx);
403
396
  },
404
397
  async signMessage(msg) {
405
398
  const address = cachedAccounts[0];
406
- if (!address) throw new Error("No connected account");
399
+ if (address === void 0) throw new Error("No connected account");
407
400
  return {
408
401
  signature: base64ToBytes((await callRequest("signMessage", {
409
402
  address,
@@ -416,7 +409,7 @@ const buildSatsConnectAdapter = (id, name, provider) => {
416
409
  if (!(tx instanceof Uint8Array)) throw new TypeError("Bitcoin signTransaction expects a PSBT as Uint8Array (e.g. psbt.toBuffer())");
417
410
  return base64ToBytes((await callRequest("signPsbt", { psbt: bytesToBase64(tx) })).psbt);
418
411
  },
419
- switchChain(target) {
412
+ switchChain: (target) => {
420
413
  if (target.namespace !== "bip122") throw new Error(`Bitcoin adapter received non-Bitcoin chain "${target.id}". Pass a chain with namespace "bip122".`);
421
414
  chain = target;
422
415
  return Promise.resolve();
@@ -446,9 +439,16 @@ const CAPS_UNISAT = {
446
439
  * derivative. Differences (network names, `sendBitcoin` presence) are
447
440
  * gated by feature detection per call.
448
441
  */
442
+ const toStringArray = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
449
443
  const buildUnisatAdapter = (id, name, provider) => {
450
444
  let chain = BITCOIN_CHAINS.mainnet;
451
445
  const listenersSet = /* @__PURE__ */ new Set();
446
+ const sendBitcoinTx = (tx) => {
447
+ if (typeof provider.sendBitcoin !== "function") throw new TypeError(`Wallet ${name} does not expose sendBitcoin`);
448
+ if (typeof tx !== "object" || tx === null || !("recipient" in tx) || typeof tx.recipient !== "string" || !("amount" in tx) || typeof tx.amount !== "bigint") throw new TypeError("Bitcoin sendTx expects { amount: bigint, recipient: string }: amount in satoshis");
449
+ const { amount, recipient } = tx;
450
+ return provider.sendBitcoin(recipient, Number(amount));
451
+ };
452
452
  const refreshChain = async () => {
453
453
  if (typeof provider.getNetwork !== "function") return;
454
454
  try {
@@ -462,7 +462,7 @@ const buildUnisatAdapter = (id, name, provider) => {
462
462
  capabilities: CAPS_UNISAT,
463
463
  chainPlatform: "bitcoin",
464
464
  async connect(opts) {
465
- if (opts?.silent) {
465
+ if (opts?.silent === true) {
466
466
  if ((await provider.getAccounts()).length === 0) throw new Error("No authorized accounts for silent reconnect");
467
467
  await refreshChain();
468
468
  return;
@@ -470,12 +470,10 @@ const buildUnisatAdapter = (id, name, provider) => {
470
470
  await provider.requestAccounts();
471
471
  await refreshChain();
472
472
  },
473
- disconnect() {
474
- return Promise.resolve();
475
- },
473
+ disconnect: () => Promise.resolve(),
476
474
  async getAccount() {
477
475
  const first = (await provider.getAccounts())[0];
478
- if (!first) return null;
476
+ if (first === void 0) return null;
479
477
  await refreshChain();
480
478
  return buildAccount(first, chain);
481
479
  },
@@ -485,20 +483,14 @@ const buildUnisatAdapter = (id, name, provider) => {
485
483
  await refreshChain();
486
484
  return accounts.map((a) => buildAccount(a, chain));
487
485
  },
488
- getBalance() {
489
- return Promise.resolve({
490
- decimals: 8,
491
- formatted: "0",
492
- symbol: "BTC",
493
- value: 0n
494
- });
495
- },
496
- getSigner() {
497
- return Promise.resolve(provider);
498
- },
499
- getTransactionReceipt() {
500
- return Promise.resolve({ status: "Pending" });
501
- },
486
+ getBalance: () => Promise.resolve({
487
+ decimals: 8,
488
+ formatted: "0",
489
+ symbol: "BTC",
490
+ value: 0n
491
+ }),
492
+ getSigner: () => Promise.resolve(provider),
493
+ getTransactionReceipt: () => Promise.resolve({ status: "Pending" }),
502
494
  icon: GENERIC_BITCOIN_ICON,
503
495
  id,
504
496
  name,
@@ -506,16 +498,10 @@ const buildUnisatAdapter = (id, name, provider) => {
506
498
  await provider.requestAccounts();
507
499
  await refreshChain();
508
500
  },
509
- sendTx(tx) {
510
- if (typeof provider.sendBitcoin !== "function") throw new TypeError(`Wallet ${name} does not expose sendBitcoin`);
511
- if (!tx || typeof tx !== "object" || typeof tx.recipient !== "string" || typeof tx.amount !== "bigint") throw new TypeError("Bitcoin sendTx expects { amount: bigint, recipient: string } — amount in satoshis");
512
- const { amount, recipient } = tx;
513
- const sats = Number(amount);
514
- return provider.sendBitcoin(recipient, sats);
515
- },
516
- sendTxToChain(tx, _targetChainIdDecimal, _account, cb) {
501
+ sendTx: (tx) => sendBitcoinTx(tx),
502
+ sendTxToChain: (tx, _targetChainIdDecimal, _account, cb) => {
517
503
  cb?.();
518
- return this.sendTx(tx);
504
+ return sendBitcoinTx(tx);
519
505
  },
520
506
  async signMessage(msg) {
521
507
  const text = new TextDecoder().decode(msg);
@@ -531,14 +517,14 @@ const buildUnisatAdapter = (id, name, provider) => {
531
517
  subscribe(listener) {
532
518
  listenersSet.add(listener);
533
519
  const onAccountsChanged = (...args) => {
534
- const accounts = args[0] ?? [];
520
+ const accounts = toStringArray(args[0]);
535
521
  if (accounts.length === 0) {
536
522
  listener({ type: "disconnected" });
537
523
  return;
538
524
  }
539
525
  const built = accounts.map((a) => buildAccount(a, chain));
540
526
  const first = built[0];
541
- if (!first) return;
527
+ if (first === void 0) return;
542
528
  listener({
543
529
  account: first,
544
530
  accounts: built,
@@ -556,7 +542,7 @@ const buildUnisatAdapter = (id, name, provider) => {
556
542
  listenersSet.delete(listener);
557
543
  };
558
544
  },
559
- switchChain(target) {
545
+ switchChain: (target) => {
560
546
  if (target.namespace !== "bip122") throw new Error(`Bitcoin adapter received non-Bitcoin chain "${target.id}". Pass a chain with namespace "bip122".`);
561
547
  chain = target;
562
548
  refreshChain();
@@ -569,7 +555,9 @@ const buildUnisatAdapter = (id, name, provider) => {
569
555
  //#region src/injected/index.ts
570
556
  const DEFAULT_SETTLE_MS = 150;
571
557
  const readHost = (target) => {
572
- return target === void 0 ? typeof window === "undefined" ? null : window : target;
558
+ if (target !== void 0) return target;
559
+ if (typeof window === "undefined") return null;
560
+ return window;
573
561
  };
574
562
  const probeProviders = (host) => {
575
563
  const adapters = [];
@@ -614,9 +602,9 @@ const discoverInjectedBitcoinAdapter = (onAdapter, options = {}) => {
614
602
  let cancelled = false;
615
603
  const timer = setTimeout(() => {
616
604
  if (cancelled) return;
617
- if (options.hasAnyWalletStandardAdapter?.()) return;
605
+ if (options.hasAnyWalletStandardAdapter?.() === true) return;
618
606
  const host = readHost(options.target);
619
- if (!host) return;
607
+ if (host === null) return;
620
608
  const adapters = probeProviders(host);
621
609
  for (const adapter of adapters) onAdapter(adapter);
622
610
  }, settleMs);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["kitSlugify"],"sources":["../src/capabilities.ts","../src/wallet-standard-adapter.ts","../src/wallet-standard.ts","../src/chains.ts","../src/injected/icon.ts","../src/injected/sats-connect.ts","../src/injected/unisat.ts","../src/injected/index.ts","../src/discoverer.ts"],"sourcesContent":["import type { WalletCapabilities } from \"@usebutr/core\";\n\ntype BitcoinCapabilityInput = {\n chainCount: number;\n features: {\n events: boolean;\n sendTransfer: boolean;\n signMessage: boolean;\n signPsbt: boolean;\n };\n};\n\n/**\n * Bitcoin capability mapping.\n *\n * - `sendTransaction = bitcoin:sendTransfer present`. The wallet handles\n * UTXO selection, fee estimation, signing, and broadcast.\n * - `signTransaction = bitcoin:signPsbt present`. Sign-only PSBT path\n * for consumers that build their own UTXO-shaped transactions with\n * `bitcoinjs-lib` and broadcast through their own provider.\n * - `signMessage = bitcoin:signMessage present`.\n * - `signIn = false`. No Sign-In-With-Bitcoin standard yet (BIP-322 is\n * message-signing oriented, not auth).\n * - `subscribe = events present`. Most Bitcoin wallets don't emit\n * change events portably; capabilities admits the truth.\n * - `switchChain = false`. No portable per-call switch RPC across\n * Bitcoin wallets — Xverse/Unisat/Phantom each pick their own network.\n */\nconst resolveBitcoinCapabilities = (input: BitcoinCapabilityInput): WalletCapabilities => ({\n getBalance: false,\n getTransactionReceipt: false,\n requestAccounts: false,\n sendTransaction: input.features.sendTransfer,\n signIn: false,\n signMessage: input.features.signMessage,\n signTransaction: input.features.signPsbt,\n subscribe: input.features.events,\n switchAccount: false,\n switchChain: input.chainCount > 1,\n});\n\nexport type { BitcoinCapabilityInput };\nexport { resolveBitcoinCapabilities };\n","import type { Account, ChainBase, ConnectorEvent, WalletAdapter } from \"@usebutr/core\";\nimport { logWarn, sanitizeIcon } from \"@usebutr/core\";\nimport {\n buildAccount,\n getFeature,\n pickAccountByAddress,\n pickFirstAddress,\n slugify as kitSlugify,\n} from \"@usebutr/wallet-standard-shared\";\nimport type {\n StandardConnectFeature,\n StandardDisconnectFeature,\n StandardEventsFeature,\n WalletStandardWallet,\n} from \"@usebutr/wallet-standard-shared\";\n\nimport { resolveBitcoinCapabilities } from \"./capabilities\";\nimport type {\n BitcoinSendTransferFeature,\n BitcoinSignMessageFeature,\n BitcoinSignPsbtFeature,\n} from \"./wallet-standard-types\";\n\nconst BITCOIN_PREFIX = \"bip122:\";\nconst BITCOIN_DECIMALS = 8;\nconst BITCOIN_MAINNET_ID = \"bip122:000000000019d6689c085ae165831e93\";\n\nconst slugify = (name: string): string => kitSlugify(\"btc\", name);\n\nconst pickBitcoinChain = (wallet: WalletStandardWallet): string | null => {\n const mainnet = wallet.chains.find((c) => c === BITCOIN_MAINNET_ID);\n if (mainnet) {\n return mainnet;\n }\n return wallet.chains.find((c) => c.startsWith(BITCOIN_PREFIX)) ?? null;\n};\n\nconst buildBitcoinChain = (chainId: string, walletName: string): ChainBase => ({\n id: chainId,\n // Same posture as EVM/SVM/Sui: butr ships no chain-id → name table.\n name: walletName,\n namespace: \"bip122\",\n reference: chainId.slice(BITCOIN_PREFIX.length),\n});\n\nconst buildBitcoinAccount = (address: string, chain: ChainBase): Account =>\n buildAccount(address, chain);\n\n/**\n * Adapt a Bitcoin Wallet Standard `Wallet` into a butr `WalletAdapter`.\n *\n * Returns `null` if the wallet doesn't advertise any `bip122:` chain or\n * doesn't expose `standard:connect`. Same posture as the SVM/Sui\n * adapters: gate features on what each wallet advertises, return\n * placeholders for RPC reads, forward `subscribe` through\n * `standard:events`.\n *\n * **Known limitations**\n *\n * - `getBalance` returns `{ value: 0n, symbol: \"BTC\" }`. Bitcoin\n * balance lookups require an Esplora/Electrum/RPC client outside\n * butr's scope.\n * - `getTransactionReceipt` returns `\"Pending\"` for the same reason.\n * - `sendTx` expects the consumer to pass `{ amount: bigint, recipient: string }`\n * via butr's `unknown` tx parameter — the simplest mental model that\n * maps onto `bitcoin:sendTransfer`. PSBT-shaped flows go through\n * `signTransaction`.\n * - `signTransaction` expects a `Uint8Array` PSBT (raw bytes) — the\n * same shape `bitcoin:signPsbt` accepts. Consumers building with\n * `bitcoinjs-lib` get bytes via `psbt.toBuffer()`.\n * - `switchChain` is local-state-only; the capability flag is `false`\n * when only one chain is advertised. Wallets that ship a real switch\n * primitive (none today, portably) would need their own adapter.\n */\nconst buildBitcoinAdapter = (\n wallet: WalletStandardWallet,\n /** Optional. Called with a function that pushes a synthetic\n * `disconnected` event to all current subscribers. The discovery\n * layer invokes it on Wallet Standard `unregister`. */\n registerDisconnector?: (emit: () => void) => void,\n): WalletAdapter | null => {\n const bitcoinChainId = pickBitcoinChain(wallet);\n if (!bitcoinChainId) {\n return null;\n }\n const connect = getFeature<StandardConnectFeature>(wallet, \"standard:connect\");\n if (!connect) {\n return null;\n }\n\n const disconnect = getFeature<StandardDisconnectFeature>(wallet, \"standard:disconnect\");\n const events = getFeature<StandardEventsFeature>(wallet, \"standard:events\");\n const signMessage = getFeature<BitcoinSignMessageFeature>(wallet, \"bitcoin:signMessage\");\n const signPsbt = getFeature<BitcoinSignPsbtFeature>(wallet, \"bitcoin:signPsbt\");\n const sendTransfer = getFeature<BitcoinSendTransferFeature>(wallet, \"bitcoin:sendTransfer\");\n\n let currentChainId = bitcoinChainId;\n const currentChain = (): ChainBase => buildBitcoinChain(currentChainId, wallet.name);\n\n const listeners = new Set<(event: ConnectorEvent) => void>();\n const notifyAccountChanged = () => {\n if (wallet.accounts.length === 0) {\n return;\n }\n const chain = currentChain();\n const built = wallet.accounts.map((a) => buildBitcoinAccount(a.address, chain));\n const first = built[0];\n if (!first) {\n return;\n }\n for (const listener of listeners) {\n listener({ account: first, accounts: built, type: \"accountChanged\" });\n }\n };\n\n registerDisconnector?.(() => {\n for (const listener of listeners) {\n listener({ type: \"disconnected\" });\n }\n });\n\n return {\n capabilities: resolveBitcoinCapabilities({\n chainCount: wallet.chains.filter((c) => c.startsWith(BITCOIN_PREFIX)).length,\n features: {\n events: Boolean(events),\n sendTransfer: Boolean(sendTransfer),\n signMessage: Boolean(signMessage),\n signPsbt: Boolean(signPsbt),\n },\n }),\n chainPlatform: \"bitcoin\",\n\n async connect(opts) {\n await connect.connect(opts?.silent ? { silent: true } : undefined);\n },\n\n async disconnect() {\n if (disconnect) {\n try {\n await disconnect.disconnect();\n } catch (error) {\n logWarn(\"[butr] Bitcoin Wallet Standard disconnect threw:\", error);\n }\n }\n },\n\n getAccount() {\n const address = pickFirstAddress(wallet.accounts);\n if (!address) {\n return Promise.resolve(null);\n }\n return Promise.resolve(buildBitcoinAccount(address, currentChain()));\n },\n\n getAccounts() {\n const chain = currentChain();\n return Promise.resolve(wallet.accounts.map((a) => buildBitcoinAccount(a.address, chain)));\n },\n\n getBalance() {\n return Promise.resolve({\n decimals: BITCOIN_DECIMALS,\n formatted: \"0\",\n symbol: \"BTC\",\n value: 0n,\n });\n },\n\n getSigner() {\n // Consumers cast to whatever Bitcoin signing wrapper they use\n // (bitcoinjs-lib's Signer, scure-btc-signer's HDWallet, etc.) or\n // call butr's adapter directly for PSBT / send-transfer.\n return Promise.resolve(wallet);\n },\n\n getTransactionReceipt() {\n return Promise.resolve({ status: \"Pending\" as const });\n },\n\n icon: sanitizeIcon(wallet.icon),\n id: slugify(wallet.name),\n name: wallet.name,\n\n async requestAccounts() {\n await connect.connect();\n },\n\n async sendTx(tx, account) {\n if (!sendTransfer) {\n throw new Error(`Wallet ${wallet.name} does not advertise bitcoin:sendTransfer`);\n }\n if (\n !tx ||\n typeof tx !== \"object\" ||\n typeof (tx as { amount?: unknown }).amount !== \"bigint\" ||\n typeof (tx as { recipient?: unknown }).recipient !== \"string\"\n ) {\n throw new TypeError(\n \"Bitcoin sendTx expects { amount: bigint, recipient: string } — pass the recipient address and an amount in satoshis\",\n );\n }\n const { amount, recipient } = tx as { amount: bigint; recipient: string };\n const wsAccount = account\n ? pickAccountByAddress(wallet.accounts, account.walletAddress)\n : (wallet.accounts[0] ?? null);\n if (!wsAccount) {\n throw new Error(\"No connected account\");\n }\n const output = await sendTransfer.sendTransfer({\n account: wsAccount,\n amount,\n chain: currentChainId,\n recipient,\n });\n return output.txid;\n },\n\n sendTxToChain(tx, _targetChainId, account, cb) {\n cb?.();\n return this.sendTx(tx, account);\n },\n\n async signMessage(msg, account) {\n if (!signMessage) {\n throw new Error(`Wallet ${wallet.name} does not advertise bitcoin:signMessage`);\n }\n const wsAccount = account\n ? pickAccountByAddress(wallet.accounts, account.walletAddress)\n : (wallet.accounts[0] ?? null);\n if (!wsAccount) {\n throw new Error(\"No connected account\");\n }\n const output = await signMessage.signMessage({ account: wsAccount, message: msg });\n return { signature: output.signature, signedMessage: output.signedMessage };\n },\n\n ...(signPsbt\n ? {\n async signTransaction(tx, account) {\n const wsAccount = account\n ? pickAccountByAddress(wallet.accounts, account.walletAddress)\n : (wallet.accounts[0] ?? null);\n if (!wsAccount) {\n throw new Error(\"No connected account\");\n }\n if (!(tx instanceof Uint8Array)) {\n throw new TypeError(\n \"Bitcoin signTransaction expects a PSBT as Uint8Array (e.g. psbt.toBuffer())\",\n );\n }\n const output = await signPsbt.signPsbt({\n account: wsAccount,\n chain: currentChainId,\n psbt: tx,\n });\n return output.signedPsbt;\n },\n }\n : {}),\n\n subscribe(listener) {\n listeners.add(listener);\n let unsubWallet: (() => void) | null = null;\n if (events) {\n const unsub = events.on(\"change\", (changes) => {\n if (changes.chains) {\n const next =\n changes.chains.find((c) => c === BITCOIN_MAINNET_ID) ??\n changes.chains.find((c) => c.startsWith(BITCOIN_PREFIX));\n if (next) {\n currentChainId = next;\n }\n }\n\n if (changes.accounts) {\n if (changes.accounts.length === 0) {\n listener({ type: \"disconnected\" });\n return;\n }\n const chain = currentChain();\n const built = changes.accounts.map((a) => buildBitcoinAccount(a.address, chain));\n const first = built[0];\n if (!first) {\n return;\n }\n listener({ account: first, accounts: built, type: \"accountChanged\" });\n return;\n }\n\n if (changes.chains) {\n notifyAccountChanged();\n }\n });\n unsubWallet = () => unsub();\n }\n return () => {\n listeners.delete(listener);\n unsubWallet?.();\n };\n },\n\n switchChain(chain) {\n if (chain.namespace !== \"bip122\") {\n throw new Error(\n `Bitcoin adapter received non-Bitcoin chain \"${chain.id}\". Pass a chain with namespace \"bip122\".`,\n );\n }\n if (!wallet.chains.includes(chain.id)) {\n throw new Error(\n `Wallet ${wallet.name} does not advertise chain \"${chain.id}\". Available: ${wallet.chains.join(\", \")}`,\n );\n }\n currentChainId = chain.id;\n notifyAccountChanged();\n return Promise.resolve();\n },\n };\n};\n\nexport { buildBitcoinAdapter, slugify };\n","import type { WalletAdapter } from \"@usebutr/core\";\nimport { discoverWalletStandard } from \"@usebutr/wallet-standard-shared\";\n\nimport { buildBitcoinAdapter } from \"./wallet-standard-adapter\";\n\n/**\n * Subscribe to Bitcoin Wallet Standard announcements.\n *\n * Phantom (Bitcoin), Magic Eden, OKX Wallet (Bitcoin), and Leather\n * advertise `bitcoin:*` features over the same `getWallets()` bus that\n * SVM and Sui consume. `buildBitcoinAdapter` returns `null` for wallets\n * that don't advertise any `bip122:` chain, so multi-chain wallets\n * (Phantom: EVM + SVM + Sui + Bitcoin) produce one adapter per platform.\n *\n * Requires the **optional peer dependency** `@wallet-standard/app`.\n *\n * The discovery loop (dynamic import, dedupe, register / unregister\n * bridge) lives in `@usebutr/wallet-standard-shared`.\n */\nconst discoverBitcoinAdapters = (onAdapter: (adapter: WalletAdapter) => void): (() => void) =>\n discoverWalletStandard(onAdapter, (wallet, registerDisconnector) =>\n buildBitcoinAdapter(wallet, registerDisconnector),\n );\n\nexport { discoverBitcoinAdapters };\n","import type { ChainBase } from \"@usebutr/core\";\n\n/**\n * CAIP-2 Bitcoin chain references use the first 8 bytes (big-endian)\n * of each network's genesis block hash. These string ids are what\n * Bitcoin Wallet Standard wallets (Phantom, Magic Eden, OKX) advertise\n * in `wallet.chains`; the adapter's `switchChain` rejects anything else.\n *\n * - Mainnet: `bip122:000000000019d6689c085ae165831e93`\n * - Testnet: `bip122:000000000933ea01ad0ee984209779ba`\n * - Signet: `bip122:00000008819873e925422c1ff0f99f7c`\n *\n * Bitcoin has no per-call \"switch chain\" RPC across the major wallets,\n * so butr's adapter treats chain as a wallet-side configuration —\n * `switchChain` updates local state to influence subsequent calls (same\n * posture as SVM). Bitcoin's `switchChain` capability is `false` by\n * default; consumers building on top can opt in if their wallet exposes\n * a switch primitive.\n */\nconst BITCOIN_CHAINS = {\n mainnet: {\n id: \"bip122:000000000019d6689c085ae165831e93\",\n name: \"Bitcoin\",\n namespace: \"bip122\",\n reference: \"000000000019d6689c085ae165831e93\",\n },\n signet: {\n id: \"bip122:00000008819873e925422c1ff0f99f7c\",\n name: \"Bitcoin Signet\",\n namespace: \"bip122\",\n reference: \"00000008819873e925422c1ff0f99f7c\",\n },\n testnet: {\n id: \"bip122:000000000933ea01ad0ee984209779ba\",\n name: \"Bitcoin Testnet\",\n namespace: \"bip122\",\n reference: \"000000000933ea01ad0ee984209779ba\",\n },\n} as const satisfies Record<string, ChainBase>;\n\nconst BITCOIN_CHAINS_LIST: ReadonlyArray<ChainBase> = Object.values(BITCOIN_CHAINS);\n\nexport { BITCOIN_CHAINS, BITCOIN_CHAINS_LIST };\n","/**\n * Generic Bitcoin wallet icon — same purse SVG style as the EVM\n * package, recoloured. Inline so the picker doesn't flash.\n *\n * Lives in its own file because both injected adapters (UniSat-shape\n * and sats-connect) need the same fallback when the wallet doesn't\n * advertise its own icon, and there's no other \"shared\" thing they\n * both want — a one-line module beats a grab-bag.\n */\nconst GENERIC_BITCOIN_ICON =\n \"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2Y3OTMxYSIgc3Ryb2tlPSJub25lIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIvPjx0ZXh0IHg9IjEyIiB5PSIxNyIgZm9udC1mYW1pbHk9InNlcmlmIiBmb250LXNpemU9IjE0IiBmb250LXdlaWdodD0iYm9sZCIgZmlsbD0iI2ZmZiIgdGV4dC1hbmNob3I9Im1pZGRsZSI+QjwvdGV4dD48L3N2Zz4=\";\n\nexport { GENERIC_BITCOIN_ICON };\n","import type { ChainBase, WalletAdapter, WalletCapabilities } from \"@usebutr/core\";\nimport { base64ToBytes, bytesToBase64 } from \"@usebutr/core\";\nimport { buildAccount } from \"@usebutr/wallet-standard-shared\";\n\nimport { BITCOIN_CHAINS } from \"../chains\";\n\nimport { GENERIC_BITCOIN_ICON } from \"./icon\";\n\n/** sats-connect (Xverse) shape — a JSON-RPC-ish `request(method, params)`. */\ntype SatsConnectProvider = {\n request(\n method: string,\n params?: Record<string, unknown>,\n ): Promise<{ error?: { message: string }; result?: unknown }>;\n};\n\nconst CAPS_SATS_CONNECT: WalletCapabilities = {\n getBalance: false,\n getTransactionReceipt: false,\n requestAccounts: true,\n sendTransaction: true,\n signIn: false,\n signMessage: true,\n signTransaction: true,\n subscribe: false,\n switchAccount: false,\n switchChain: false,\n};\n\n/**\n * Wrap an Xverse-style `BitcoinProvider` (sats-connect) into a butr\n * `WalletAdapter`. sats-connect routes everything through a single\n * `request(method, params)` RPC; we shim each butr capability onto the\n * corresponding sats-connect method.\n *\n * Tested against Xverse's `getAccounts`, `signMessage`, `signPsbt`,\n * `sendTransfer` methods.\n */\nconst buildSatsConnectAdapter = (\n id: string,\n name: string,\n provider: SatsConnectProvider,\n): WalletAdapter => {\n let chain: ChainBase = BITCOIN_CHAINS.mainnet;\n let cachedAccounts: ReadonlyArray<string> = [];\n\n const callRequest = async <T>(method: string, params?: Record<string, unknown>): Promise<T> => {\n const response = await provider.request(method, params);\n if (response.error) {\n throw new Error(`[butr/bitcoin] sats-connect ${method} failed: ${response.error.message}`);\n }\n return response.result as T;\n };\n\n const loadAccounts = async (): Promise<ReadonlyArray<string>> => {\n const result = await callRequest<{\n addresses?: ReadonlyArray<{ address: string; purpose?: string }>;\n }>(\"getAccounts\", {\n message: \"Connect to butr\",\n purposes: [\"payment\", \"ordinals\"],\n });\n if (!result?.addresses) {\n return [];\n }\n const addresses = result.addresses.map((a) => a.address);\n cachedAccounts = addresses;\n return addresses;\n };\n\n return {\n capabilities: CAPS_SATS_CONNECT,\n chainPlatform: \"bitcoin\",\n\n async connect() {\n await loadAccounts();\n },\n\n disconnect() {\n cachedAccounts = [];\n return Promise.resolve();\n },\n\n async getAccount() {\n const first = cachedAccounts[0];\n if (first) {\n return buildAccount(first, chain);\n }\n const accounts = await loadAccounts();\n const firstFresh = accounts[0];\n return firstFresh ? buildAccount(firstFresh, chain) : null;\n },\n\n async getAccounts() {\n const accounts = cachedAccounts.length > 0 ? cachedAccounts : await loadAccounts();\n return accounts.map((a) => buildAccount(a, chain));\n },\n\n getBalance() {\n return Promise.resolve({\n decimals: 8,\n formatted: \"0\",\n symbol: \"BTC\",\n value: 0n,\n });\n },\n\n getSigner() {\n return Promise.resolve(provider);\n },\n\n getTransactionReceipt() {\n return Promise.resolve({ status: \"Pending\" as const });\n },\n\n icon: GENERIC_BITCOIN_ICON,\n id,\n name,\n\n async requestAccounts() {\n await loadAccounts();\n },\n\n async sendTx(tx) {\n if (\n !tx ||\n typeof tx !== \"object\" ||\n typeof (tx as { recipient?: unknown }).recipient !== \"string\" ||\n typeof (tx as { amount?: unknown }).amount !== \"bigint\"\n ) {\n throw new TypeError(\n \"Bitcoin sendTx expects { amount: bigint, recipient: string } — amount in satoshis\",\n );\n }\n const { amount, recipient } = tx as { amount: bigint; recipient: string };\n const result = await callRequest<{ txid: string }>(\"sendTransfer\", {\n recipients: [{ address: recipient, amount: amount.toString() }],\n });\n return result.txid;\n },\n\n sendTxToChain(tx, _targetChainId, _account, cb) {\n cb?.();\n return this.sendTx(tx);\n },\n\n async signMessage(msg) {\n const address = cachedAccounts[0];\n if (!address) {\n throw new Error(\"No connected account\");\n }\n const result = await callRequest<{ messageHash?: string; signature: string }>(\"signMessage\", {\n address,\n message: new TextDecoder().decode(msg),\n });\n return { signature: base64ToBytes(result.signature), signedMessage: msg };\n },\n\n async signTransaction(tx) {\n if (!(tx instanceof Uint8Array)) {\n throw new TypeError(\n \"Bitcoin signTransaction expects a PSBT as Uint8Array (e.g. psbt.toBuffer())\",\n );\n }\n // sats-connect's signPsbt takes a base64 PSBT; encode our bytes\n // and decode the response back to bytes.\n const result = await callRequest<{ psbt: string }>(\"signPsbt\", {\n psbt: bytesToBase64(tx),\n });\n return base64ToBytes(result.psbt);\n },\n\n switchChain(target) {\n if (target.namespace !== \"bip122\") {\n throw new Error(\n `Bitcoin adapter received non-Bitcoin chain \"${target.id}\". Pass a chain with namespace \"bip122\".`,\n );\n }\n chain = target;\n return Promise.resolve();\n },\n };\n};\n\nexport type { SatsConnectProvider };\nexport { buildSatsConnectAdapter };\n","import type { ChainBase, ConnectorEvent, WalletAdapter, WalletCapabilities } from \"@usebutr/core\";\nimport { base64ToBytes, bytesToHex, hexToBytes } from \"@usebutr/core\";\nimport { buildAccount } from \"@usebutr/wallet-standard-shared\";\n\nimport { BITCOIN_CHAINS } from \"../chains\";\n\nimport { GENERIC_BITCOIN_ICON } from \"./icon\";\n\n/** UniSat-style provider: a single object on `window.unisat` with the\n * same four methods every UniSat-derivative wallet exposes (UniSat\n * itself, OKX Wallet's Bitcoin path at `window.okxwallet.bitcoin`). */\ntype UnisatProvider = {\n getAccounts(): Promise<ReadonlyArray<string>>;\n getNetwork?(): Promise<\"livenet\" | \"mainnet\" | \"testnet\" | \"signet\">;\n on?(\n event: \"accountsChanged\" | \"networkChanged\",\n listener: (...args: Array<unknown>) => void,\n ): void;\n pushPsbt?(psbtHex: string): Promise<string>;\n removeListener?(\n event: \"accountsChanged\" | \"networkChanged\",\n listener: (...args: Array<unknown>) => void,\n ): void;\n requestAccounts(): Promise<ReadonlyArray<string>>;\n sendBitcoin?(recipient: string, amount: number): Promise<string>;\n signMessage(message: string, type?: \"ecdsa\" | \"bip322-simple\"): Promise<string>;\n signPsbt(psbtHex: string, options?: Record<string, unknown>): Promise<string>;\n};\n\nconst CAPS_UNISAT: WalletCapabilities = {\n getBalance: false,\n getTransactionReceipt: false,\n requestAccounts: true,\n sendTransaction: true,\n signIn: false,\n signMessage: true,\n signTransaction: true,\n subscribe: true,\n switchAccount: false,\n switchChain: false,\n};\n\n/**\n * Wrap a UniSat-style provider (`window.unisat`, `window.okxwallet.bitcoin`,\n * `window.btc`) into a butr `WalletAdapter`.\n *\n * The UniSat shape is consistent enough that one adapter handles every\n * derivative. Differences (network names, `sendBitcoin` presence) are\n * gated by feature detection per call.\n */\nconst buildUnisatAdapter = (id: string, name: string, provider: UnisatProvider): WalletAdapter => {\n let chain: ChainBase = BITCOIN_CHAINS.mainnet;\n const listenersSet = new Set<(event: ConnectorEvent) => void>();\n\n const refreshChain = async () => {\n if (typeof provider.getNetwork !== \"function\") {\n return;\n }\n try {\n const network = await provider.getNetwork();\n if (network === \"testnet\") {\n chain = BITCOIN_CHAINS.testnet;\n } else if (network === \"signet\") {\n chain = BITCOIN_CHAINS.signet;\n } else {\n chain = BITCOIN_CHAINS.mainnet;\n }\n } catch {\n // Network probe failed — keep the current chain. The next call\n // will retry through whichever path next invokes refreshChain.\n }\n };\n\n return {\n capabilities: CAPS_UNISAT,\n chainPlatform: \"bitcoin\",\n\n async connect(opts) {\n if (opts?.silent) {\n const accounts = await provider.getAccounts();\n if (accounts.length === 0) {\n throw new Error(\"No authorized accounts for silent reconnect\");\n }\n await refreshChain();\n return;\n }\n await provider.requestAccounts();\n await refreshChain();\n },\n\n disconnect() {\n // No portable disconnect across UniSat-shaped wallets. butr's\n // reducer marks the wallet disconnected on its side regardless.\n return Promise.resolve();\n },\n\n async getAccount() {\n const accounts = await provider.getAccounts();\n const first = accounts[0];\n if (!first) {\n return null;\n }\n await refreshChain();\n return buildAccount(first, chain);\n },\n\n async getAccounts() {\n const accounts = await provider.getAccounts();\n if (accounts.length === 0) {\n return [];\n }\n await refreshChain();\n return accounts.map((a) => buildAccount(a, chain));\n },\n\n getBalance() {\n return Promise.resolve({\n decimals: 8,\n formatted: \"0\",\n symbol: \"BTC\",\n value: 0n,\n });\n },\n\n getSigner() {\n return Promise.resolve(provider);\n },\n\n getTransactionReceipt() {\n return Promise.resolve({ status: \"Pending\" as const });\n },\n\n icon: GENERIC_BITCOIN_ICON,\n id,\n name,\n\n async requestAccounts() {\n await provider.requestAccounts();\n await refreshChain();\n },\n\n sendTx(tx) {\n if (typeof provider.sendBitcoin !== \"function\") {\n throw new TypeError(`Wallet ${name} does not expose sendBitcoin`);\n }\n if (\n !tx ||\n typeof tx !== \"object\" ||\n typeof (tx as { recipient?: unknown }).recipient !== \"string\" ||\n typeof (tx as { amount?: unknown }).amount !== \"bigint\"\n ) {\n throw new TypeError(\n \"Bitcoin sendTx expects { amount: bigint, recipient: string } — amount in satoshis\",\n );\n }\n const { amount, recipient } = tx as { amount: bigint; recipient: string };\n // UniSat's sendBitcoin takes a JS number for satoshis. Values\n // above 2^53 aren't representable; that's 90+ million BTC, which\n // would never appear in practice.\n const sats = Number(amount);\n return provider.sendBitcoin(recipient, sats);\n },\n\n sendTxToChain(tx, _targetChainIdDecimal, _account, cb) {\n cb?.();\n return this.sendTx(tx);\n },\n\n async signMessage(msg) {\n // UniSat takes a UTF-8 message and returns a base64 signature.\n // We return the raw signature bytes (decoded from base64) and the\n // bytes the wallet signed (pass-through of the input). UniSat\n // doesn't expose a \"pre-image\" so the input itself is the signed\n // message from butr's perspective.\n const text = new TextDecoder().decode(msg);\n const signatureB64 = await provider.signMessage(text);\n return { signature: base64ToBytes(signatureB64), signedMessage: msg };\n },\n\n async signTransaction(tx) {\n if (!(tx instanceof Uint8Array)) {\n throw new TypeError(\n \"Bitcoin signTransaction expects a PSBT as Uint8Array (e.g. psbt.toBuffer())\",\n );\n }\n const signedHex = await provider.signPsbt(bytesToHex(tx));\n return hexToBytes(signedHex);\n },\n\n subscribe(listener) {\n listenersSet.add(listener);\n const onAccountsChanged = (...args: ReadonlyArray<unknown>) => {\n const accounts = (args[0] as ReadonlyArray<string> | undefined) ?? [];\n if (accounts.length === 0) {\n listener({ type: \"disconnected\" });\n return;\n }\n const built = accounts.map((a) => buildAccount(a, chain));\n const first = built[0];\n if (!first) {\n return;\n }\n listener({ account: first, accounts: built, type: \"accountChanged\" });\n };\n const onNetworkChanged = () => {\n void refreshChain();\n };\n provider.on?.(\"accountsChanged\", onAccountsChanged);\n provider.on?.(\"networkChanged\", onNetworkChanged);\n return () => {\n provider.removeListener?.(\"accountsChanged\", onAccountsChanged);\n provider.removeListener?.(\"networkChanged\", onNetworkChanged);\n listenersSet.delete(listener);\n };\n },\n\n switchChain(target) {\n if (target.namespace !== \"bip122\") {\n throw new Error(\n `Bitcoin adapter received non-Bitcoin chain \"${target.id}\". Pass a chain with namespace \"bip122\".`,\n );\n }\n // UniSat-shaped wallets pick their network via the user's\n // extension UI; we update local state so consumers see it, but\n // the wallet itself doesn't switch.\n chain = target;\n void refreshChain();\n return Promise.resolve();\n },\n };\n};\n\nexport type { UnisatProvider };\nexport { buildUnisatAdapter };\n","import type { WalletAdapter } from \"@usebutr/core\";\n\nimport { GENERIC_BITCOIN_ICON } from \"./icon\";\nimport type { SatsConnectProvider } from \"./sats-connect\";\nimport { buildSatsConnectAdapter } from \"./sats-connect\";\nimport type { UnisatProvider } from \"./unisat\";\nimport { buildUnisatAdapter } from \"./unisat\";\n\nconst DEFAULT_SETTLE_MS = 150;\n\ntype InjectedHost = {\n btc?: UnisatProvider;\n okxwallet?: { bitcoin?: UnisatProvider };\n unisat?: UnisatProvider;\n XverseProviders?: { BitcoinProvider?: SatsConnectProvider };\n};\n\ntype InjectedBitcoinDiscoveryOptions = {\n /** Suppresses emission when Wallet Standard discovery has already\n * registered a Bitcoin adapter for the same browser session. */\n hasAnyWalletStandardAdapter?: () => boolean;\n /** Settle deadline in ms before the fallback fires. Same default and\n * intent as the EVM injected fallback. */\n settleMs?: number;\n /** Override the global host (tests, iframes). */\n target?: InjectedHost | null;\n};\n\nconst readHost = (target: InjectedBitcoinDiscoveryOptions[\"target\"]): InjectedHost | null => {\n const globalWindow = typeof window === \"undefined\" ? null : (window as unknown as InjectedHost);\n return target === undefined ? globalWindow : target;\n};\n\nconst probeProviders = (host: InjectedHost): Array<WalletAdapter> => {\n const adapters: Array<WalletAdapter> = [];\n const seen = new Set<UnisatProvider | SatsConnectProvider>();\n\n if (host.unisat && !seen.has(host.unisat)) {\n seen.add(host.unisat);\n adapters.push(buildUnisatAdapter(\"injected:bitcoin:unisat\", \"Unisat\", host.unisat));\n }\n\n const okxBitcoin = host.okxwallet?.bitcoin;\n if (okxBitcoin && !seen.has(okxBitcoin)) {\n seen.add(okxBitcoin);\n adapters.push(buildUnisatAdapter(\"injected:bitcoin:okx\", \"OKX Wallet (Bitcoin)\", okxBitcoin));\n }\n\n const xverse = host.XverseProviders?.BitcoinProvider;\n if (xverse && !seen.has(xverse)) {\n seen.add(xverse);\n adapters.push(buildSatsConnectAdapter(\"injected:bitcoin:xverse\", \"Xverse\", xverse));\n }\n\n if (host.btc && !seen.has(host.btc)) {\n seen.add(host.btc);\n adapters.push(\n buildUnisatAdapter(\"injected:bitcoin:legacy\", \"Browser Bitcoin wallet\", host.btc),\n );\n }\n\n return adapters;\n};\n\n/**\n * Last-resort discovery path for Bitcoin wallets that DON'T announce via\n * Wallet Standard. Probes, in order: `window.unisat`,\n * `window.okxwallet.bitcoin`, `window.XverseProviders.BitcoinProvider`,\n * `window.btc`.\n *\n * Wallet Standard wallets (Phantom, Magic Eden, Leather, modern OKX\n * builds) are already handled by `discoverBitcoinAdapters`. This\n * fallback waits `settleMs` (default 150ms), consults\n * `hasAnyWalletStandardAdapter` if provided, and emits adapters for\n * any injected providers that weren't already covered.\n *\n * Each emitted adapter has a stable id prefix (`injected:bitcoin:*`)\n * so consumers can distinguish them in the picker UI.\n */\nconst discoverInjectedBitcoinAdapter = (\n onAdapter: (adapter: WalletAdapter) => void,\n options: InjectedBitcoinDiscoveryOptions = {},\n): (() => void) => {\n const settleMs = options.settleMs ?? DEFAULT_SETTLE_MS;\n let cancelled = false;\n const timer = setTimeout(() => {\n if (cancelled) {\n return;\n }\n if (options.hasAnyWalletStandardAdapter?.()) {\n return;\n }\n const host = readHost(options.target);\n if (!host) {\n return;\n }\n const adapters = probeProviders(host);\n for (const adapter of adapters) {\n onAdapter(adapter);\n }\n }, settleMs);\n\n return () => {\n cancelled = true;\n clearTimeout(timer);\n };\n};\n\nexport type { InjectedBitcoinDiscoveryOptions };\nexport { GENERIC_BITCOIN_ICON, discoverInjectedBitcoinAdapter };\n","import type { PlatformDiscoverer } from \"@usebutr/core\";\n\nimport { discoverInjectedBitcoinAdapter } from \"./injected\";\nimport { discoverBitcoinAdapters } from \"./wallet-standard\";\n\n/**\n * Bitcoin's `PlatformDiscoverer`: Wallet Standard primary (Phantom,\n * Magic Eden, Leather, OKX); legacy fallback covers sats-connect\n * (Xverse), `window.unisat`, OKX legacy, and `window.btc`. The\n * fallback defers to Wallet Standard via `hasAnyPrimaryAdapter`.\n */\nconst bitcoinDiscoverer: PlatformDiscoverer = {\n fallback: {\n subscribe: (onAdapter, opts) =>\n discoverInjectedBitcoinAdapter(onAdapter, {\n hasAnyWalletStandardAdapter: opts.hasAnyPrimaryAdapter,\n }),\n },\n platform: \"bitcoin\",\n subscribe: discoverBitcoinAdapters,\n};\n\nexport { bitcoinDiscoverer };\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["kitSlugify"],"sources":["../src/capabilities.ts","../src/wallet-standard-adapter.ts","../src/wallet-standard.ts","../src/chains.ts","../src/injected/icon.ts","../src/injected/sats-connect.ts","../src/injected/unisat.ts","../src/injected/index.ts","../src/discoverer.ts"],"sourcesContent":["import type { WalletCapabilities } from \"@usebutr/core\";\n\ntype BitcoinCapabilityInput = {\n chainCount: number;\n features: {\n events: boolean;\n sendTransfer: boolean;\n signMessage: boolean;\n signPsbt: boolean;\n };\n};\n\n/**\n * Bitcoin capability mapping.\n *\n * - `sendTransaction = bitcoin:sendTransfer present`. The wallet handles\n * UTXO selection, fee estimation, signing, and broadcast.\n * - `signTransaction = bitcoin:signPsbt present`. Sign-only PSBT path\n * for consumers that build their own UTXO-shaped transactions with\n * `bitcoinjs-lib` and broadcast through their own provider.\n * - `signMessage = bitcoin:signMessage present`.\n * - `signIn = false`. No Sign-In-With-Bitcoin standard yet (BIP-322 is\n * message-signing oriented, not auth).\n * - `subscribe = events present`. Most Bitcoin wallets don't emit\n * change events portably; capabilities admits the truth.\n * - `switchChain = chainCount > 1`. No portable switch RPC across\n * Bitcoin wallets (Xverse/Unisat/Phantom each pick their own\n * network), so the switch is local-state-only and advertised only\n * when the wallet exposes more than one chain to switch between.\n */\nconst resolveBitcoinCapabilities = (input: BitcoinCapabilityInput): WalletCapabilities => ({\n getBalance: false,\n getTransactionReceipt: false,\n requestAccounts: false,\n sendTransaction: input.features.sendTransfer,\n signIn: false,\n signMessage: input.features.signMessage,\n signTransaction: input.features.signPsbt,\n subscribe: input.features.events,\n switchAccount: false,\n switchChain: input.chainCount > 1,\n});\n\nexport type { BitcoinCapabilityInput };\nexport { resolveBitcoinCapabilities };\n","import type { ChainBase, ConnectorEvent, WalletAdapter } from \"@usebutr/core\";\nimport { logWarn, sanitizeIcon } from \"@usebutr/core\";\nimport {\n buildAccount,\n getFeature,\n pickAccountByAddress,\n pickFirstAddress,\n slugify as kitSlugify,\n} from \"@usebutr/wallet-standard-shared\";\nimport type {\n StandardConnectFeature,\n StandardDisconnectFeature,\n StandardEventsFeature,\n WalletStandardWallet,\n} from \"@usebutr/wallet-standard-shared\";\n\nimport { resolveBitcoinCapabilities } from \"./capabilities\";\nimport type {\n BitcoinSendTransferFeature,\n BitcoinSignMessageFeature,\n BitcoinSignPsbtFeature,\n} from \"./wallet-standard-types\";\n\nconst BITCOIN_PREFIX = \"bip122:\";\nconst BITCOIN_DECIMALS = 8;\nconst BITCOIN_MAINNET_ID = \"bip122:000000000019d6689c085ae165831e93\";\n\nconst slugify = (name: string): string => kitSlugify(\"btc\", name);\n\nconst pickBitcoinChain = (wallet: WalletStandardWallet): string | null => {\n const mainnet = wallet.chains.find((c) => c === BITCOIN_MAINNET_ID);\n if (mainnet) {\n return mainnet;\n }\n return wallet.chains.find((c) => c.startsWith(BITCOIN_PREFIX)) ?? null;\n};\n\nconst buildBitcoinChain = (chainId: string, walletName: string): ChainBase => ({\n id: chainId,\n name: walletName,\n namespace: \"bip122\",\n reference: chainId.slice(BITCOIN_PREFIX.length),\n});\n\n/**\n * Adapt a Bitcoin Wallet Standard `Wallet` into a butr `WalletAdapter`.\n *\n * Returns `null` if the wallet doesn't advertise any `bip122:` chain or\n * doesn't expose `standard:connect`. Same posture as the SVM/Sui\n * adapters: gate features on what each wallet advertises, return\n * placeholders for RPC reads, forward `subscribe` through\n * `standard:events`.\n *\n * **Known limitations**\n *\n * - `getBalance` returns `{ value: 0n, symbol: \"BTC\" }`. Bitcoin\n * balance lookups require an Esplora/Electrum/RPC client outside\n * butr's scope.\n * - `getTransactionReceipt` returns `\"Pending\"` for the same reason.\n * - `sendTx` expects the consumer to pass `{ amount: bigint, recipient: string }`\n * via butr's `unknown` tx parameter; the simplest mental model that\n * maps onto `bitcoin:sendTransfer`. PSBT-shaped flows go through\n * `signTransaction`.\n * - `signTransaction` expects a `Uint8Array` PSBT (raw bytes); the\n * same shape `bitcoin:signPsbt` accepts. Consumers building with\n * `bitcoinjs-lib` get bytes via `psbt.toBuffer()`.\n * - `switchChain` is local-state-only; the capability flag is `false`\n * when only one chain is advertised. Wallets that ship a real switch\n * primitive (none today, portably) would need their own adapter.\n */\nconst buildBitcoinAdapter = (\n wallet: WalletStandardWallet,\n /** Optional. Called with a function that pushes a synthetic\n * `disconnected` event to all current subscribers. The discovery\n * layer invokes it on Wallet Standard `unregister`. */\n registerDisconnector?: (emit: () => void) => void,\n): WalletAdapter | null => {\n const bitcoinChainId = pickBitcoinChain(wallet);\n if (bitcoinChainId === null) {\n return null;\n }\n const connect = getFeature<StandardConnectFeature>(wallet, \"standard:connect\");\n if (connect === undefined) {\n return null;\n }\n\n const disconnect = getFeature<StandardDisconnectFeature>(wallet, \"standard:disconnect\");\n const events = getFeature<StandardEventsFeature>(wallet, \"standard:events\");\n const signMessage = getFeature<BitcoinSignMessageFeature>(wallet, \"bitcoin:signMessage\");\n const signPsbt = getFeature<BitcoinSignPsbtFeature>(wallet, \"bitcoin:signPsbt\");\n const sendTransfer = getFeature<BitcoinSendTransferFeature>(wallet, \"bitcoin:sendTransfer\");\n\n let currentChainId = bitcoinChainId;\n const currentChain = (): ChainBase => buildBitcoinChain(currentChainId, wallet.name);\n\n const listeners = new Set<(event: ConnectorEvent) => void>();\n const notifyAccountChanged = () => {\n if (wallet.accounts.length === 0) {\n return;\n }\n const chain = currentChain();\n const built = wallet.accounts.map((a) => buildAccount(a.address, chain));\n const first = built[0];\n if (first === undefined) {\n return;\n }\n for (const listener of listeners) {\n listener({ account: first, accounts: built, type: \"accountChanged\" });\n }\n };\n\n registerDisconnector?.(() => {\n for (const listener of listeners) {\n listener({ type: \"disconnected\" });\n }\n });\n\n const sendTransferTx = async (\n tx: unknown,\n account?: { walletAddress: string },\n ): Promise<string> => {\n if (sendTransfer === undefined) {\n throw new Error(`Wallet ${wallet.name} does not advertise bitcoin:sendTransfer`);\n }\n if (\n typeof tx !== \"object\" ||\n tx === null ||\n !(\"amount\" in tx) ||\n typeof tx.amount !== \"bigint\" ||\n !(\"recipient\" in tx) ||\n typeof tx.recipient !== \"string\"\n ) {\n throw new TypeError(\n \"Bitcoin sendTx expects { amount: bigint, recipient: string }: pass the recipient address and an amount in satoshis\",\n );\n }\n const { amount, recipient } = tx;\n const wsAccount = account\n ? pickAccountByAddress(wallet.accounts, account.walletAddress)\n : wallet.accounts[0];\n if (wsAccount === undefined) {\n throw new Error(\"No connected account\");\n }\n const output = await sendTransfer.sendTransfer({\n account: wsAccount,\n amount,\n chain: currentChainId,\n recipient,\n });\n return output.txid;\n };\n\n return {\n capabilities: resolveBitcoinCapabilities({\n chainCount: wallet.chains.filter((c) => c.startsWith(BITCOIN_PREFIX)).length,\n features: {\n events: Boolean(events),\n sendTransfer: Boolean(sendTransfer),\n signMessage: Boolean(signMessage),\n signPsbt: Boolean(signPsbt),\n },\n }),\n chainPlatform: \"bitcoin\",\n\n async connect(opts) {\n await connect.connect(opts?.silent === true ? { silent: true } : undefined);\n },\n\n async disconnect() {\n if (disconnect !== undefined) {\n try {\n await disconnect.disconnect();\n } catch (error) {\n logWarn(\"[butr] Bitcoin Wallet Standard disconnect threw:\", error);\n }\n }\n },\n\n getAccount: () => {\n const address = pickFirstAddress(wallet.accounts);\n if (address === null) {\n return Promise.resolve(null);\n }\n return Promise.resolve(buildAccount(address, currentChain()));\n },\n\n getAccounts: () => {\n const chain = currentChain();\n return Promise.resolve(wallet.accounts.map((a) => buildAccount(a.address, chain)));\n },\n\n getBalance: () =>\n Promise.resolve({\n decimals: BITCOIN_DECIMALS,\n formatted: \"0\",\n symbol: \"BTC\",\n value: 0n,\n }),\n\n // Consumers wrap this in whatever Bitcoin signing library they use\n // (bitcoinjs-lib's Signer, scure-btc-signer's HDWallet, etc.) or\n // call butr's adapter directly for PSBT / send-transfer.\n getSigner: () => Promise.resolve(wallet),\n\n getTransactionReceipt: () => Promise.resolve({ status: \"Pending\" as const }),\n\n icon: sanitizeIcon(wallet.icon),\n id: slugify(wallet.name),\n name: wallet.name,\n\n async requestAccounts() {\n await connect.connect();\n },\n\n sendTx: (tx, account) => sendTransferTx(tx, account),\n\n sendTxToChain: (tx, _targetChainId, account, cb) => {\n cb?.();\n return sendTransferTx(tx, account);\n },\n\n async signMessage(msg, account) {\n if (signMessage === undefined) {\n throw new Error(`Wallet ${wallet.name} does not advertise bitcoin:signMessage`);\n }\n const wsAccount = account\n ? pickAccountByAddress(wallet.accounts, account.walletAddress)\n : wallet.accounts[0];\n if (wsAccount === undefined) {\n throw new Error(\"No connected account\");\n }\n const output = await signMessage.signMessage({ account: wsAccount, message: msg });\n return { signature: output.signature, signedMessage: output.signedMessage };\n },\n\n ...(signPsbt === undefined\n ? {}\n : {\n async signTransaction(tx, account) {\n const wsAccount = account\n ? pickAccountByAddress(wallet.accounts, account.walletAddress)\n : wallet.accounts[0];\n if (wsAccount === undefined) {\n throw new Error(\"No connected account\");\n }\n if (!(tx instanceof Uint8Array)) {\n throw new TypeError(\n \"Bitcoin signTransaction expects a PSBT as Uint8Array (e.g. psbt.toBuffer())\",\n );\n }\n const output = await signPsbt.signPsbt({\n account: wsAccount,\n chain: currentChainId,\n psbt: tx,\n });\n return output.signedPsbt;\n },\n }),\n\n subscribe(listener) {\n listeners.add(listener);\n let unsubWallet: (() => void) | null = null;\n if (events !== undefined) {\n const unsub = events.on(\"change\", (changes) => {\n if (changes.chains !== undefined) {\n const next =\n changes.chains.find((c) => c === BITCOIN_MAINNET_ID) ??\n changes.chains.find((c) => c.startsWith(BITCOIN_PREFIX));\n if (next !== undefined) {\n currentChainId = next;\n }\n }\n\n if (changes.accounts !== undefined) {\n if (changes.accounts.length === 0) {\n listener({ type: \"disconnected\" });\n return;\n }\n const chain = currentChain();\n const built = changes.accounts.map((a) => buildAccount(a.address, chain));\n const first = built[0];\n if (first === undefined) {\n return;\n }\n listener({ account: first, accounts: built, type: \"accountChanged\" });\n return;\n }\n\n if (changes.chains !== undefined) {\n notifyAccountChanged();\n }\n });\n unsubWallet = () => {\n unsub();\n };\n }\n return () => {\n listeners.delete(listener);\n unsubWallet?.();\n };\n },\n\n switchChain: (chain) => {\n if (chain.namespace !== \"bip122\") {\n throw new Error(\n `Bitcoin adapter received non-Bitcoin chain \"${chain.id}\". Pass a chain with namespace \"bip122\".`,\n );\n }\n if (!wallet.chains.includes(chain.id)) {\n throw new Error(\n `Wallet ${wallet.name} does not advertise chain \"${chain.id}\". Available: ${wallet.chains.join(\", \")}`,\n );\n }\n currentChainId = chain.id;\n notifyAccountChanged();\n return Promise.resolve();\n },\n };\n};\n\nexport { buildBitcoinAdapter, slugify };\n","import type { WalletAdapter } from \"@usebutr/core\";\nimport { discoverWalletStandard } from \"@usebutr/wallet-standard-shared\";\n\nimport { buildBitcoinAdapter } from \"./wallet-standard-adapter\";\n\n/**\n * Subscribe to Bitcoin Wallet Standard announcements.\n *\n * Phantom (Bitcoin), Magic Eden, OKX Wallet (Bitcoin), and Leather\n * advertise `bitcoin:*` features over the same `getWallets()` bus that\n * SVM and Sui consume. `buildBitcoinAdapter` returns `null` for wallets\n * that don't advertise any `bip122:` chain, so multi-chain wallets\n * (Phantom: EVM + SVM + Sui + Bitcoin) produce one adapter per platform.\n *\n * Requires the **optional peer dependency** `@wallet-standard/app`.\n *\n * The discovery loop (dynamic import, dedupe, register / unregister\n * bridge) lives in `@usebutr/wallet-standard-shared`.\n */\nconst discoverBitcoinAdapters = (onAdapter: (adapter: WalletAdapter) => void): (() => void) =>\n discoverWalletStandard(onAdapter, (wallet, registerDisconnector) =>\n buildBitcoinAdapter(wallet, registerDisconnector),\n );\n\nexport { discoverBitcoinAdapters };\n","import type { ChainBase } from \"@usebutr/core\";\n\n/**\n * CAIP-2 Bitcoin chain references use the first 8 bytes (big-endian)\n * of each network's genesis block hash. These string ids are what\n * Bitcoin Wallet Standard wallets (Phantom, Magic Eden, OKX) advertise\n * in `wallet.chains`; the adapter's `switchChain` rejects anything else.\n *\n * - Mainnet: `bip122:000000000019d6689c085ae165831e93`\n * - Testnet: `bip122:000000000933ea01ad0ee984209779ba`\n * - Signet: `bip122:00000008819873e925422c1ff0f99f7c`\n *\n * Bitcoin has no per-call \"switch chain\" RPC across the major wallets,\n * so butr's adapter treats chain as a wallet-side configuration;\n * `switchChain` updates local state to influence subsequent calls (same\n * posture as SVM). Bitcoin's `switchChain` capability is `false` by\n * default; consumers building on top can opt in if their wallet exposes\n * a switch primitive.\n */\nconst BITCOIN_CHAINS = {\n mainnet: {\n id: \"bip122:000000000019d6689c085ae165831e93\",\n name: \"Bitcoin\",\n namespace: \"bip122\",\n reference: \"000000000019d6689c085ae165831e93\",\n },\n signet: {\n id: \"bip122:00000008819873e925422c1ff0f99f7c\",\n name: \"Bitcoin Signet\",\n namespace: \"bip122\",\n reference: \"00000008819873e925422c1ff0f99f7c\",\n },\n testnet: {\n id: \"bip122:000000000933ea01ad0ee984209779ba\",\n name: \"Bitcoin Testnet\",\n namespace: \"bip122\",\n reference: \"000000000933ea01ad0ee984209779ba\",\n },\n} as const satisfies Record<string, ChainBase>;\n\nconst BITCOIN_CHAINS_LIST: ReadonlyArray<ChainBase> = Object.values(BITCOIN_CHAINS);\n\nexport { BITCOIN_CHAINS, BITCOIN_CHAINS_LIST };\n","/**\n * Generic Bitcoin wallet icon, same purse SVG style as the EVM\n * package, recoloured. Inline so the picker doesn't flash.\n *\n * Lives in its own file because both injected adapters (UniSat-shape\n * and sats-connect) need the same fallback when the wallet doesn't\n * advertise its own icon, and there's no other \"shared\" thing they\n * both want; a one-line module beats a grab-bag.\n */\nconst GENERIC_BITCOIN_ICON =\n \"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2Y3OTMxYSIgc3Ryb2tlPSJub25lIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIvPjx0ZXh0IHg9IjEyIiB5PSIxNyIgZm9udC1mYW1pbHk9InNlcmlmIiBmb250LXNpemU9IjE0IiBmb250LXdlaWdodD0iYm9sZCIgZmlsbD0iI2ZmZiIgdGV4dC1hbmNob3I9Im1pZGRsZSI+QjwvdGV4dD48L3N2Zz4=\";\n\nexport { GENERIC_BITCOIN_ICON };\n","import type { ChainBase, WalletAdapter, WalletCapabilities } from \"@usebutr/core\";\nimport { base64ToBytes, bytesToBase64 } from \"@usebutr/core\";\nimport { buildAccount } from \"@usebutr/wallet-standard-shared\";\n\nimport { BITCOIN_CHAINS } from \"../chains\";\n\nimport { GENERIC_BITCOIN_ICON } from \"./icon\";\n\n/** sats-connect (Xverse) shape; a JSON-RPC-ish `request(method, params)`. */\ntype SatsConnectProvider = {\n request: (\n method: string,\n params?: Record<string, unknown>,\n ) => Promise<{ error?: { message: string }; result?: unknown }>;\n};\n\nconst CAPS_SATS_CONNECT: WalletCapabilities = {\n getBalance: false,\n getTransactionReceipt: false,\n requestAccounts: true,\n sendTransaction: true,\n signIn: false,\n signMessage: true,\n signTransaction: true,\n subscribe: false,\n switchAccount: false,\n switchChain: false,\n};\n\n/**\n * Wrap an Xverse-style `BitcoinProvider` (sats-connect) into a butr\n * `WalletAdapter`. sats-connect routes everything through a single\n * `request(method, params)` RPC; we shim each butr capability onto the\n * corresponding sats-connect method.\n *\n * Tested against Xverse's `getAccounts`, `signMessage`, `signPsbt`,\n * `sendTransfer` methods.\n */\nconst buildSatsConnectAdapter = (\n id: string,\n name: string,\n provider: SatsConnectProvider,\n): WalletAdapter => {\n let chain: ChainBase = BITCOIN_CHAINS.mainnet;\n let cachedAccounts: ReadonlyArray<string> = [];\n\n // oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- caller-supplied result shape for an untyped RPC bridge\n const callRequest = async <T>(method: string, params?: Record<string, unknown>): Promise<T> => {\n const response = await provider.request(method, params);\n if (response.error) {\n throw new Error(`[butr/bitcoin] sats-connect ${method} failed: ${response.error.message}`);\n }\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- untyped sats-connect RPC result; caller declares the shape\n return response.result as T;\n };\n\n const loadAccounts = async (): Promise<ReadonlyArray<string>> => {\n // `callRequest` only asserts the caller's shape onto an untyped RPC\n // payload, so a wallet that answers without a `result` lands here as\n // null/undefined and has to be read through an optional chain.\n const result = await callRequest<{\n addresses?: ReadonlyArray<{ address: string; purpose?: string }>;\n } | null>(\"getAccounts\", {\n message: \"Connect to butr\",\n purposes: [\"payment\", \"ordinals\"],\n });\n if (result?.addresses === undefined) {\n return [];\n }\n const addresses = result.addresses.map((a) => a.address);\n cachedAccounts = addresses;\n return addresses;\n };\n\n const sendTransferTx = async (tx: unknown): Promise<string> => {\n if (\n typeof tx !== \"object\" ||\n tx === null ||\n !(\"recipient\" in tx) ||\n typeof tx.recipient !== \"string\" ||\n !(\"amount\" in tx) ||\n typeof tx.amount !== \"bigint\"\n ) {\n throw new TypeError(\n \"Bitcoin sendTx expects { amount: bigint, recipient: string }: amount in satoshis\",\n );\n }\n const { amount, recipient } = tx;\n const result = await callRequest<{ txid: string }>(\"sendTransfer\", {\n recipients: [{ address: recipient, amount: amount.toString() }],\n });\n return result.txid;\n };\n\n return {\n capabilities: CAPS_SATS_CONNECT,\n chainPlatform: \"bitcoin\",\n\n async connect() {\n await loadAccounts();\n },\n\n disconnect: () => {\n cachedAccounts = [];\n return Promise.resolve();\n },\n\n async getAccount() {\n const first = cachedAccounts[0];\n if (first !== undefined) {\n return buildAccount(first, chain);\n }\n const accounts = await loadAccounts();\n const firstFresh = accounts[0];\n return firstFresh === undefined ? null : buildAccount(firstFresh, chain);\n },\n\n async getAccounts() {\n const accounts = cachedAccounts.length > 0 ? cachedAccounts : await loadAccounts();\n return accounts.map((a) => buildAccount(a, chain));\n },\n\n getBalance: () =>\n Promise.resolve({\n decimals: 8,\n formatted: \"0\",\n symbol: \"BTC\",\n value: 0n,\n }),\n\n getSigner: () => Promise.resolve(provider),\n\n getTransactionReceipt: () => Promise.resolve({ status: \"Pending\" as const }),\n\n icon: GENERIC_BITCOIN_ICON,\n id,\n name,\n\n async requestAccounts() {\n await loadAccounts();\n },\n\n sendTx: (tx) => sendTransferTx(tx),\n\n sendTxToChain: (tx, _targetChainId, _account, cb) => {\n cb?.();\n return sendTransferTx(tx);\n },\n\n async signMessage(msg) {\n const address = cachedAccounts[0];\n if (address === undefined) {\n throw new Error(\"No connected account\");\n }\n const result = await callRequest<{ messageHash?: string; signature: string }>(\"signMessage\", {\n address,\n message: new TextDecoder().decode(msg),\n });\n return { signature: base64ToBytes(result.signature), signedMessage: msg };\n },\n\n async signTransaction(tx) {\n if (!(tx instanceof Uint8Array)) {\n throw new TypeError(\n \"Bitcoin signTransaction expects a PSBT as Uint8Array (e.g. psbt.toBuffer())\",\n );\n }\n // sats-connect's signPsbt takes a base64 PSBT; encode our bytes\n // and decode the response back to bytes.\n const result = await callRequest<{ psbt: string }>(\"signPsbt\", {\n psbt: bytesToBase64(tx),\n });\n return base64ToBytes(result.psbt);\n },\n\n switchChain: (target) => {\n if (target.namespace !== \"bip122\") {\n throw new Error(\n `Bitcoin adapter received non-Bitcoin chain \"${target.id}\". Pass a chain with namespace \"bip122\".`,\n );\n }\n chain = target;\n return Promise.resolve();\n },\n };\n};\n\nexport type { SatsConnectProvider };\nexport { buildSatsConnectAdapter };\n","import type { ChainBase, ConnectorEvent, WalletAdapter, WalletCapabilities } from \"@usebutr/core\";\nimport { base64ToBytes, bytesToHex, hexToBytes } from \"@usebutr/core\";\nimport { buildAccount } from \"@usebutr/wallet-standard-shared\";\n\nimport { BITCOIN_CHAINS } from \"../chains\";\n\nimport { GENERIC_BITCOIN_ICON } from \"./icon\";\n\n/** UniSat-style provider: a single object on `window.unisat` with the\n * same four methods every UniSat-derivative wallet exposes (UniSat\n * itself, OKX Wallet's Bitcoin path at `window.okxwallet.bitcoin`). */\ntype UnisatProvider = {\n getAccounts: () => Promise<ReadonlyArray<string>>;\n getNetwork?: () => Promise<\"livenet\" | \"mainnet\" | \"testnet\" | \"signet\">;\n on?: (\n event: \"accountsChanged\" | \"networkChanged\",\n listener: (...args: Array<unknown>) => void,\n ) => void;\n pushPsbt?: (psbtHex: string) => Promise<string>;\n removeListener?: (\n event: \"accountsChanged\" | \"networkChanged\",\n listener: (...args: Array<unknown>) => void,\n ) => void;\n requestAccounts: () => Promise<ReadonlyArray<string>>;\n sendBitcoin?: (recipient: string, amount: number) => Promise<string>;\n signMessage: (message: string, type?: \"ecdsa\" | \"bip322-simple\") => Promise<string>;\n signPsbt: (psbtHex: string, options?: Record<string, unknown>) => Promise<string>;\n};\n\nconst CAPS_UNISAT: WalletCapabilities = {\n getBalance: false,\n getTransactionReceipt: false,\n requestAccounts: true,\n sendTransaction: true,\n signIn: false,\n signMessage: true,\n signTransaction: true,\n subscribe: true,\n switchAccount: false,\n switchChain: false,\n};\n\n/**\n * Wrap a UniSat-style provider (`window.unisat`, `window.okxwallet.bitcoin`,\n * `window.btc`) into a butr `WalletAdapter`.\n *\n * The UniSat shape is consistent enough that one adapter handles every\n * derivative. Differences (network names, `sendBitcoin` presence) are\n * gated by feature detection per call.\n */\nconst toStringArray = (value: unknown): Array<string> =>\n Array.isArray(value) ? value.filter((item): item is string => typeof item === \"string\") : [];\n\nconst buildUnisatAdapter = (id: string, name: string, provider: UnisatProvider): WalletAdapter => {\n let chain: ChainBase = BITCOIN_CHAINS.mainnet;\n const listenersSet = new Set<(event: ConnectorEvent) => void>();\n\n const sendBitcoinTx = (tx: unknown): Promise<string> => {\n if (typeof provider.sendBitcoin !== \"function\") {\n throw new TypeError(`Wallet ${name} does not expose sendBitcoin`);\n }\n if (\n typeof tx !== \"object\" ||\n tx === null ||\n !(\"recipient\" in tx) ||\n typeof tx.recipient !== \"string\" ||\n !(\"amount\" in tx) ||\n typeof tx.amount !== \"bigint\"\n ) {\n throw new TypeError(\n \"Bitcoin sendTx expects { amount: bigint, recipient: string }: amount in satoshis\",\n );\n }\n const { amount, recipient } = tx;\n return provider.sendBitcoin(recipient, Number(amount));\n };\n\n const refreshChain = async () => {\n if (typeof provider.getNetwork !== \"function\") {\n return;\n }\n try {\n const network = await provider.getNetwork();\n if (network === \"testnet\") {\n chain = BITCOIN_CHAINS.testnet;\n } else if (network === \"signet\") {\n chain = BITCOIN_CHAINS.signet;\n } else {\n chain = BITCOIN_CHAINS.mainnet;\n }\n } catch {\n void 0;\n }\n };\n\n return {\n capabilities: CAPS_UNISAT,\n chainPlatform: \"bitcoin\",\n\n async connect(opts) {\n if (opts?.silent === true) {\n const accounts = await provider.getAccounts();\n if (accounts.length === 0) {\n throw new Error(\"No authorized accounts for silent reconnect\");\n }\n await refreshChain();\n return;\n }\n await provider.requestAccounts();\n await refreshChain();\n },\n\n disconnect: () =>\n // No portable disconnect across UniSat-shaped wallets. butr's\n // reducer marks the wallet disconnected on its side regardless.\n Promise.resolve(),\n\n async getAccount() {\n const accounts = await provider.getAccounts();\n const first = accounts[0];\n if (first === undefined) {\n return null;\n }\n await refreshChain();\n return buildAccount(first, chain);\n },\n\n async getAccounts() {\n const accounts = await provider.getAccounts();\n if (accounts.length === 0) {\n return [];\n }\n await refreshChain();\n return accounts.map((a) => buildAccount(a, chain));\n },\n\n getBalance: () =>\n Promise.resolve({\n decimals: 8,\n formatted: \"0\",\n symbol: \"BTC\",\n value: 0n,\n }),\n\n getSigner: () => Promise.resolve(provider),\n\n getTransactionReceipt: () => Promise.resolve({ status: \"Pending\" as const }),\n\n icon: GENERIC_BITCOIN_ICON,\n id,\n name,\n\n async requestAccounts() {\n await provider.requestAccounts();\n await refreshChain();\n },\n\n sendTx: (tx) => sendBitcoinTx(tx),\n\n sendTxToChain: (tx, _targetChainIdDecimal, _account, cb) => {\n cb?.();\n return sendBitcoinTx(tx);\n },\n\n async signMessage(msg) {\n // UniSat takes a UTF-8 message and returns a base64 signature.\n // We return the raw signature bytes (decoded from base64) and the\n // bytes the wallet signed (pass-through of the input). UniSat\n // doesn't expose a \"pre-image\" so the input itself is the signed\n // message from butr's perspective.\n const text = new TextDecoder().decode(msg);\n const signatureB64 = await provider.signMessage(text);\n return { signature: base64ToBytes(signatureB64), signedMessage: msg };\n },\n\n async signTransaction(tx) {\n if (!(tx instanceof Uint8Array)) {\n throw new TypeError(\n \"Bitcoin signTransaction expects a PSBT as Uint8Array (e.g. psbt.toBuffer())\",\n );\n }\n const signedHex = await provider.signPsbt(bytesToHex(tx));\n return hexToBytes(signedHex);\n },\n\n subscribe(listener) {\n listenersSet.add(listener);\n const onAccountsChanged = (...args: ReadonlyArray<unknown>) => {\n const accounts = toStringArray(args[0]);\n if (accounts.length === 0) {\n listener({ type: \"disconnected\" });\n return;\n }\n const built = accounts.map((a) => buildAccount(a, chain));\n const first = built[0];\n if (first === undefined) {\n return;\n }\n listener({ account: first, accounts: built, type: \"accountChanged\" });\n };\n const onNetworkChanged = () => {\n void refreshChain();\n };\n provider.on?.(\"accountsChanged\", onAccountsChanged);\n provider.on?.(\"networkChanged\", onNetworkChanged);\n return () => {\n provider.removeListener?.(\"accountsChanged\", onAccountsChanged);\n provider.removeListener?.(\"networkChanged\", onNetworkChanged);\n listenersSet.delete(listener);\n };\n },\n\n switchChain: (target) => {\n if (target.namespace !== \"bip122\") {\n throw new Error(\n `Bitcoin adapter received non-Bitcoin chain \"${target.id}\". Pass a chain with namespace \"bip122\".`,\n );\n }\n // UniSat-shaped wallets pick their network via the user's\n // extension UI; we update local state so consumers see it, but\n // the wallet itself doesn't switch.\n chain = target;\n void refreshChain();\n return Promise.resolve();\n },\n };\n};\n\nexport type { UnisatProvider };\nexport { buildUnisatAdapter };\n","import type { WalletAdapter } from \"@usebutr/core\";\n\nimport type { SatsConnectProvider } from \"./sats-connect\";\nimport { buildSatsConnectAdapter } from \"./sats-connect\";\nimport type { UnisatProvider } from \"./unisat\";\nimport { buildUnisatAdapter } from \"./unisat\";\n\nconst DEFAULT_SETTLE_MS = 150;\n\ntype InjectedHost = {\n btc?: UnisatProvider;\n okxwallet?: { bitcoin?: UnisatProvider };\n unisat?: UnisatProvider;\n XverseProviders?: { BitcoinProvider?: SatsConnectProvider };\n};\n\ntype InjectedBitcoinDiscoveryOptions = {\n /** Suppresses emission when Wallet Standard discovery has already\n * registered a Bitcoin adapter for the same browser session. */\n hasAnyWalletStandardAdapter?: () => boolean;\n /** Settle deadline in ms before the fallback fires. Same default and\n * intent as the EVM injected fallback. */\n settleMs?: number;\n /** Override the global host (tests, iframes). */\n target?: InjectedHost | null;\n};\n\nconst readHost = (target: InjectedBitcoinDiscoveryOptions[\"target\"]): InjectedHost | null => {\n if (target !== undefined) {\n return target;\n }\n if (typeof window === \"undefined\") {\n return null;\n }\n // `window` carries the injected wallet globals (`unisat`, `okxwallet`,\n // etc.) as an untyped host object; `InjectedHost` names the four keys\n // butr probes, all optional and read defensively in `probeProviders`.\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- untyped injected-wallet window globals\n return window as unknown as InjectedHost;\n};\n\nconst probeProviders = (host: InjectedHost): Array<WalletAdapter> => {\n const adapters: Array<WalletAdapter> = [];\n const seen = new Set<UnisatProvider | SatsConnectProvider>();\n\n if (host.unisat && !seen.has(host.unisat)) {\n seen.add(host.unisat);\n adapters.push(buildUnisatAdapter(\"injected:bitcoin:unisat\", \"Unisat\", host.unisat));\n }\n\n const okxBitcoin = host.okxwallet?.bitcoin;\n if (okxBitcoin && !seen.has(okxBitcoin)) {\n seen.add(okxBitcoin);\n adapters.push(buildUnisatAdapter(\"injected:bitcoin:okx\", \"OKX Wallet (Bitcoin)\", okxBitcoin));\n }\n\n const xverse = host.XverseProviders?.BitcoinProvider;\n if (xverse && !seen.has(xverse)) {\n seen.add(xverse);\n adapters.push(buildSatsConnectAdapter(\"injected:bitcoin:xverse\", \"Xverse\", xverse));\n }\n\n if (host.btc && !seen.has(host.btc)) {\n seen.add(host.btc);\n adapters.push(\n buildUnisatAdapter(\"injected:bitcoin:legacy\", \"Browser Bitcoin wallet\", host.btc),\n );\n }\n\n return adapters;\n};\n\n/**\n * Last-resort discovery path for Bitcoin wallets that DON'T announce via\n * Wallet Standard. Probes, in order: `window.unisat`,\n * `window.okxwallet.bitcoin`, `window.XverseProviders.BitcoinProvider`,\n * `window.btc`.\n *\n * Wallet Standard wallets (Phantom, Magic Eden, Leather, modern OKX\n * builds) are already handled by `discoverBitcoinAdapters`. This\n * fallback waits `settleMs` (default 150ms), consults\n * `hasAnyWalletStandardAdapter` if provided, and emits adapters for\n * any injected providers that weren't already covered.\n *\n * Each emitted adapter has a stable id prefix (`injected:bitcoin:*`)\n * so consumers can distinguish them in the picker UI.\n */\nconst discoverInjectedBitcoinAdapter = (\n onAdapter: (adapter: WalletAdapter) => void,\n options: InjectedBitcoinDiscoveryOptions = {},\n): (() => void) => {\n const settleMs = options.settleMs ?? DEFAULT_SETTLE_MS;\n let cancelled = false;\n const timer = setTimeout(() => {\n if (cancelled) {\n return;\n }\n if (options.hasAnyWalletStandardAdapter?.() === true) {\n return;\n }\n const host = readHost(options.target);\n if (host === null) {\n return;\n }\n const adapters = probeProviders(host);\n for (const adapter of adapters) {\n onAdapter(adapter);\n }\n }, settleMs);\n\n return () => {\n cancelled = true;\n clearTimeout(timer);\n };\n};\n\nexport type { InjectedBitcoinDiscoveryOptions };\nexport { GENERIC_BITCOIN_ICON } from \"./icon\";\nexport { discoverInjectedBitcoinAdapter };\n","import type { PlatformDiscoverer } from \"@usebutr/core\";\n\nimport { discoverInjectedBitcoinAdapter } from \"./injected\";\nimport { discoverBitcoinAdapters } from \"./wallet-standard\";\n\n/**\n * Bitcoin's `PlatformDiscoverer`: Wallet Standard primary (Phantom,\n * Magic Eden, Leather, OKX); legacy fallback covers sats-connect\n * (Xverse), `window.unisat`, OKX legacy, and `window.btc`. The\n * fallback defers to Wallet Standard via `hasAnyPrimaryAdapter`.\n */\nconst bitcoinDiscoverer: PlatformDiscoverer = {\n fallback: {\n subscribe: (onAdapter, opts) =>\n discoverInjectedBitcoinAdapter(onAdapter, {\n hasAnyWalletStandardAdapter: opts.hasAnyPrimaryAdapter,\n }),\n },\n platform: \"bitcoin\",\n subscribe: discoverBitcoinAdapters,\n};\n\nexport { bitcoinDiscoverer };\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usebutr/bitcoin",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Wallet Standard + injected (sats-connect / Unisat / OKX) wallet discovery and adapters for butr (Bitcoin).",
5
5
  "license": "MIT",
6
6
  "author": "Pedro Filho <pedro@filho.me>",
@@ -25,13 +25,13 @@
25
25
  "access": "public"
26
26
  },
27
27
  "dependencies": {
28
- "@usebutr/core": "0.4.0",
29
- "@usebutr/wallet-standard-shared": "0.2.4"
28
+ "@usebutr/core": "0.4.2",
29
+ "@usebutr/wallet-standard-shared": "0.2.6"
30
30
  },
31
31
  "devDependencies": {
32
- "@wallet-standard/app": "^1.1.0",
32
+ "@wallet-standard/app": "^1.1.1",
33
33
  "typescript": "^6.0.3",
34
- "vitest": "^4.1.8",
34
+ "vitest": "^4.1.10",
35
35
  "@repo/config-vitest": "0.0.0",
36
36
  "@repo/typescript-config": "0.0.0"
37
37
  },