npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@coldai/clip-wallet-chains-bitcoincash

v0.2.0

Published

Bitcoin Cash ChainModule for Clip Wallet: builds and decodes transactions in plain words; never touches keys

Readme

@coldai/clip-wallet-chains-bitcoincash

Bitcoin Cash ChainModule for Clip Wallet. It builds and decodes BCH transactions in plain words and never touches keys. prepare() returns one 32-byte BCH sighash per input the account signs; finalize() checks each signature with secp256k1.verify, DER-encodes it with the sighash byte 0x41, builds the P2PKH unlocking bytecode and broadcasts through Fulcrum when the request asks for it.

Everything is hand-written with @noble/hashes and @noble/curves (verification only): CashAddr, the transaction format with CashTokens prefixes, the BCH signing serialization, DER, the Electrum Cash client. @bitauth/libauth 3 is a dev dependency: the tests compare our addresses, transaction bytes and sighashes with it and run every signed transaction through its BCH 2023 virtual machine (createVirtualMachineBCH().verify).

Networks

| NetworkId (CAIP-2) | network | prefix | WalletConnect (wc2-bch-bcr) | Fulcrum (wss, in order) | explorer | |---|---|---|---|---|---| | bip122:00000000040ba9641ba98a37b2e5ceea | chipnet (default test network) | bchtest | bch:bchtest | chipnet.imaginary.cash:50004, chipnet.bch.ninja:50004, chipnet.c3-soft.com:64004, cbch.loping.net:62104 | https://cbch.loping.net | | bip122:000000001dd410c49a788668ce267517 | testnet4 | bchtest | bch:bchtest | testnet4.imaginary.cash:50004, tbch4.loping.net:62004 | https://tbch4.loping.net | | bip122:000000000000000000651ef99cb9fcbe | mainnet | bitcoincash | bch:bitcoincash | bch.imaginary.cash:50004, electrum.imaginary.cash:50004, bch.loping.net:50004, bch.soul-dev.com:50004 | https://bch.loping.net |

  • Ids: BIP-122 / ChainAgnostic bip122 (first 32 hex of a block hash). BCH shares Bitcoin's genesis, so the namespace's own test case names BCH mainnet by its first block after the split (478559). Chipnet is named the same way by its first block after it left testnet4 (115252, found by comparing both chains' headers on Fulcrum); testnet4 by its genesis. None collides with chains-bitcoin.
  • The BCH wallet community's WalletConnect spec uses bch:bitcoincash and bch:bchtest (any testnet) instead: BCH_NETS[n].wcChain, and 1Mask's BCH_WC_CHAINS maps them (bchtest → chipnet).
  • Every Fulcrum server above answered server.version (Fulcrum 2.1.x, protocol 1.4), blockchain.scripthash.get_balance, blockchain.headers.get_tip and blockchain.relayfee (2026-10). They're tried in order; the next one is used when one can't be reached. Calls: blockchain.scripthash.get_balance, listunspent (with token_data), blockchain.relayfee, blockchain.transaction.broadcast.
  • Faucet: https://tbch.googol.cash (testnet3, testnet4 and chipnet): no account, but a simple image captcha (type the sum of the numbers shown).

Assets: BCH is bch (8 decimals). Fungible CashTokens are cashtoken:<category> (no metadata registry is trusted, so they show as CT-<first 6 hex> with 0 decimals). getNfts returns [].

Accounts and addresses

  • derivationPath(i) = m/44'/145'/0'/0/i (Electron Cash, Paytaca, Cashonize), secp256k1, the same key on every network.
  • P2PKH CashAddr, spelled per network: bitcoincash:q… on mainnet, bchtest:q… on chipnet / testnet4. Account.address is the mainnet form; receiveAddress(ctx) / addressFromPublicKey(key, network) give the network's. Fixtures: "abandon … about" → bitcoincash:qqyx49mu…tahq3q6, as libauth encodes it.
  • isAddress accepts CashAddr P2PKH / P2SH (20 and 32-byte) and the token-aware z… / r… forms, with or without the prefix, checksum verified; mixed case and legacy base58 (1…, 3…, which Bitcoin uses too) are refused.

Sending (buildTransfer)

  • Coins from listunspent, largest first. A coin that carries CashTokens is never spent by a plain BCH send (it would burn the tokens).
  • Fee: the server's relay fee (1 sat/byte on every network today), at least minFeeRate (default 1). Size estimate 148 bytes per P2PKH input, 34 per output, 10 overhead.
  • Dust limit 546 sats: smaller sends are refused; change under it goes to the fee.
  • Change goes back to the same address (the account's one P2PKH address; there is no change chain). Electron Cash and Paytaca will see it like any other coin of that address.
  • The request is a bch_signTransaction with the unsigned transaction hex, the coins as libauth-stringified source outputs and broadcast: true, so wallet sends and app requests go through the same decoder.

Methods (BCH_METHODS, wc2-bch-bcr)

| method | params | result | |---|---|---| | bch_signTransaction | { transaction: hex \| libauth Transaction \| stringify(Transaction), sourceOutputs: (stringified) libauth source outputs, broadcast? = true, userPrompt? } | { signedTransaction: hex, signedTransactionHash: txid } | | bch_signMessage | { message, userPrompt? } | base64 compact signature (Electron Cash format) | | bch_getAddresses | (answered by 1Mask, not the module) | ["bchtest:q…"] |

  • Signs every input whose source output is this account's P2PKH and whose unlocking bytecode is empty. Other inputs (CashScript contracts, other people) are left as the app sent them.
  • wc2-bch-bcr's zero-filled pubkey (33 bytes) / Schnorr signature (65 bytes) placeholders for CashScript contract arguments are refused in plain words (bitcoincash/unsupported-contract): the vault signs ECDSA only.
  • Source outputs must match the inputs one to one (same outpoints, same order) or the request is unreadable (blind).
  • Refusals: other network → bitcoincash/network-mismatch; no input of ours → bitcoincash/not-a-signer.

What gets signed (prepare)

  • Inputs: double SHA-256 of version ‖ hashPrevouts ‖ hashSequence ‖ outpoint ‖ the spent output's token prefix ‖ scriptCode (our P2PKH) ‖ value ‖ sequence ‖ hashOutputs ‖ locktime ‖ 41 00 00 00 (SIGHASH_ALL | FORKID, fork id 0). The token prefix and the value are committed, so an app can't lie about our coins.
  • Messages: double SHA-256 of CompactSize(24) ‖ "Bitcoin Signed Message:\n" ‖ CompactSize(len) ‖ message; answered as base64(27 + recovery + 4 ‖ r ‖ s).

Decoding

"Send 0.0003 BCH to qp8sfd…q4lg", one line per recipient (tokens included), "You get back" for change to this address, the network fee, data outputs (OP_RETURN), the app's contract name and prompt (marked unverified), how many inputs belong to others. Balance changes are this account's BCH in − out and token amounts. CashTokens leaving the wallet get a caution. A fee above 20 sat/byte (and 10,000 sats) is a "high fee" caution.

Dapp connectivity

There's no injected-provider standard for BCH (Paytaca's extension injects its own window.paytaca, which another wallet mustn't imitate). Dapps reach wallets over WalletConnect v2 with wc2-bch-bcr, where the wallet shows up under its own metadata. In @coldai/clip-wallet-1mask the WalletConnect session layer serves the bch namespace: proposals for bch:bitcoincash / bch:bchtest map onto the bip122 networks (networkIdForWcChain), session accounts are bch:<CashAddr> spelled for the chain (as Cashonize builds them), bch_getAddresses is answered from the session, the signing methods reach this module unchanged, and addressesChanged carries the CashAddrs.

Not supported (yet)

Sending CashTokens, CashScript placeholders (Schnorr), P2SH spending, NFTs in getNfts, BCMR token metadata.