Search by

amashukov / bchn-rpc-client-php

Andrey Mashukov

Typed JSON-RPC client for Bitcoin Cash Node (BCHN) in pure PHP over any PSR-18 client — wallet, UTXO, PSBT, raw-transaction and double-spend-proof calls in the BCHN dialect, CashTokens token data, exact satoshi amounts, never floats.

Package info

github.com/AndreyMashukov/bchn-rpc-client-php

pkg:composer/amashukov/bchn-rpc-client-php

Statistics

Installs: 72

Dependents: 2

Suggesters: 0

Stars: 0

Open Issues: 0

v0.2.0 2026-10-23 10:09 UTC

This package is auto-updated.

Last update: 2026-10-23 10:10:06 UTC


README

Typed JSON-RPC client for Bitcoin Cash Node (BCHN) in pure PHP over any PSR-18 client — wallet, UTXO, PSBT, raw-transaction and DSProof calls in the BCHN dialect, exact satoshi amounts.

CI PHPStan L9 Latest Version Downloads PHP License Stars

A typed client for the Bitcoin Cash Node JSON-RPC API (tested against BCHN v29.2.0) built on any PSR-18 HTTP client. BCHN shares its RPC heritage with Bitcoin Core but its signatures differ — createwallet takes four parameters, getnewaddress has no address type, lockunspent has no persistent flag, sendrawtransaction / testmempoolaccept take a boolean allowhighfees instead of a max fee rate, sighash types carry FORKID, there is estimatefee instead of estimatesmartfee, and outputs may carry CashTokens tokenData. This client follows the BCHN signatures exactly and returns final readonly Value Objects. Every JSON number is read as a string before decoding, so BCH amounts become exact integer satoshis (BchAmount) and never pass through a float.

Features

  • BCHN dialect — signatures checked against the BCHN JSON-RPC reference, method by method.
  • Exact amounts — BchAmount holds integer satoshis parsed from the node's decimal text; token amounts stay decimal strings (they exceed 53 bits).
  • Typed prevouts — getRawTransaction() asks for verbosity 2 and turns vin.value / vin.scriptPubKey into a Prevout; Transaction::fee() is computed from them and is null when any input value is unknown (coinbase) — never guessed. When a pruned node without -txindex cannot fetch an input's transaction for the fee calculation, the transaction is read again at verbosity 1, so every prevout and the fee are null; any other error (an unknown transaction) is still thrown.
  • Wallet entry times — listsinceblock entries carry time, timeReceived and, once mined, blockTime.
  • Outputs without guessing — an output exposes an address only when the node reports exactly one; OP_RETURN and bare multisig outputs keep their script type, value and token data with address = null.
  • CashTokens — tokenData (category, fungible amount, NFT capability and commitment) on UTXOs, inputs and outputs; listUnspent(includeTokens: true) sets BCHN's query_options.includeTokens.
  • Multi-wallet — withWallet('hot-wallet') targets /wallet/hot-wallet.
  • Loud failures — BchnRpcException carries the RPC code and the HTTP status; a reply that is not JSON (a proxy's HTML 502, an empty 401) is reported with its status and the first 256 bytes of the body.

Installation

composer require amashukov/bchn-rpc-client-php

Usage

use Amashukov\BchnRpc\BchnRpcClient;
use Amashukov\BchnRpc\Vo\BchAmount;
use Amashukov\BchnRpc\Vo\PsbtOutput;
use Amashukov\HttpClient\CurlClient;
use Nyholm\Psr7\Factory\Psr17Factory;

$psr17  = new Psr17Factory();
$node   = new BchnRpcClient(new CurlClient($psr17, $psr17, timeoutSeconds: 30), $psr17, $psr17, 'http://127.0.0.1:8332', 'rpcuser', 'rpcpassword');
$wallet = $node->withWallet('hot-wallet');

$node->getBlockchainInfo()->blocks;
$wallet->getWalletInfo()->balance->satoshis;

$address = $wallet->getNewAddress('deposit');
$info    = $wallet->getAddressInfo($address);        // ismine, hdkeypath

foreach ($wallet->listSinceBlock($lastBlock, 6)->transactions as $entry) {
    // $entry->txid, $entry->vout, $entry->address, $entry->amount->satoshis, $entry->confirmations
}

$utxos = $wallet->listUnspent(1, 9999999, [], true, includeTokens: false);
$psbt  = $wallet->createPsbt([$utxos[0]->outpoint], [PsbtOutput::payTo('bitcoincash:qr7fzmep8g7h7ymfxy74lgc0v950j3r2959lhtxxsl', BchAmount::fromSatoshis(10_000))]);
$signed = $wallet->walletProcessPsbt($psbt);                // sighash ALL|FORKID
$final  = $wallet->finalizePsbt($signed->psbt);

if ($wallet->testMempoolAccept((string) $final->hex)->allowed) {
    $txid = $wallet->sendRawTransaction((string) $final->hex);
}

$tx  = $node->getRawTransaction($txid);
$fee = $tx->fee();                                         // ?BchAmount
$satPerByte = $node->estimateFee();                        // int, rounded up
$score = $node->getDsProofScore($txid);                    // 0.0 … 1.0

Methods

Method BCHN call
getBlockchainInfo() getblockchaininfo
getWalletInfo() getwalletinfo
createWallet(name, disablePrivateKeys, blank, passphrase) createwallet
loadWallet(name) loadwallet
getNewAddress(label) getnewaddress
getAddressInfo(address) getaddressinfo
listSinceBlock(blockHash, targetConfirmations, includeWatchOnly, includeRemoved, includeChange, label) listsinceblock
listUnspent(minconf, maxconf, addresses, includeUnsafe, includeTokens) listunspent
listLockUnspent() / lockUnspent(unlock, outpoints) listlockunspent / lockunspent
getTransaction(txid, includeWatchOnly) gettransaction
getRawTransaction(txid, blockHash) getrawtransaction (verbosity 2, falls back to 1 when prevouts are unavailable)
getMempoolEntry(txid) getmempoolentry (null when not in the mempool)
decodeRawTransaction(hex) decoderawtransaction
getTxOut(txid, vout, includeMempool) gettxout (null when spent)
createPsbt / walletProcessPsbt / finalizePsbt / decodePsbt PSBT calls
testMempoolAccept(hex, allowHighFees) / sendRawTransaction(hex, allowHighFees) broadcast
estimateFee() estimatefee, converted to sat/byte
walletPassphrase / walletLock / backupWallet wallet security
getDsProofScore(txid) getdsproofscore

BCHN has no getbalances; the confirmed, unconfirmed and immature balances come from getWalletInfo().

Requirements

  • PHP 8.3+ on a 64-bit build
  • A PSR-18 client + PSR-17 request / stream factories

Related packages

Package Role
amashukov/cashaddr-php CashAddr codec and typed address value object
amashukov/bitcoin-cash-php Bitcoin Cash meta-package
amashukov/http-client-php PSR-18 cURL client + retry / header-injection middleware

Quality

  • PHPStan level 9, clean.
  • php-cs-fixer @PER-CS ruleset.
  • GitHub Actions CI on every push.
  • Every method is pinned by a test against a fixture shaped like the BCHN reference output.

License

MIT — see LICENSE.