A robust React-based solution for connecting and interacting with Bitcoin wallets. This package provides components and hooks for seamless integration within your React application. 🚀
- 🌐 Web: React
- 🔄 State Management: Redux
- 🦾 Language: TypeScript
- 🔌 Easy-to-use React components for wallet connection and interactions
- 🔐 Support for multiple Bitcoin wallet providers
- 🎨 Customizable UI components
- 🪝 Hooks for common wallet operations (address fetching, transaction signing, message signing, BTC payments)
- 📘 TypeScript support
Install the package using npm or yarn:
npm install bitcoin-wallet-adapter
# or
yarn add bitcoin-wallet-adapter
Wrap your application with the WalletProvider
to enable wallet functionalities:
import { WalletProvider } from "bitcoin-wallet-adapter";
function App() {
return (
<WalletProvider customAuthOptions={/* optional auth options */}>
<YourApp />
</WalletProvider>
);
}
Prop | Type | Description |
---|---|---|
children | ReactNode | The child components to be wrapped by the provider |
customAuthOptions | AuthOptionsArgs (optional) | Custom authentication options |
The AuthOptionsArgs
type includes:
interface AuthOptionsArgs {
manifestPath?: string;
redirectTo?: string;
network?: "mainnet" | "testnet";
appDetails?: {
name?: string;
icon?: string;
};
}
📝 Note: The
appDetails
field incustomAuthOptions
is primarily used by the Leather wallet.
Use the ConnectMultiWallet
component to render a multi-wallet connect button:
import { ConnectMultiWallet } from "bitcoin-wallet-adapter";
function WalletConnect() {
return (
<ConnectMultiWallet
buttonClassname="custom-button-class"
modalContainerClass="custom-modal-container"
modalContentClass="custom-modal-content"
closeButtonClass="custom-close-button"
headingClass="custom-heading"
walletItemClass="custom-wallet-item"
walletImageClass="custom-wallet-image"
walletLabelClass="custom-wallet-label"
InnerMenu={CustomInnerMenu}
icon="custom-icon.png"
iconClass="custom-icon-class"
balance={1000}
network="mainnet"
connectionMessage="Custom connection message"
fractal={true}
supportedWallets={["unisat", "xverse", "leather"]}
/>
);
}
Prop | Type | Description |
---|---|---|
buttonClassname | string (optional) | Custom class for the main button |
modalContainerClass | string (optional) | Custom class for the modal container |
modalContentClass | string (optional) | Custom class for the modal content |
closeButtonClass | string (optional) | Custom class for the close button |
headingClass | string (optional) | Custom class for the modal heading |
walletItemClass | string (optional) | Custom class for each wallet item in the list |
walletImageClass | string (optional) | Custom class for wallet logos |
walletLabelClass | string (optional) | Custom class for wallet labels |
InnerMenu | React.ComponentType (optional) | Custom component for the inner menu when wallet is connected |
icon | string (optional) | Custom logo URL of your application |
iconClass | string (optional) | Custom class for the icon |
balance | number (optional) | Wallet balance to display |
network | "mainnet" | "testnet" (optional) | Bitcoin network to use |
connectionMessage | string (optional) | Custom message for wallet connection |
fractal | boolean (optional) | Show only fractal supporting wallets (Unisat |
supportedWallets | string[] (optional) | Array of wallet names to be supported in the dApp |
The supportedWallets
prop allows you to specify which wallets you want to support in your dApp. Pass an array of wallet names (in lowercase) to filter the available wallets. For example:
supportedWallets={["unisat", "xverse", "leather"]}
This will only show the Unisat, Xverse, and Leather wallet options in the connect modal, even if other wallets are installed in the user's browser.
📝 Note: If
supportedWallets
is not provided, all available wallets will be shown.
Add the Notification
component to your app to display wallet-related notifications:
import { Notification } from "bitcoin-wallet-adapter";
function App() {
return (
<div>
<YourAppContent />
<Notification />
</div>
);
}
Fetch wallet addresses:
import { useWalletAddress } from "bitcoin-wallet-adapter";
function WalletInfo() {
const walletDetails = useWalletAddress();
return (
<div>
<p>Ordinal Address: {walletDetails.ordinal}</p>
<p>Cardinal Address: {walletDetails.cardinal}</p>
</div>
);
}
Sign PSBT (Partially Signed Bitcoin Transaction) for various operations:
import { useSignTx } from "bitcoin-wallet-adapter";
function TransactionSigner() {
const { signTx, loading, result, error } = useSignTx();
const handleSellSign = async () => {
const signOptions = {
psbt: "your-psbt-base64",
network: "mainnet",
action: "sell",
inputs: [
{
address: walletDetails.ordinal,
publickey: walletDetails.ordinalPubkey,
sighash: 131,
index: [0],
},
],
};
await signTx(signOptions);
};
// Use useEffect to handle the result or error
useEffect(() => {
if (result) {
console.log("Sign Result:", result);
// Handle successful signing
}
if (error) {
console.error("Sign Error:", error);
// Handle error
}
}, [result, error]);
return (
<button onClick={handleSellSign} disabled={loading}>
{loading ? "Signing..." : "Sign Transaction"}
</button>
);
}
Sign messages for various wallets:
import { useMessageSign } from "bitcoin-wallet-adapter";
function MessageSigner() {
const { signMessage, loading, result, error } = useMessageSign();
const handleMessageSign = async () => {
const messageOptions = {
network: "mainnet",
address: walletDetails.ordinal,
message: "Your message here",
wallet: walletDetails.wallet,
};
await signMessage(messageOptions);
};
// Use useEffect to handle the result or error
useEffect(() => {
if (result) {
console.log("Message Sign Result:", result);
// Handle successful signing
}
if (error) {
console.error("Message Sign Error:", error);
// Handle error
}
}, [result, error]);
return (
<button onClick={handleMessageSign} disabled={loading}>
{loading ? "Signing..." : "Sign Message"}
</button>
);
}
The usePayBTC
hook facilitates BTC payments from the currently connected wallet:
import { usePayBTC } from "bitcoin-wallet-adapter";
function BTCPayment() {
const { payBTC, loading, result, error } = usePayBTC();
const handlePayment = async () => {
const paymentOptions = {
network: "mainnet",
address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
amount: 1000, // Amount in satoshis
fractal: false, // Optional: use fractal for OKX wallet
};
await payBTC(paymentOptions);
};
// Use useEffect to handle the result or error
useEffect(() => {
if (result) {
console.log("Payment Result (txid):", result);
// Handle successful payment
}
if (error) {
console.error("Payment Error:", error);
// Handle error
}
}, [result, error]);
return (
<button onClick={handlePayment} disabled={loading}>
{loading ? "Processing Payment..." : "Pay BTC"}
</button>
);
}
The payBTC
function accepts a PaymentOptions
object with the following properties:
Property | Type | Description |
---|---|---|
network | "testnet" | "mainnet" | The Bitcoin network to use |
address | string | The recipient's Bitcoin address |
amount | number | The amount to send in satoshis |
fractal | boolean (optional) | Whether to use fractal for OKX wallet |
The usePayBTC
hook returns an object with the following properties:
Property | Type | Description |
---|---|---|
payBTC | (options: PaymentOptions) => Promise | Function to initiate the payment |
loading | boolean | Indicates if a payment is in progress |
result | string | null | The transaction ID (txid) if the payment was successful |
error | Error | null | Any error that occurred during the payment process |
The usePayBTC
hook supports the following wallets:
- Leather
- Xverse
- MagicEden
- Unisat
- OKX
- Phantom (not implemented for BTC payments)
📝 Note: Make sure a wallet is connected before attempting to make a payment. The hook will return an error if no wallet is connected. The payment will be made using the currently connected wallet, which is determined by the
walletDetails
in the app's state.
This hook integrates with the notification system of the Bitcoin Wallet Adapter. Any errors during the payment process will be displayed as notifications in your application.
Bitcoin Wallet Adapter currently supports the following wallets:
- 🦄 Unisat
- 🌌 Xverse
- 🐂 Leather/Hiro
- 🔮 MagicEden
- 👻 Phantom
🅾️ OKX
The package includes TypeScript definitions for key interfaces and types. Here are some of the main types used:
interface WalletDetails {
cardinal: string;
cardinalPubkey: string;
ordinal: string;
ordinalPubkey: string;
connected: boolean;
wallet: string;
derivationPath?: string;
}
type Purpose = "payment" | "ordinals";
type Account = {
address: string;
publicKey: string;
purpose: Purpose;
};
interface UTXO {
status: {
block_hash: string;
block_height: number;
block_time: number;
confirmed: boolean;
};
txid: string;
value: number;
vout: number;
tx: any;
}
interface CommonSignOptions {
psbt: string;
network: "mainnet" | "testnet";
action: "sell" | "buy" | "dummy" | "other";
fractal?: boolean;
inputs: {
publickey: string;
address: string;
index: number[];
sighash: number;
}[];
}
interface CommonSignResponse {
loading: boolean;
result: any;
error: Error | null;
sign: (options: CommonSignOptions) => Promise<void>;
}
For a complete list of types, please refer to the types.ts
file in the package.
We welcome contributions to the Bitcoin Wallet Adapter! Please read our CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests. Let's build the future of Bitcoin wallets together! 🚀
This project is licensed under the MIT License - see the LICENSE.md file for details.