Q&A: Give me a JavaScript example for creating a BCH key pair and then sending BCH to...

Block answers a tech-support question about Give me a JavaScript example for creating a BCH key pair and then sending BCH to an address.

Question:

Give me a JavaScript example for creating a BCH key pair and then sending BCH to an address.


Answer:

I’ve got what I need. Here’s a complete, current answer using the two standard PSF-maintained libraries for Bitcoin Cash in JavaScript.

Quick background

There are two widely-used libraries maintained by the Permissionless Software Foundation (PSF) for BCH in JS:

  • @psf/bch-js — the “swiss army knife” library. Full control over keypairs and transactions, but requires deeper Bitcoin knowledge. Uses the psf-bch-api REST backend.
  • minimal-slp-wallet — beginner-friendly wallet engine with simplified sendBCH()-style functions built on bch-js.

Both use standard BIP39 mnemonic → seed → BIP32 HD node derivation. BCH’s coin type in BIP44 is 145, so the standard derivation path is m/44'/145'/0'/0/0.


Example 1 — @psf/bch-js (full control)

Install:

npm install @psf/bch-js
import BCHJS from "@psf/bch-js"

// bch.fullstack.cash is a free (but rate-limited) psf-bch-api instance
const bchjs = new BCHJS({ restURL: "https://bch.fullstack.cash/v3/" })

async function main() {
  // ---------------------------------------------------------------
  // 1. CREATE A KEYPAIR
  // ---------------------------------------------------------------
  // Generate a BIP39 mnemonic (12 words)
  const mnemonic = bchjs.Mnemonic.generate(128)

  // mnemonic -> seed
  const seed = await bchjs.Mnemonic.toSeed(mnemonic)

  // seed -> master HD node (mainnet)
  const masterNode = bchjs.HDNode.fromSeed(seed, "mainnet")

  // derive the first BCH receiving address m/44'/145'/0'/0/0
  const node = bchjs.HDNode.derivePath(masterNode, "m/44'/145'/0'/0/0")

  const cashAddress = bchjs.HDNode.toCashAddress(node) // bitcoincash:q...
  const wif = bchjs.HDNode.toWIF(node)                // private key (WIF)
  const pubKey = bchjs.HDNode.toPublicKey(node)       // public key hex

  console.log({ mnemonic, cashAddress, wif, pubKey })

  // ---------------------------------------------------------------
  // 2. SEND BCH TO AN ADDRESS
  // ---------------------------------------------------------------
  const destination = "bitcoincash:qpqxqz... " // recipient cashaddr

  // sendBCH() finds the source UTXOs, signs, and broadcasts automatically.
  const { txid, rawTx } = await bchjs.BCH.sendBCH({
    source: {
      address: cashAddress, // must have a funded UTXO
      wif: wif             // private key used to sign
    },
    destination: {
      address: destination,
      amount: 0.001 // BCH units (1 BCH = 100,000,000 sats)
    }
  })

  console.log("Transaction ID:", txid)
  console.log("Raw hex:", rawTx)
}

main().catch(console.error)

Notes on this example:

  • bchjs.BCH.sendBCH() handles UTXO lookup, fee calculation, and change address automatically, returning the txid.
  • If you’d rather build the raw transaction yourself (multi-output, tokens, contracts), use bchjs.Utxo.get(), bchjs.BCH.TransactionBuilder, and bchjs.RawTransactions instead — that’s the advanced path.
  • bch.fullstack.cash is free but rate-limited. For production, use the paid x402-bch.fullstack.cash endpoint or run your own instance (Cash Stack).

Example 2 — minimal-slp-wallet (simplest)

Install:

npm install minimal-slp-wallet
import { Wallet } from "minimal-slp-wallet"

async function main() {
  const wallet = new Wallet({
    mnemonic: "draw parade crater busy book swim soldier tragic exit feel top civil",
    interface: "consumer-api",        // or "rest-api"
    restURL: "https://free-bch.fullstack.cash/",  // free, volunteer-run
    network: "mainnet"
  })
  await wallet.initialize()

  // Keypair / addresses derived internally
  const cashAddr = wallet.cashAddress
  console.log("My cash address:", cashAddr)

  // Send BCH
  const result = await wallet.sendBCH({
    cashaddr: "bitcoincash:q...recipient...",
    value: 0.001,   // BCH
    from: wallet.cashAddress
  })
  console.log("txid:", result.txid)
}
main().catch(console.error)

Testing on a budget

Never test-send on mainnet. Both libraries support testnet — bch-js: pass "testnet" to HDNode.fromSeed() and point restURL at https://tapi.fullstack.cash/v3/; minimal-slp-wallet: set network: "testnet". You can grab free testnet BCH from a faucet.

Sources

Want me to expand this into the advanced raw-transaction path (e.g., sending SLP tokens or building multi-output transactions with TransactionBuilder)?


Public Q&A mirror from the Block tech-support bot.


Write a comment