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

# On the Backend

> Build on Bitcoin easily on the backend with Bigmi.

To get started, install the latest version of the core Bigmi package.

## Installation

```sh theme={"system"}
pnpm add @bigmi/core
```

## Configuration

### Client Configuration

The client is the core of Bigmi. Here's how to configure it:

```typescript theme={"system"}
import { createClient, bitcoin, blockchair, ankr, fallback } from '@bigmi/core'

const client = createClient({
  chain: bitcoin,
  transport: fallback([
    blockchair(),
    ankr({apiKey: 'YOUR_ANKR_API_KEY'})
  ]),
  // Additional parameters
})
```

#### Parameters

| Parameter         | Required | Default                      | Description                                                                                                                                                                            |
| ----------------- | -------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chain`           | No       | -                            | The chain/network this client will perform operations on. The library exports `bitcoin` and `signet` networks, and custom chains can be made using the `defineChain` utility function. |
| `transport`       | Yes      | -                            | This is a JSON-RPC service accessible via HTTP used to communicate with the blockchain.                                                                                                |
| `account`         | No       | -                            | An account or address for the client to perform operations on.                                                                                                                         |
| `pollingInterval` | No       | 4,000ms                      | Frequency for polling actions or events.                                                                                                                                               |
| `cacheTime`       | No       | `pollingInterval` \| 4,000ms | The duration that the client will cache responses for.                                                                                                                                 |
| `key`             | No       | 'base'                       | The key of the client.                                                                                                                                                                 |
| `name`            | No       | 'Base Client'                | The name of the client.                                                                                                                                                                |
| `type`            | No       | 'base'                       | The type of client.                                                                                                                                                                    |
| `rpcSchema`       | No       | -                            | Typed JSON-RPC schema for the client.                                                                                                                                                  |

### Transport Configuration

Bigmi supports JSON-RPC endpoints that are consumed via HTTP.

Bigmi also contains transports that wrap the Blockchair, Blockcypher, Ankr, and Mempool APIs for blockchain read operations.

Most of these transports are free to use with API limits. They can be configured with an `apiKey` and `baseUrl` for production-ready use cases.

It is recommended to use the fallback transport that wraps multiple transports for better reliability.

```typescript theme={"system"}
import { createClient, bitcoin, blockchair, ankr, fallback, mempool, http } from '@bigmi/core'

