bitcoin-wallet-connector
v0.3.1
Published
A Bitcoin wallet connector with various adapters.
Downloads
856
Maintainers
Readme
bitcoin-wallet-connector 
A unified interface for interacting with multiple Bitcoin wallet browser extensions.
Features
This library is carefully designed with a focus on API compatibility and dependency security.
Unified API
- Normalizes wallet differences - Each Bitcoin wallet has its own unique API. This library provides a consistent interface across all supported wallets, so you can write your code once and support multiple wallets.
- Auto-discovery - Automatically detects which wallet extensions are installed in the user's browser and makes them available for connection.
Security-First Design
- Minimal dependencies - All dependencies are declared as peer dependencies, not bundled. This means you install them directly in your project and have full control over their versions. If a security vulnerability is discovered, you can upgrade immediately without waiting for this library to release an update.
- Optional wallet SDKs - Wallet SDKs (like
sats-connector@leather.io/rpc) are optional peer dependencies. You only need to install them if you use the corresponding adapter. - Lazy loading via dynamic imports - Wallet SDKs are loaded via
dynamic import()only when the user attempts to connect to that specific wallet. Even if a supply chain attack compromises an optional SDK, it won't be loaded unless the user explicitly tries to connect to that wallet.
Supported Wallets
| Wallet | Adapter | Optional Dependency |
| ------------------------------------------ | ------------------------------- | ------------------- |
| Unisat | UnisatWalletAdapterFactory | - |
| Xverse | XverseWalletAdapterFactory | sats-connect |
| OKX | OkxWalletAdapterFactory | - |
| Leather | LeatherWalletAdapterFactory | @leather.io/rpc |
| Bitget | BitgetWalletAdapterFactory | - |
| Magic Eden | MagicEdenWalletAdapterFactory | sats-connect |
Installation
pnpm add bitcoin-wallet-connector @scure/base @scure/btc-signerOptional Dependencies
Install based on which wallets you need to support:
# For Xverse / Magic Eden wallet support
pnpm add sats-connect
# For Leather wallet support
pnpm add @leather.io/rpcUsage
Basic Usage (Vanilla JS/TS)
import {
BitcoinWalletConnector,
UnisatWalletAdapterFactory,
XverseWalletAdapterFactory,
} from "bitcoin-wallet-connector"
const connector = new BitcoinWalletConnector([
UnisatWalletAdapterFactory(),
XverseWalletAdapterFactory(),
])
// Get available wallets
const availableAdapters = connector.getAvailableAdapters()
// => [['unisat', adapter], ['xverse', adapter], ...]
// Connect to a wallet
const [adapterId, adapter] = availableAdapters[0]
await connector.connect(adapterId, adapter)
// Get addresses
const addresses = await adapter.getAddresses()
// Sign a message
const result = await adapter.signMessage(addresses[0].address, "Hello Bitcoin!")
// Disconnect
await connector.disconnect()React Integration
import {
BitcoinConnectionProvider,
useBitcoinConnectionContext,
} from "bitcoin-wallet-connector/react"
import {
UnisatWalletAdapterFactory,
XverseWalletAdapterFactory,
} from "bitcoin-wallet-connector/adapters"
const adapterFactories = [
UnisatWalletAdapterFactory(),
XverseWalletAdapterFactory(),
]
function App() {
return (
<BitcoinConnectionProvider
adapterFactories={adapterFactories}
onWalletConnected={session => console.log("Connected:", session)}
onWalletDisconnected={() => console.log("Disconnected")}
>
<WalletUI />
</BitcoinConnectionProvider>
)
}
function WalletUI() {
const {
walletSession,
isConnectionInitializing,
availableAdapters,
connect,
disconnect,
} = useBitcoinConnectionContext()
if (walletSession) {
return (
<div>
<p>Connected: {walletSession.adapterId}</p>
<button onClick={() => disconnect()}>Disconnect</button>
</div>
)
}
return (
<div>
{availableAdapters.map(([adapterId, adapter]) => (
<button
key={adapterId}
onClick={() => connect(adapterId, adapter)}
disabled={isConnectionInitializing}
>
Connect {adapterId}
</button>
))}
</div>
)
}API
WalletAdapter Interface
All adapters implement the following interface:
interface WalletAdapter {
connect(): Promise<void>
disconnect(): Promise<void>
getAddresses(): Promise<WalletAdapterAddress[]>
signMessage(address: string, message: string): Promise<SignMessageResult>
sendBitcoinFeeRateCapability: WalletAdapterSendBitcoinCapability
sendBitcoin(
fromAddress: string,
receiverAddress: string,
satoshiAmount: bigint,
options?: { feeRate?: number },
): Promise<{ txid: string }>
signAndFinalizePsbt(
psbtHex: string,
signIndices: [address: string, signIndex: number][],
): Promise<{ signedPsbtHex: string }>
onAddressesChanged(callback): { unsubscribe: () => void }
}Development
# Install dependencies
pnpm install
# Build
pnpm build
# Run Storybook
pnpm storybook
# Run tests
pnpm testLicense
MIT
