> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shakesco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# @shakesco/bitcoin_base

> Dart SDK for receiving Bitcoin privately with silent payments

<span style={{display:"none"}}>For the complete documentation index, see [llms.txt](/llms.txt).</span>

<Note>
  **Flutter/Dart SDK** - This guide uses our Dart package for mobile and Flutter
  applications. For JavaScript/Node.js, see the [JavaScript
  SDK](/silent-payments/integrate).
</Note>

<Card title="Built With" icon="heart">
  Special thanks to [Cake
  Wallet](https://github.com/cake-tech/bitcoin_base/tree/cake-update-v5) for
  their excellent Bitcoin base library.
</Card>

***

## Installation

Add to your `pubspec.yaml`:

```yaml theme={null}
dependencies:
  bitcoin_base:
    git:
      url: https://github.com/shakesco/bitcoin_base
      ref: cake-update-v5
```

Import the package:

```dart theme={null}
import 'package:bitcoin_base/bitcoin_base.dart' as bitcoin_base;
```

***

## Integration Workflow

<Steps>
  <Step title="Generate silent payment address">
    Create a reusable address for receiving payments
  </Step>

  <Step title="Create taproot destination">
    Generate unique address for each payment
  </Step>

  <Step title="Scan blockchain for funds">Detect incoming transactions</Step>

  <Step title="Spend received funds">
    Derive private keys and transfer Bitcoin
  </Step>
</Steps>

***

## Step 1: Generate Silent Payment Address

<Tabs>
  <Tab title="From Private Keys">
    **Best for:** Apps where users control their own keys

    ```dart theme={null}
    void main() {
      final b_scan = ""; // Scan private key
      final b_spend = ""; // Spend private key

      final paymentOwner = bitcoin_base.SilentPaymentOwner.fromPrivateKeys(
        network: bitcoin_base.BitcoinNetwork.testnet,
        version: 0,
        b_scan: bitcoin_base.ECPrivate.fromHex(b_scan),
        b_spend: bitcoin_base.ECPrivate.fromHex(b_spend)
      );

      print(paymentOwner.toAddress());
    }
    ```

    <Tip>
      **Derive from signatures:** Have users sign a message, then use the [ECDSA signature](https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-messages#ecdsa-sign) components:

      * `r` → `b_scan`
      * `s` → `b_spend`

      This ensures cryptographically secure randomness.
    </Tip>

    <Warning>
      If not using signature derivation, ensure your random number generator is cryptographically secure.
    </Warning>
  </Tab>

  <Tab title="From Mnemonic (Wallets)">
    **Best for:** Wallet applications managing user funds

    ```dart theme={null}
    void main() {
      final mnemonic = ""; // 12, 15, or 24 word phrase

      final paymentOwner = bitcoin_base.SilentPaymentOwner.fromMnemonic(mnemonic);
      print(paymentOwner.toAddress());
    }
    ```

    <Accordion title="Alternative: From HD key">
      ```dart theme={null}
      void main() {
        final paymentOwner = bitcoin_base.SilentPaymentOwner.fromHd();
        print(paymentOwner.toAddress());
      }
      ```
    </Accordion>
  </Tab>
</Tabs>

***

## Step 2: Create Taproot Destination

Generate a one-time taproot address for the payment:

```dart theme={null}
void main() {
  // Parse recipient's silent payment address
  final B_scan = bitcoin_base.SilentPaymentAddress
      .fromAddress(paymentOwner.toAddress()).B_scan;
  final B_spend = bitcoin_base.SilentPaymentAddress
      .fromAddress(paymentOwner.toAddress()).B_spend;

  // Your UTXO details
  final tx_hash = "";
  final tx_id_output_index = 0;
  final sender_privateKey = "";
  final amount = 1000; // Satoshis

  // Build the destination
  final payto = bitcoin_base.SilentPaymentBuilder(
    vinOutpoints: [
      bitcoin_base.Outpoint(
        txid: tx_hash,
        index: tx_id_output_index
      )
    ]
  ).createOutputs(
    [
      bitcoin_base.ECPrivateInfo(
        bitcoin_base.ECPrivate.fromHex(sender_privateKey),
        false // Set true if UTXO is from taproot
      )
    ],
    [
      bitcoin_base.SilentPaymentDestination(
        amount: amount,
        network: bitcoin_base.BitcoinNetwork.testnet,
        version: 0,
        scanPubkey: B_scan,
        spendPubkey: B_spend
      )
    ]
  );

  // Get the taproot address
  final destinationAddress = payto.values.first.first.address
      .toAddress(bitcoin_base.BitcoinNetwork.testnet);
  print("Send $amount sats to: $destinationAddress");
}
```

<Info>
  **Required inputs:**

  <ul>
    <li>UTXO transaction hash and output index</li>
    <li>UTXO private key</li>
    <li>Amount in satoshis (1 BTC = 100,000,000 sats)</li>
    <li>Recipient's scan and spend public keys</li>
  </ul>
</Info>

***

## Step 3: Scan for Incoming Funds

<Warning>
  **Scanning overhead:** This is the main limitation of silent payments - you
  must scan the blockchain to detect incoming transactions.
</Warning>

Check if a transaction belongs to you:

```dart theme={null}
void main() {
  final tx_hash = "";
  final tx_id_output_index = 0;
  final senders_pubKey = "";
  final amount = 1000;
  final Script = "";

  Map<String, bitcoin_base.SilentPaymentScanningOutput> output =
      bitcoin_base.SilentPaymentBuilder(
    vinOutpoints: [
      bitcoin_base.Outpoint(
        txid: tx_hash,
        index: tx_id_output_index
      )
    ],
    pubkeys: [
      bitcoin_base.ECPublic.fromHex(senders_pubKey),
    ],
  ).scanOutputs(
    paymentOwner.b_scan,    // Your scan private key
    paymentOwner.B_spend,   // Your spend public key
    [
      bitcoin_base.BitcoinScriptOutput(
        script: bitcoin_base.Script(script: [Script]),
        value: BigInt.from(amount)
      )
    ]
  );

  final scannedAddress = payto.values.first.first.address
      .toAddress(bitcoin_base.BitcoinNetwork.testnet);
  print("Found address: $scannedAddress");
}
```

If `scannedAddress` matches the taproot output → funds are yours! 🎉

<Accordion title="What you need for scanning">
  **Required data:**

  * Transaction input's `txid` and `output_index`
  * Sender's public key from the output
  * Script and amount from the taproot address

  Learn more: [BIP-352 Scanning Specification](https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#scanning-silent-payment-eligible-transactions)
</Accordion>

***

## Step 4: Spend the Funds

Once confirmed, derive the private key to spend:

```dart theme={null}
void main() {
  final tx_hash = "";
  final tx_id_output_index = 0;
  final senders_pubKey = "";

  bitcoin_base.ECPrivate spendPrivKey = bitcoin_base.SilentPaymentBuilder(
    vinOutpoints: [
      bitcoin_base.Outpoint(
        txid: tx_hash,
        index: tx_id_output_index
      ),
    ],
    pubkeys: [
      bitcoin_base.ECPublic.fromHex(senders_pubKey)
    ],
  ).spendOutputs(
    paymentOwner.b_scan,   // Your scan private key
    paymentOwner.b_spend   // Your spend private key
  );

  print("Private key: ${spendPrivKey}");
  // Use this to build and sign a Bitcoin transaction
}
```

<Tip>
  Use `spendPrivKey` with Bitcoin transaction builders to create and broadcast
  your spending transaction.
</Tip>

***

## Complete

Your Flutter app now supports Bitcoin silent payments with:

* ✅ Reusable static addresses
* ✅ Transaction privacy
* ✅ No notification fees
* ✅ Cross-platform compatibility

***

## Additional Resources

<CardGroup cols={2}>
  <Card title="JavaScript SDK" icon="js" href="/silent-payments/integrate">
    Node.js implementation for backend services
  </Card>

  <Card title="BIP-352 Specification" icon="book" href="https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki">
    Complete technical specification
  </Card>
</CardGroup>