const client = createClient({
  chain: bitcoin,
  transport: fallback([
    blockchair(),
    ankr({apiKey: 'YOUR_ANKR_API_KEY'}),
    mempool(),
    http() // It defaults to the chain's public RPC URL.
  ]),
})
```

#### UTXO-API Transport Parameters

These include the API-based transports `blockchair`, `ankr`, `mempool`, and `blockcypher`.

<Note>
  As these are wrappers around the HTTP transport, they can also be configured with any of the HTTP Transport Config parameters.
</Note>

| Parameter | Required | type     | Default | Description                  |
| --------- | -------- | -------- | ------- | ---------------------------- |
| `apiKey`  | No       | `string` | -       | The API key for the service. |
| `baseUrl` | No       | `string` | -       | The base URL for the API.    |

#### HTTP Transport Config Parameters

| Parameter         | Required | type                                       | Default  | Description                                                                                           |
| ----------------- | -------- | ------------------------------------------ | -------- | ----------------------------------------------------------------------------------------------------- |
| `key`             | No       | `string`                                   | 'http'   | The key of the transport.                                                                             |
| `name`            | No       | `string`                                   | 'HTTP'   | The name of the transport.                                                                            |
| `rank`            | No       | `boolean` \| `RankOptions`                 | false    | If `true`, the transport is ranked by latency. Options can be provided to customize ranking behavior. |
| `retryCount`      | No       | `number`                                   | 3        | The number of times to retry a request before giving up.                                              |
| `retryDelay`      | No       | `number`                                   | 150      | The delay (in ms) between retries.                                                                    |
| `timeout`         | No       | `number`                                   | 10,000ms | Maximum amount of time to wait for a response.                                                        |
| `raw`             | No       | `boolean`                                  | false    | If `true`, JSON-RPC errors are returned as part of the response instead of being thrown.              |
| `onFetchRequest`  | No       | `function`                                 | -        | Callback function to intercept the fetch request.                                                     |
| `onFetchResponse` | No       | `function`                                 | -        | Callback function to intercept the fetch response.                                                    |
| `fetchOptions`    | No       | `object`                                   | -        | [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) options to pass to the request.     |
| `methods`         | No       | `{include?: method[], exclude?: method[]}` | -        | Methods to include or exclude from this transport.                                                    |

#### Fallback Transport Config Parameters

| Parameter     | Required | type                       | Default    | Description                                                                                                                          |
| ------------- | -------- | -------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `key`         | No       | `string`                   | 'fallback' | The key of the transport.                                                                                                            |
| `name`        | No       | `string`                   | 'Fallback' | The name of the transport.                                                                                                           |
| `rank`        | No       | `boolean` \| `RankOptions` | false      | If `true`, the transport is ranked by latency. Options can be provided to customize ranking behavior.                                |
| `retryCount`  | No       | `number`                   | 3          | The number of times to retry a request before giving up.                                                                             |
| `retryDelay`  | No       | `number`                   | 150        | The delay (in ms) between retries before falling back to the next transport.                                                         |
| `shouldThrow` | No       | `function`                 | -          | When an error is thrown by a transport, this predicate determines if it should fall back to the next transport or end the execution. |

### Chain Configuration

Bigmi comes with mainnet and signet chain definitions.

```typescript theme={"system"}
import { createClient, bitcoin, signet, http, mempool, fallback } from '@bigmi/core'

const mainnetClient = createClient({
    chain: bitcoin,
    transport: fallback([
        mempool(),
        http()
    ])
})

const testnetClient = createClient({
    chain: signet,
    transport: fallback([
        mempool({baseUrl: 'https://mempool.space/signet/api'}),
        http()
    ])
})

