| name | bch |
| description | Bitcoin Cash (BCH) blockchain operations using the psf-slp-wallet CLI. Use when the user wants to create a BCH wallet, check balances, send BCH, send SLP tokens, create tokens, sign or verify messages, sweep funds, get addresses, get token info, or perform any BCH blockchain interaction. Triggers on: BCH, Bitcoin Cash, wallet, send BCH, SLP token, blockchain, check balance, sweep, private key, WIF, cashAddress, token create, token mint, token burn, NFT, fungible token, sign message, verify message. |
BCH Blockchain Operations with psf-slp-wallet
This skill teaches you how to interact with the Bitcoin Cash (BCH) blockchain using the psf-slp-wallet command-line application. The tool supports wallet management, sending/receiving BCH, SLP token operations (fungible, group, and NFT), message signing/verification, and fund sweeping.
Prerequisites
- Node.js (v22+) must be installed.
- The
psf-slp-wallet repository must be cloned and dependencies installed.
git clone https://github.com/Permissionless-Software-Foundation/psf-slp-wallet
If dependencies are not yet installed, run:
cd psf-slp-wallet && npm install
All CLI commands below are run from the psf-slp-wallet project root:
node psf-slp-wallet.js <command> [options]
Setup: Choosing a Back End
The psf-slp-wallet uses minimal-slp-wallet under the hood, which can connect to different back end infrastructure. The back end is configured in psf-slp-wallet/config/index.js.
Ask the user which back end they want to use before proceeding. Present these three options:
Option 1: x402 Payment Protocol (Recommended)
- Speed: Fastest and most reliable.
- Cost: Requires a small amount of BCH to pay for API calls (~10,000 satoshis per call, roughly $0.003 USD).
- Requires: A funded BCH address and its WIF private key.
To configure x402, edit psf-slp-wallet/config/index.js:
const config = {
restURL: 'https://x402-bch.fullstack.cash/v6/',
interface: 'rest-api',
x402wif: 'L...',
paymentAmountSats: 10000,
bchServerURL: 'https://bch.fullstack.cash/v6/'
}
x402 Setup Steps:
- Create a new wallet (see "Create a Wallet" below).
- Show the user the wallet's Cash Address (see "Get Addresses").
- Ask the user to send a small amount of BCH (e.g., $1-2 USD worth) to that address.
- Read the wallet file at
psf-slp-wallet/.wallets/<name>.json to get the privateKey (WIF) field.
- Update
config/index.js with the WIF, set interface to 'rest-api', and set restURL to 'https://x402-bch.fullstack.cash/v6/'.
Option 2: free-bch.fullstack.cash (Free Tier)
- Speed: Medium speed, but no guarantee of uptime.
- Cost: Free.
- Best for: Quick testing or low-frequency usage.
const config = {
restURL: 'https://free-bch.fullstack.cash',
interface: 'consumer-api'
}
This is the default configuration. No additional setup needed.
Option 3: bch.fullstack.cash (Free and Reliable)
- Speed: Reliable but much slower than x402.
- Cost: Free.
- Best for: Reliable usage when you don't want to spend BCH on API calls.
const config = {
restURL: 'https://bch.fullstack.cash',
interface: 'rest-api'
}
Applying Configuration Changes
After the user selects a back end, edit the file psf-slp-wallet/config/index.js to set the restURL, interface, and (for x402) the x402wif fields. The x402-specific fields (x402wif, paymentAmountSats, bchServerURL) are only needed when using the x402 back end.
Core Workflows
Create a Wallet
Creates a new BCH wallet and saves it as a JSON file under .wallets/.
node psf-slp-wallet.js wallet-create -n <wallet-name> -d "<description>"
Flags:
-n <name> (required): A short name for the wallet (no spaces).
-d <description> (optional): A human-readable description of the wallet's purpose.
Example:
node psf-slp-wallet.js wallet-create -n mywallet -d "My primary BCH wallet"
The wallet file is saved at psf-slp-wallet/.wallets/mywallet.json and contains the mnemonic seed phrase, private key (WIF), and all derived addresses. Warn the user to back up their mnemonic -- it is the only way to recover the wallet.
List Wallets
Lists all wallets that have been created.
node psf-slp-wallet.js wallet-list
Displays a table with wallet names and descriptions.
Get Addresses
Shows the Cash Address, SLP Address, and Legacy Address for a wallet.
node psf-slp-wallet.js wallet-addrs -n <wallet-name>
Example:
node psf-slp-wallet.js wallet-addrs -n mywallet
Output includes:
- Cash Address (
bitcoincash:q...): Use this to receive BCH.
- SLP Address (
simpleledger:q...): Use this to receive SLP tokens.
- Legacy Address (
1...): Legacy format, used by older applications.
When the user asks "what is my address?" or "how do I receive BCH?", show them the Cash Address.
Check Balance
Gets the BCH balance and any SLP token balances held by the wallet.
node psf-slp-wallet.js wallet-balance -n <wallet-name>
Example:
node psf-slp-wallet.js wallet-balance -n mywallet
Output shows:
- BCH balance in satoshis and BCH.
- A list of SLP tokens with ticker, quantity, and token ID.
- Any minting batons held by the wallet.
Note: This command contacts the blockchain. If the back end is not configured or is down, it will fail. Ensure the config is properly set first.
Send BCH
Send BCH from a wallet to a recipient address.
node psf-slp-wallet.js send-bch -n <wallet-name> -a <recipient-address> -q <amount-in-bch>
Flags:
-n <name> (required): Wallet name to send from.
-a <address> (required): Recipient's Cash Address (bitcoincash:q...).
-q <amount> (required): Amount of BCH to send (e.g., 0.001).
Example:
node psf-slp-wallet.js send-bch -n mywallet -a bitcoincash:qp2rmj8heytjrksxm2xrjs0hncnvl08xwgkweawu9h -q 0.001
On success, the TXID is printed along with a block explorer link. Always confirm the address and amount with the user before executing a send.
Important: The quantity is in BCH, not satoshis. 1 BCH = 100,000,000 satoshis.
Send SLP Tokens
Send SLP tokens from a wallet to a recipient address.
node psf-slp-wallet.js send-tokens -n <wallet-name> -a <recipient-address> -q <quantity> -t <token-id>
Flags:
-n <name> (required): Wallet name to send from.
-a <address> (required): Recipient address (SLP or Cash Address).
-q <quantity> (required): Number of tokens to send.
-t <token-id> (required): The 64-character hex token ID.
Example:
node psf-slp-wallet.js send-tokens -n mywallet -a simpleledger:qpeq7xx5x3a2jfa0x0w8cjqp4v9cm842vgsjqwzvfk -q 10 -t a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2
The wallet must hold BCH for transaction fees in addition to the tokens being sent.
Wallet Security
Reading Wallet Data
Wallet files are stored at psf-slp-wallet/.wallets/<name>.json. The JSON structure is:
{
"wallet": {
"mnemonic": "twelve word seed phrase ...",
"privateKey": "L...",
"cashAddress": "bitcoincash:q...",
"slpAddress": "simpleledger:q...",
"legacyAddress": "1...",
"hdPath": "m/44'/245'/0'/0/0",
"description": "..."
}
}
Never display the mnemonic or privateKey to the user unless they explicitly ask for it. These are secrets that control the wallet funds.
Sweep Funds from a Private Key
Sweeps all BCH and SLP tokens from an external WIF private key into the wallet.
node psf-slp-wallet.js wallet-sweep -n <wallet-name> -w <wif-private-key>
Flags:
-n <name> (required): Wallet to receive the swept funds.
-w <wif> (required): The WIF private key to sweep (starts with K or L).
Example:
node psf-slp-wallet.js wallet-sweep -n mywallet -w L3BUek8oq1iijZTkfdRYo8RDxEe3PpB8MyJnh2FSGWAoCjAffQCp
This moves all BCH and tokens from the WIF address into the target wallet in a single transaction.
Message Signing and Verification
Sign a Message
Cryptographically sign a message using a wallet's private key. This proves that the owner of the wallet's address produced the signature.
node psf-slp-wallet.js msg-sign -n <wallet-name> -m "<message>"
Example:
node psf-slp-wallet.js msg-sign -n mywallet -m "I agree to the terms of this contract"
Output includes the address that signed it and the signature string.
Verify a Signature
Verify that a message was signed by the private key associated with a given BCH address.
node psf-slp-wallet.js msg-verify -a <bch-address> -m "<message>" -s "<signature>"
Example:
node psf-slp-wallet.js msg-verify -a bitcoincash:qz... -m "I agree to the terms of this contract" -s "H..."
Returns true if the signature is valid, false otherwise. No wallet is needed for verification.
Token Operations
Get Token Info
Retrieve metadata about an SLP token, including its name, ticker, genesis data, and mutable/immutable data.
node psf-slp-wallet.js token-info -t <token-id>
Get Token Transaction History
Retrieve the transaction history for a token. Useful for NFTs to find the current holder.
node psf-slp-wallet.js token-tx-history -t <token-id>
Create a Fungible Token (Type 1)
Create a new SLP Type 1 fungible token.
node psf-slp-wallet.js token-create-fungible \
-n <wallet-name> \
-m "<token-name>" \
-t "<ticker>" \
-d <decimals> \
-q <initial-quantity> \
-u "<document-url>" \
-h "<document-hash>"
Flags:
-n <wallet-name> (required): Wallet paying for the transaction.
-m <token-name> (required): Full name of the token.
-t <ticker> (required): Short ticker symbol (e.g., MYT).
-d <decimals> (required): Number of decimal places (0-9).
-q <quantity> (required): Initial token supply to mint.
-u <url> (optional): URL for immutable data (e.g., IPFS CID).
-h <hash> (optional): Transaction hash for mutable data address.
Example:
node psf-slp-wallet.js token-create-fungible -n mywallet -m "My Token" -t MYT -d 2 -q 1000
The wallet must hold BCH to pay the transaction fee. The minting baton is kept by the wallet for future minting.
Create a Group Token
Create an SLP Group token (used as a parent for NFTs).
node psf-slp-wallet.js token-create-group \
-n <wallet-name> \
-m "<token-name>" \
-t "<ticker>" \
-q <quantity> \
-u "<url>" \
-h "<hash>"
Example:
node psf-slp-wallet.js token-create-group -n mywallet -m "My NFT Collection" -t MNFT -q 10
Each Group token can later be burned to create one NFT child token.
Create an NFT
Create an SLP NFT by burning one Group token.
node psf-slp-wallet.js token-create-nft \
-n <wallet-name> \
-m "<nft-name>" \
-t "<ticker>" \
-i <group-token-id> \
-u "<url>" \
-h "<hash>"
Flags:
-i <group-token-id> (required): Token ID of the Group token to burn.
Example:
node psf-slp-wallet.js token-create-nft -n mywallet -m "My First NFT" -t NFT001 -i <group-token-id>
Mint Additional Tokens
Mint more of an existing Fungible (Type 1) or Group token. Requires the minting baton.
node psf-slp-wallet.js token-mint -n <wallet-name> -t <token-id> -q <quantity>
Optional:
-r <receiver>: Address to send the minting baton to. Defaults to same wallet. Use -r null to permanently burn the baton (no more minting possible).
Burn Tokens
Destroy a specific quantity of tokens.
node psf-slp-wallet.js token-burn -n <wallet-name> -t <token-id> -q <quantity>
Update Token Mutable Data
Update the mutable data for a token (e.g., change token icon or metadata). This is a two-step process:
- Create a Mutable Data Address transaction:
node psf-slp-wallet.js token-mda-tx -n <wallet-name> -a <mutable-data-address>
- Update the data with a new IPFS CID:
node psf-slp-wallet.js token-update -n <wallet-name> -c <ipfs-cid>
Troubleshooting
Common Errors
- "Insufficient funds": The wallet does not have enough BCH to cover the transaction amount plus fees. Ask the user to send more BCH to the wallet's Cash Address.
- "walletName is required": The
-n flag was not provided. All commands that interact with a wallet require -n <wallet-name>.
- "ENOENT" or file not found: The wallet file does not exist. Check the wallet name with
wallet-list, or create a new wallet.
- Network/timeout errors: The configured back end may be down or slow. Consider switching back ends (see Setup section). If using
free-bch.fullstack.cash, try again -- it is rate-limited.
- "No tokens found": The wallet has no SLP tokens, or the blockchain data hasn't been fetched yet. Check the balance first.
Block Explorer Links
After any transaction, the TXID is printed. View it on a block explorer:
- BCH transactions:
https://bch.loping.net/tx/<txid>
- Token transactions:
https://token.fullstack.cash/transactions/?txid=<txid>
Quick Reference
| Task | Command |
|---|
| Create wallet | node psf-slp-wallet.js wallet-create -n <name> -d "<desc>" |
| List wallets | node psf-slp-wallet.js wallet-list |
| Get addresses | node psf-slp-wallet.js wallet-addrs -n <name> |
| Check balance | node psf-slp-wallet.js wallet-balance -n <name> |
| Send BCH | node psf-slp-wallet.js send-bch -n <name> -a <addr> -q <bch> |
| Send tokens | node psf-slp-wallet.js send-tokens -n <name> -a <addr> -q <qty> -t <tokenId> |
| Sweep WIF | node psf-slp-wallet.js wallet-sweep -n <name> -w <wif> |
| Sign message | node psf-slp-wallet.js msg-sign -n <name> -m "<msg>" |
| Verify signature | node psf-slp-wallet.js msg-verify -a <addr> -m "<msg>" -s "<sig>" |
| Token info | node psf-slp-wallet.js token-info -t <tokenId> |
| Token history | node psf-slp-wallet.js token-tx-history -t <tokenId> |
| Create fungible token | node psf-slp-wallet.js token-create-fungible -n <name> -m "<tokenName>" -t <ticker> -d <dec> -q <qty> |
| Create group token | node psf-slp-wallet.js token-create-group -n <name> -m "<tokenName>" -t <ticker> -q <qty> |
| Create NFT | node psf-slp-wallet.js token-create-nft -n <name> -m "<nftName>" -t <ticker> -i <groupTokenId> |
| Mint tokens | node psf-slp-wallet.js token-mint -n <name> -t <tokenId> -q <qty> |
| Burn tokens | node psf-slp-wallet.js token-burn -n <name> -t <tokenId> -q <qty> |