BigBlocks Docs
Components/Wallet

SendBSVButton

Send Bitcoin SV with a simple button interface. Handles transaction creation, signing, and broadcasting.

BitcoinAuthProviderBitcoinQueryProvider
paymentsactionswallet

SendBSVButton combines the Radix Button primitive and Dialog primitive with Bitcoin transaction logic, providing secure BSV sending with balance validation, fee calculation, and confirmation workflows.

Installation

npm install bigblocks

Usage

import { SendBSVButton } from 'bigblocks';

export default function WalletActions() {
  return (
    <SendBSVButton
      recipientAddress="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
      amount="0.001"
      onSuccess={(txid) => {
        console.log('Transaction sent:', txid);
      }}
    />
  );
}

This component extends the Button primitive and Dialog primitive and inherits their props.

Props

PropTypeDefaultDescription
recipientAddressstring-Recipient Bitcoin address
amountstring-Amount in BSV to send
messagestring-Optional transaction memo
walletDataWalletUserExtension-Wallet data for transaction
disabledbooleanfalseDisable the button
loadingbooleanfalseShow loading state
classNamestring-Additional CSS classes
variant'solid' | 'soft' | 'outline' | 'ghost''solid'Button style variant
size'1' | '2' | '3' | '4''2'Button size
maxAmountnumber-Maximum send amount
feeRatenumber-Custom fee rate (sat/byte)
onSuccess(txid: string) => void-Success callback with transaction ID
onError(error: Error) => void-Error callback
buttonTextstring'Send BSV'Custom button label
dialogTitlestring'Send BSV'Dialog title
showContactsbooleanfalseShow contacts selector

Features

  • Transaction Building: Automatic UTXO selection and fee calculation
  • Interactive Dialog: User-friendly send interface with address/amount inputs
  • Contact Integration: Optional contact selector for recipient addresses
  • Real-time Validation: Address and amount validation with feedback
  • Fee Estimation: Dynamic fee calculation based on transaction size
  • Error Handling: Comprehensive error states with user guidance
  • Loading States: Visual feedback during transaction processing
  • Confirmation Flow: Built-in confirmation before broadcasting

Examples

Basic Send Button

<SendBSVButton
  recipientAddress="1BitcoinAddress..."
  amount="0.01"
  onSuccess={(txid) => {
    toast.success(`Transaction sent! TXID: ${txid}`);
  }}
  onError={(error) => {
    toast.error(`Send failed: ${error.message}`);
  }}
/>

Send with Message

<SendBSVButton
  recipientAddress="1BitcoinAddress..."
  amount="0.001"
  message="Payment for coffee"
  onSuccess={(txid) => {
    console.log('Payment sent:', txid);
  }}
/>

Interactive Send Dialog

<SendBSVButton
  buttonText="Send Payment"
  dialogTitle="Send BSV Payment"
  showContacts={true}
  onSuccess={(txid) => {
    router.push(`/transactions/${txid}`);
  }}
/>

Custom Styling

<SendBSVButton
  recipientAddress={address}
  amount={amount}
  variant="outline"
  size="3"
  className="w-full"
  buttonText="Pay Invoice"
  onSuccess={handlePayment}
/>

With Maximum Amount

<SendBSVButton
  maxAmount={0.1}
  feeRate={1.5}
  onSuccess={(txid) => {
    console.log('Send completed:', txid);
  }}
  onError={(error) => {
    if (error.message.includes('insufficient')) {
      toast.error('Insufficient balance');
    } else {
      toast.error(error.message);
    }
  }}
/>

In Payment Form

