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

bwalletx

v0.5.0

Published

bWalletX CLI and MCP server: run bWalletX agent accounts from the command line

Readme

bwalletx: the bWalletX CLI and MCP server

Run bWalletX agent accounts from the command line or from any MCP client (Claude Desktop, Claude Code, Cursor). v1 is standalone mode: the CLI holds one agent account's exported key file, encrypted with a passphrase. Paired mode (scoped tokens from the app) comes later; bwalletx login says so.

Only agent accounts can be exported, never the main wallet. The agent account's balance is the budget.

Install

npm i -g bwalletx      # Node 20+

Pair with your phone (recommended)

Keys stay on your phone. In bWalletX (5.1.40+), open your agent account, then run:

bwalletx login --account phone

Scan the QR in the terminal from bWalletX (Settings › Paired websites › Scan to connect), check both screens show the same 4-digit code, choose what the CLI may do (see balances; buy and load strategies; send BSV) and for how long (1, 7 or 30 days), then tap Pair. Every command for that account becomes an end-to-end encrypted request: bWalletX checks it against the account's Stop switch, daily cap and loaded strategy, then signs it. Keep bWalletX open on that account while the CLI works. Disconnect any time in the app (Settings › Paired websites) or with bwalletx logout --account phone.

For unattended servers where no phone is around, import a key file instead (below).

Install (from source)

git clone <this repo> bwalletx-cli && cd bwalletx-cli
pnpm install
pnpm build
pnpm link --global      # puts `bwalletx` on your PATH (or run `node dist/cli.js`)

Node 20+ required.

Import an agent account

In bWalletX: Settings › Agents › account › Export key file. Then:

bwalletx key import ./trader.key.json     # asks for the passphrase (or set BWALLETX_PASSPHRASE)
bwalletx accounts

The file is checked by decrypting it once, then stored still encrypted at ~/.bwalletx/accounts/<name>.key.json (mode 600). Keys are only decrypted in memory, when a live transaction is signed. Set BWALLETX_HOME to keep state somewhere other than ~/.bwalletx.

Key file format (bwalletx.agentkey/1)

{"format":"bwalletx.agentkey/1","name":"trader","identityAddress":"1…",
 "enc":{"kdf":"pbkdf2-sha256","iter":310000,"salt":"<b64 16 bytes>","iv":"<b64 12 bytes>",
        "alg":"aes-256-gcm","data":"<b64 ciphertext || 16-byte GCM tag>"}}

data decrypts to {"payPk":WIF,"ordPk":WIF,"identityPk":WIF}. PBKDF2-SHA256 over the UTF-8 passphrase → AES-256-GCM, tag appended to the ciphertext exactly as WebCrypto returns it. src/keyfile.ts (encryptKeyFile / decryptKeyFile) uses only crypto.subtle, so the app can use the same code.

Commands

bwalletx balance --account trader                 # BSV + BSV-21 tokens, valued in USD
bwalletx price <tokenId>                          # floor price, USD per token
bwalletx send 5 [email protected] --account trader   # $5 of BSV to a paymail or address
bwalletx buy <tokenId> --max-usd 2 --account trader
bwalletx list <outpoint> --price 50000 -a trader  # list an ordinal / OpNS name / BSV-21 output on the 1Sat order book
bwalletx unlist <outpoint> -a trader              # cancel it; the item comes back to the wallet
bwalletx listings -a trader                       # your open listings, price and live status
bwalletx buy-listing <outpoint> -a trader         # buy one listing (ordinal or BSV-21) by outpoint
bwalletx strategy load ./accumulator.json --account trader          # paper ($100 pretend book)
bwalletx strategy load ./accumulator.json --account trader --live   # real money
bwalletx strategy show | unload
bwalletx agent run trader --interval 300          # rule-driven loop; Ctrl-C to stop
bwalletx log --account trader                     # ~/.bwalletx/log/trader.jsonl
bwalletx stop                                     # kill switch: refuse all spending
bwalletx resume
bwalletx cap trader 10                            # optional $10/day cap ("off" to clear)
bwalletx mcp                                      # stdio MCP server

Add --json for machine-readable output. send asks for confirmation on a terminal; -y skips it.

Token ids are BSV-21 ids (txid_vout). send moves BSV, so when a strategy is loaded its rules.tokens must include "BSV", actions must include "send", and the recipient must be in sendTo.

BRC-100 wallet for sites (serve)

A standalone agent account can act as a full BRC-100 wallet, so any BRC-100 site or script can use it: launchpads, games, anything that asks for createAction, signAction, createSignature, listOutputs.

bwalletx brc100 fund      -a trader                      # move the pay address's BSV into the BRC-100 wallet
bwalletx serve            -a trader --origin www.tokenblaster.lol localhost:3000
bwalletx brc100 balance   -a trader
bwalletx brc100 withdraw all 1YourAddress… -a trader     # take it back out