```

#### Custom chains

Custom chains can be created using the `defineChain` util.

<CodeGroup>
  ```typescript testnet4.ts theme={"system"}
  import { defineChain, createClient, ChainId, ankr, mempool, http, fallback } from '@bigmi/core'

  const testnet4 = defineChain({
    id: ChainId.Testnet4,
    name: 'Bitcoin Testnet4',
    nativeCurrency: { name: 'Bitcoin', symbol: 'BTC', decimals: 8 },
    rpcUrls: {
      default: {
        http: ['https://bitcoin-testnet-rpc.publicnode.com'],
      },
    },
    blockExplorers: {
      default: {
        name: 'Mempool',
        url: 'https://mempool.space/testnet4/',
      },
    },
    testnet: true
  })


  const testnet4Client = createClient({
    chain: testnet4,
    transport: fallback([
      ankr({apiKey: 'YOUR_ANKR_API_KEY'}),
      mempool({ baseUrl: 'https://mempool.space/testnet4/api' }),
      http()
    ]),
  })
  ```
</CodeGroup>

## Actions

Bigmi contains many functions called actions that can be used to perform various blockchain operations.

### Reading blockchain data

<CodeGroup>
  ```typescript main.ts theme={"system"}
  import { getBalance, getTransaction, getBlockCount } from '@bigmi/core'
  import { client } from './client.ts'

  // check address balance
  const address = 'some_address'
  const balance = await getBalance(client, { address })
  console.log('Balance:', balance)

  // get transaction
  const txId = 'some_tx'
  const tx = await getTransaction(client, { txId })
  console.log('Transaction:', tx)

  // get the latest block 
  const blockCount = await getBlockCount(client)
  console.log('Current block:', blockCount)
  ```

  ```typescript client.ts theme={"system"}
  import { createClient, bitcoin, http, fallback, mempool } from '@bigmi/core'

  export const client = createClient({
      chain: bitcoin,
      transport: fallback([
          mempool(),
          http()
      ])
  })
  ```
</CodeGroup>

### Creating and sending Bitcoin transactions

<CodeGroup>
  ```typescript main.ts theme={"system"}
  import { sendBitcoin } from './sendBitcoin.ts'
  import { client } from './client.ts'

  const privateKey = Buffer.from('0xgf.....', 'hex')
  const fromAddress = 'b1qc....'
  const toAddress = 'b1qer..'
  const amount = 10000 // in sats, equivalent to 0.0001 BTC

  // send bitcoin to another address
  const { txId, confirmed, fee } = await sendBitcoin(client, fromAddress, toAddress, amount, privateKey)
  console.log({
    txId,
    confirmed,
    fee
  })
  ```

  ```typescript client.ts theme={"system"}
  import { createClient, bitcoin, http, fallback, mempool } from '@bigmi/core'

  export const client = createClient({
      chain: bitcoin,
      transport: fallback([
          mempool(),
          http()
      ])
  })
  ```

  ```typescript sendBitcoin.ts theme={"system"}
  import * as bitcoin from 'bitcoinjs-lib';
  import * as ecc from '@bitcoinerlab/secp256k1'
  import { createClient, getBalance, getUTXOs, sendUTXOTransaction, waitForTransaction, estimateFee, type Client } from '@bigmi/core';



  export async function sendBitcoin(
    client: Client,
    fromAddress: string,
    toAddress: string,
    amount: number,
    privateKey: Buffer
  ) {
    try {
      // Check balance
      const balance = await getBalance(client, { address: fromAddress });
      // Add a 1000 sats buffer for transaction fees
      if (balance < amount + 1000) {
        throw new Error('Insufficient balance');
      }
      
      // Get UTXOs
      const utxos = await getUTXOs(client, {
        address: fromAddress,
        // Add a 1000 sats buffer for transaction fees
        minValue: amount + 1000,
      });
      
      if (utxos.length === 0) {
        throw new Error('No UTXOs available');
      }
      
      //init ECC lib
      bitcoin.initEccLib(ecc)

      // Create transaction
      const psbt = new bitcoin.Psbt();
      
      let totalInput = 0;
      for (const utxo of utxos) {
        psbt.addInput({
          hash: utxo.txId,
          index: utxo.vout,
          witnessUtxo: {
            script: Buffer.from(utxo.scriptHex, 'hex'),
            value: utxo.value,
          },
        });
        totalInput += utxo.value;
      }
      
      // Add outputs
      psbt.addOutput({
        address: toAddress,
        value: amount,
      });
      
      // Calculate fee and change
      const fee = await estimateFee(client, utxos.length, 2);
      const change = totalInput - amount - fee;
      
      if (change < 0) {
        throw new Error('Insufficient funds for fee');
      }
      
      if (change > 546) { // Dust threshold
        psbt.addOutput({
          address: fromAddress,
          value: change,
        });
      }
      
      // Sign and finalize
      const keyPair = bitcoin.ECPair.fromPrivateKey(privateKey);
      psbt.signAllInputs(keyPair);
      psbt.finalizeAllInputs();
      
      // Get transaction hex
      const txHex = psbt.extractTransaction().toHex();
      
      // Broadcast with Bigmi
      const txId = await sendUTXOTransaction(client, { hex: txHex });
      
      // Wait for confirmation
      const confirmed = await waitForTransaction(client, {
        txId,
        txHex,
        senderAddress: fromAddress,
        confirmations: 1,
      });
      
      return {
        txId,
        fee,
        confirmed,
      };
      
    } catch (error) {
      console.error('Transaction failed:', error);
      throw error;
    }
  }
  ```
</CodeGroup>