function PaymentForm() {
  const [recipient, setRecipient] = useState('');
  const [amount, setAmount] = useState('');
  
  return (
    <div className="space-y-4">
      <input
        value={recipient}
        onChange={(e) => setRecipient(e.target.value)}
        placeholder="Recipient address"
        className="w-full p-2 border rounded"
      />
      <input
        type="number"
        value={amount}
        onChange={(e) => setAmount(e.target.value)}
        placeholder="Amount (BSV)"
        className="w-full p-2 border rounded"
      />
      <SendBSVButton
        recipientAddress={recipient}
        amount={amount}
        disabled={!recipient || !amount}
        buttonText="Send Payment"
        onSuccess={(txid) => {
          toast.success('Payment sent successfully!');
          setRecipient('');
          setAmount('');
        }}
      />
    </div>
  );
}

With Wallet Integration

import { useWallet, SendBSVButton } from 'bigblocks';

function WalletSendButton() {
  const { balance, walletData } = useWallet();
  
  return (
    <div className="space-y-2">
      <p className="text-sm text-gray-600">
        Available: {balance} BSV
      </p>
      <SendBSVButton
        walletData={walletData}
        maxAmount={balance * 0.9} // Leave some for fees
        showContacts={true}
        onSuccess={(txid) => {
          console.log('Transaction sent:', txid);
        }}
      />
    </div>
  );
}

Quick Send Variant

import { QuickSendButton } from 'bigblocks';

<QuickSendButton
  amount="0.001"
  recipient="1BitcoinAddress..."
  variant="soft"
  size="1"
  onSuccess={(txid) => {
    console.log('Quick send completed:', txid);
  }}
/>

Required Context

The component requires the following providers:

import { 
  BitcoinAuthProvider, 
  BitcoinQueryProvider 
} from 'bigblocks';

function App() {
  return (
    <BitcoinAuthProvider>
      <BitcoinQueryProvider>
        <SendBSVButton
          recipientAddress="1Address..."
          amount="0.001"
          onSuccess={handleSuccess}
        />
      </BitcoinQueryProvider>
    </BitcoinAuthProvider>
  );
}

API Integration

Required Backend Endpoints

The component expects these API endpoints:

1. Get Wallet Balance

GET /api/wallet/balance

Response:
{
  confirmed: number;    // BSV amount
  unconfirmed: number;  // BSV amount
  total: number;        // BSV amount
  satoshis: {
    confirmed: number;
    unconfirmed: number;
    total: number;
  };
}

2. Build Transaction

POST /api/wallet/send

Request:
{
  recipientAddress: string;
  amount: string;       // BSV amount
  message?: string;     // Optional OP_RETURN memo
  feeRate?: number;     // Custom fee rate
}

Response:
{
  success: boolean;
  txid?: string;
  error?: string;
  fee?: number;
  size?: number;
}

3. Get UTXOs

GET /api/wallet/utxos

Response:
{
  utxos: Array<{
    txid: string;
    vout: number;
    satoshis: number;
    script: string;
    confirmed: boolean;
  }>;
  totalSatoshis: number;
}

Authentication Headers

All wallet API calls require authentication:

headers: {
  'X-Auth-Token': '<BSM signature>',
  'Content-Type': 'application/json'
}

Error Handling

The component handles various error scenarios:

<SendBSVButton
  recipientAddress={address}
  amount={amount}
  onError={(error) => {
    switch (error.message) {
      case 'INSUFFICIENT_FUNDS':
        toast.error('Not enough BSV to send');
        break;
      case 'INVALID_ADDRESS':
        toast.error('Invalid Bitcoin address');
        break;
      case 'AMOUNT_TOO_SMALL':
        toast.error('Amount below minimum threshold');
        break;
      case 'NETWORK_ERROR':
        toast.error('Network connection failed');
        break;
      default:
        toast.error(`Transaction failed: ${error.message}`);
    }
  }}
/>

Security Considerations

  • Private Keys: Never transmitted - signing happens client-side
  • Address Validation: Both client and server-side validation
  • Amount Limits: Configurable maximum send amounts
  • Confirmation Dialogs: Prevent accidental transactions
  • Rate Limiting: Backend protection against spam
  • UTXO Verification: Server validates UTXO ownership