By default the BRC-100 wallet is the CLI's own (pay-key root, ~/.bwalletx/brc100/<account>.sqlite); fund it with brc100 fund, which also collects from the receive addresses the app shows. --shared opens the account's own bWalletX wallet instead (identity-key root, 1Sat Storage https://wallet.1sat.app as the active store). Use it only if the app uses that remote as the account's active storage: bWallet normally keeps the phone's local store active and only backs up every 5 minutes, so the two would drift. brc100 migrate moves the CLI wallet's balance into it.

serve listens on http://localhost:3321, where BRC-100 sites already look for a desktop wallet, so they find it the same way they find BSV Desktop. Built on @bsv/wallet-toolbox; keys are decrypted into memory only.

  • Allowlist: only the hosts given with --origin get an answer; everyone else gets 403.
  • The gate: every createAction is checked like a send for the BSV it takes out of the account (its outputs minus what the site's own inputs bring in), so the kill switch, daily cap, rate limit and a loaded strategy all apply. Refusals reach the site as a readable wallet error.
  • Log: every spend and signature lands in the activity log with the site and txid.
  • Paired accounts can't serve: their keys stay on the phone.

The gate

Every spending action, from the CLI, agent run or MCP, passes the same checks in this order:

  1. Kill switch (bwalletx stop, file ~/.bwalletx/STOP) or the account is stopped
  2. Daily cap for the account (if set)
  3. Rate limit: at most 30 spending actions per hour per account (paper and failed attempts count)
  4. Strategy rules (bwalletx.strategy/1; same parseStrategy / checkRules / paperFill as the app)
  5. Paper mode fills on the paper book and never signs

Every refusal is logged with the rule that refused it.

Strategies

Same format as the app; see docs/STRATEGY-FORMAT.md in the bWalletX repo. Example:

{
  "format": "bwalletx.strategy/1",
  "name": "Slow accumulator",
  "version": "1.0",
  "goals": "Build a position slowly while the price is low.",
  "rules": {
    "tokens": ["<bsv21 id txid_vout>"],
    "actions": ["buy"],
    "buyBelowUsd": 0.001,
    "maxPerTradeUsd": 2,
    "maxPerDayUsd": 10,
    "maxTotalUsd": 200,
    "stop": { "holdTokens": 100000 }
  }
}

agent run needs no AI: each tick, for every BSV-21 id in rules.tokens, if buy is allowed and the floor price is at or below buyBelowUsd, it asks to buy maxPerTradeUsd worth. The gate decides.

Live vs paper

| Action | Paper | Live | | --- | --- | --- | | balance, price, log | yes | yes (read-only) | | send BSV (address or paymail) | yes | yes: P2PKH from the pay key, WhatsOnChain UTXOs, ARC (GorillaPool) broadcast with WhatsOnChain fallback; paymail via P2P destinations or basic paymentDestination | | buy BSV-21 | yes (fills at the floor on the paper book) | yes: takes the cheapest whole 1Sat OrdLock (v1) listing that fits --max-usd and that the 1Sat overlay holds as valid; pays the seller exactly as the lock encodes, adds the 1% bWalletX market fee and (when active) the overlay fee, sends the tokens to the ord address, change to the pay address. Every input script is verified locally before broadcast. OrdLock v2 listings: not yet (use the app) |

Live sends sign with the account's key file; set BWALLETX_PASSPHRASE for unattended use (MCP, servers). 1-sat outputs are never spent as fee money, so ordinals and tokens on the pay address are safe.

bwalletx buy <tokenId> --max-usd 5 shows the exact totals (seller, market fee, overlay fee, network fee) and asks before broadcasting; -y or BWALLETX_YES=1 skips the prompt. The gate sees the full dollar cost including fees. --dry-run builds and verifies the purchase against the real listing with throwaway keys and a synthetic funding coin, without touching your account or broadcasting.

Selling and listing (1Sat order book)

bwalletx list <outpoint> --price <sats> [--amount <n>] [-a account] [--yes] [--dry-run]
bwalletx unlist <outpoint> [-a account] [--yes] [--dry-run]
bwalletx listings [-a account]
bwalletx buy-listing <outpoint> [--max-usd <n>] [-a account] [--yes] [--dry-run]

These run on a key-file account's own BRC-100 wallet (the same local wallet opns and brc100 use; fund it with bwalletx brc100 fund). Paired accounts are refused, because their keys stay on the phone. The transactions are built by the same @1sat/actions code the bWalletX app uses:

  • list: finds <outpoint> among the wallet's ordinals, OpNS names and BSV-21 tokens and lists it with OrdLock v2 for --price sats (the whole listing). Ordinals go through sellOrdinal and names through sellOpns. BSV-21 tokens are sent to a listing script (a transfer inscription around an OrdLock v2), as the app's sell sheet does; --amount lists part of the output (whole tokens, at the token's decimals). Proceeds go to the wallet's default 1Sat pay address. The token cancel key is recorded in ~/.bwalletx/listings-<account>.json. It is derived from the token id, so it can be re-derived if that file is lost.
  • unlist: cancels a listing the wallet tracks (cancelOrdinalListing, cancelTokenListing, cancelOpnsListing) or a recorded BSV-21 listing (signed with its cancel key). The item returns to the wallet.
  • listings: OrdLock outputs in the wallet plus recorded BSV-21 listings, with price and live / gone (sold or cancelled) from the 1Sat index.
  • buy-listing <outpoint>: decodes the listing (v1 or v2, ordinal or BSV-21) and buys it with buyOrdinal / buyBsv21: the seller price, plus the 1% bWalletX market fee, plus the overlay fee for tokens. --max-usd refuses it if the total is higher. This is a separate command from buy <tokenId> --max-usd, which is unchanged.

Every spend asks for confirmation and shows the price and fees. -y or BWALLETX_YES=1 skips the prompt, for scripts. Each one passes the gate: buy-listing with its full dollar cost, and list / unlist as a $0 list action (kill switch, rate limit, strategy rules). A paper-mode strategy refuses these commands. --dry-run runs the real builder against a wallet that records the createAction it is asked for and refuses it. You see the inputs and outputs it would have made, and nothing is signed or broadcast. A dry run still opens the wallet, so it asks for the passphrase.

OpNS: mint whole name lists unattended

bwalletx opns mint lists/*.txt --vault keep.txt --gift gift.txt --to <ordinals address> --budget 72000000 -a opns
bwalletx opns status -a opns      # progress, spent, ETA (also ~/.bwalletx/opns-batch-<account>.html)
bwalletx opns sweep --to <address> -a opns   # cancel unsold listings, send names + remaining sats to the owner
bwalletx opns bench               # proof-of-work speed on this machine

Mines every name from the agent account's own BRC-100 wallet, alphabetically (prefixes reused), re-checking each name right before it is mined; vault/gift names are locked straight to --to, the rest are listed with OrdLock v2 at $1 / $5 / $15 by length. Resumable (~/.bwalletx/opns-batch-<account>.json), stops before going over --budget, Ctrl-C stops cleanly. Proof of work runs on worker threads. The covenant code is shared with bWalletX (src/opns/opns*.ts, copied with attribution). Owner runbook: docs/OPNS-HEADLESS.md.

MCP

Tools (reads are free; anything that spends passes the gate above, paper mode never signs, live key-file accounts need BWALLETX_PASSPHRASE in the MCP env, paired accounts sign on the phone):

| Tool | What it does | |------|--------------| | accounts | list accounts and loaded strategies | | balance | BSV and BSV-21 balances in USD | | price | floor price of a BSV-21 token | | send | send BSV worth usd (gated) | | buy | buy a BSV-21 token for at most maxUsd (gated) | | list_for_sale | list an ordinal / OpNS name / BSV-21 output on the 1Sat order book (OrdLock v2; gated as list; dryRun builds only) | | unlist | cancel one of the account's listings (dryRun builds only) | | listings | the account's open listings with price and live status | | buy_listing | buy one listing by outpoint, like buy-listing (+1% market fee; gated as buy; optional maxUsd; dryRun builds only) | | strategy_show | the loaded strategy, mode and paper book | | strategy_load | load a strategy file, always in paper mode | | log | recent activity log entries | | stop_all | kill switch: refuse every spending action | | brc100_balance | BRC-100 wallet balance (wallet: local or shared) | | brc100_addresses | pay address + app receive addresses (key-file accounts only) | | brc100_fund | move the account's own pay/receive BSV into its own BRC-100 wallet (no money leaves; logged; refused while stopped) | | brc100_withdraw | send usd (or "all") from the BRC-100 wallet to an address (gated like send; paper refuses; logged; ARC relay) | | mint, mint_manifest | mint files / a manifest as NFTs on a paired phone (the phone signs within its pairing's mint limits; refused while stopped; dryRun estimates only) | | pairing_status | whether an account is paired and how (agent or brc100 main wallet), scopes, expiry, limits; never secrets | | serve_status | whether something listens on the serve port (3321) |

Human-only, never exposed over MCP: cap changes, resume, strategy load --live, key import, pair / login / logout, brc100 migrate, and starting/stopping serve. They loosen safety settings, change trust or key material, or need a person at the terminal or phone. An agent can stop things (stop_all) but never turn them back on or raise its own limits.

Claude Code

claude mcp add bwalletx -e BWALLETX_PASSPHRASE=your-passphrase-here -- bwalletx mcp

Claude Desktop (claude_desktop_config.json) and Cursor (~/.cursor/mcp.json):

{
  "mcpServers": {
    "bwalletx": {
      "command": "bwalletx",
      "args": ["mcp"],
      "env": { "BWALLETX_PASSPHRASE": "your-passphrase-here" }
    }
  }
}

Leave out BWALLETX_PASSPHRASE to keep MCP read-only and paper-only: live sends then fail with "No passphrase". If bwalletx isn't on the PATH, use "command": "node", "args": ["/path/to/bwalletx-cli/dist/cli.js", "mcp"].

Development

pnpm build
pnpm test      # keyfile round-trip, strategy rules, gate order, rate limit, paper book, offline send signing

Tests use freshly generated throwaway keys only.