@usebutr/bitcoin 0.2.4 → 0.2.5

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
@@ -11,7 +11,7 @@ type BitcoinSignMessageOutput = {
11
11
  signedMessage: Uint8Array;
12
12
  };
13
13
  type BitcoinSignMessageFeature = {
14
- signMessage(input: BitcoinSignMessageInput): Promise<BitcoinSignMessageOutput>;
14
+ signMessage: (input: BitcoinSignMessageInput) => Promise<BitcoinSignMessageOutput>;
15
15
  };
16
16
  type BitcoinSignPsbtInput = {
17
17
  account: WalletStandardWalletAccount; /** Network chain id (`bip122:…`). */
@@ -27,7 +27,7 @@ type BitcoinSignPsbtOutput = {
27
27
  signedPsbt: Uint8Array;
28
28
  };
29
29
  type BitcoinSignPsbtFeature = {
30
- signPsbt(input: BitcoinSignPsbtInput): Promise<BitcoinSignPsbtOutput>;
30
+ signPsbt: (input: BitcoinSignPsbtInput) => Promise<BitcoinSignPsbtOutput>;
31
31
  };
32
32
  type BitcoinSendTransferInput = {
33
33
  account: WalletStandardWalletAccount;
@@ -39,7 +39,7 @@ type BitcoinSendTransferOutput = {
39
39
  /** Broadcast txid. */txid: string;
40
40
  };
41
41
  type BitcoinSendTransferFeature = {
42
- sendTransfer(input: BitcoinSendTransferInput): Promise<BitcoinSendTransferOutput>;
42
+ sendTransfer: (input: BitcoinSendTransferInput) => Promise<BitcoinSendTransferOutput>;
43
43
  };
44
44
  //#endregion
45
45
  //#region src/wallet-standard-adapter.d.ts
@@ -162,22 +162,10 @@ type BitcoinCapabilityInput = {
162
162
  */
163
163
  declare const resolveBitcoinCapabilities: (input: BitcoinCapabilityInput) => WalletCapabilities;
164
164
  //#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
165
  //#region src/injected/sats-connect.d.ts
178
166
  /** sats-connect (Xverse) shape — a JSON-RPC-ish `request(method, params)`. */
179
167
  type SatsConnectProvider = {
180
- request(method: string, params?: Record<string, unknown>): Promise<{
168
+ request: (method: string, params?: Record<string, unknown>) => Promise<{
181
169
  error?: {
182
170
  message: string;
183
171
  };
@@ -199,15 +187,15 @@ type SatsConnectProvider = {
199
187
  * same four methods every UniSat-derivative wallet exposes (UniSat
200
188
  * itself, OKX Wallet's Bitcoin path at `window.okxwallet.bitcoin`). */
201
189
  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>;
190
+ getAccounts: () => Promise<ReadonlyArray<string>>;
191
+ getNetwork?: () => Promise<"livenet" | "mainnet" | "testnet" | "signet">;
192
+ on?: (event: "accountsChanged" | "networkChanged", listener: (...args: Array<unknown>) => void) => void;
193
+ pushPsbt?: (psbtHex: string) => Promise<string>;
194
+ removeListener?: (event: "accountsChanged" | "networkChanged", listener: (...args: Array<unknown>) => void) => void;
195
+ requestAccounts: () => Promise<ReadonlyArray<string>>;
196
+ sendBitcoin?: (recipient: string, amount: number) => Promise<string>;
197
+ signMessage: (message: string, type?: "ecdsa" | "bip322-simple") => Promise<string>;
198
+ signPsbt: (psbtHex: string, options?: Record<string, unknown>) => Promise<string>;
211
199
  };
212
200
  /**
213
201
  * Wrap a UniSat-style provider (`window.unisat`, `window.okxwallet.bitcoin`,
@@ -218,6 +206,18 @@ type UnisatProvider = {
218
206
  * gated by feature detection per call.
219
207
  */
220
208
  //#endregion
209
+ //#region src/injected/icon.d.ts
210
+ /**
211
+ * Generic Bitcoin wallet icon — same purse SVG style as the EVM
212
+ * package, recoloured. Inline so the picker doesn't flash.
213
+ *
214
+ * Lives in its own file because both injected adapters (UniSat-shape
215
+ * and sats-connect) need the same fallback when the wallet doesn't
216
+ * advertise its own icon, and there's no other "shared" thing they
217
+ * both want — a one-line module beats a grab-bag.
218
+ */
219
+ declare const GENERIC_BITCOIN_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2Y3OTMxYSIgc3Ryb2tlPSJub25lIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIvPjx0ZXh0IHg9IjEyIiB5PSIxNyIgZm9udC1mYW1pbHk9InNlcmlmIiBmb250LXNpemU9IjE0IiBmb250LXdlaWdodD0iYm9sZCIgZmlsbD0iI2ZmZiIgdGV4dC1hbmNob3I9Im1pZGRsZSI+QjwvdGV4dD48L3N2Zz4=";
220
+ //#endregion
221
221
  //#region src/injected/index.d.ts
222
222
  type InjectedHost = {
223
223
  btc?: UnisatProvider;
@@ -281,13 +281,13 @@ declare const bitcoinDiscoverer: PlatformDiscoverer;
281
281
  * to runtime-narrow.
282
282
  */
283
283
  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>;
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>;
288
288
  };
289
289
  type SatsConnectLike = {
290
- request(method: string, params?: Record<string, unknown>): Promise<{
290
+ request: (method: string, params?: Record<string, unknown>) => Promise<{
291
291
  error?: {
292
292
  message: string;
293
293
  };
@@ -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":"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"}
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 = 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 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 } 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.5",
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.1",
29
+ "@usebutr/wallet-standard-shared": "0.2.5"
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.9",
35
35
  "@repo/config-vitest": "0.0.0",
36
36
  "@repo/typescript-config": "0.0.0"
37
37
  },