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

bip38-messages

v1.2.0

Published

BIP38 wallet utility for loading encrypted keys and creating Bitcoin transactions with OP_RETURN messages

Readme

BIP38 Messages - Bitcoin Wallet Utility

A command-line utility for loading BIP38 encrypted wallets and creating Bitcoin transactions with OP_RETURN messages. Designed for use with Ballet Real Bitcoin cards and other SegWit wallets.

Features

  • BIP38 Key Decryption - Decrypt encrypted private keys (6P... format)
  • SegWit Support - Native SegWit (P2WPKH) addresses (bc1q... format)
  • OP_RETURN Messages - Embed messages in Bitcoin transactions
  • Automatic UTXO Fetching - No need to manually provide UTXOs!
  • Automatic Broadcasting - Transactions broadcast automatically!
  • Ballet Card Compatible - Works with Ballet Real Bitcoin cards
  • Environment Variables - Secure key management via .env files
  • CLI Interface - Easy-to-use command-line scripts

Installation

npm install
npm run build

Quick Start

1. Set Up Environment Variables (Optional)

Create a .env file:

PRIVATE_KEY=6PnXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PASSPHRASE=your-secret-passphrase

2. Load Your Wallet

# Using command-line arguments
npm run wallet:load -- --private-key 6Pn... --passphrase "your-passphrase"

# Using environment variables
npm run wallet:load -- --env-vars PRIVATE_KEY,PASSPHRASE

# Mix of both (env var for key, CLI for passphrase)
npm run wallet:load -- --env-vars PRIVATE_KEY --passphrase "your-passphrase"

3. Create and Broadcast a Transaction

That's it! Everything is automatic - UTXOs fetched, transaction signed and broadcast! 🎉

# Send BTC with a message (auto-fetched UTXOs + auto-broadcast!)
npm run wallet:transact -- --to bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh --amount 0.0001 --message "Hello Bitcoin" --env-vars PRIVATE_KEY,PASSPHRASE

# Message-only transaction (amount defaults to 0)
npm run wallet:transact -- --to bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh --message "Storage test" --env-vars PRIVATE_KEY,PASSPHRASE

# Sign only (don't broadcast) - for manual review
npm run wallet:transact -- --to bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh --amount 0.0001 --sign-only --env-vars PRIVATE_KEY,PASSPHRASE

The tool will automatically:

  • Query the blockchain for your UTXOs
  • Show your balance
  • Select optimal UTXOs for the transaction
  • Create and sign the transaction
  • Broadcast to the network (unless --sign-only is used)
  • Display the transaction ID and explorer link

Commands

wallet:load

Loads a BIP38 encrypted wallet and displays the address.

Usage:

npm run wallet:load -- [options]

Options:

  • -k, --private-key <key> - BIP38 encrypted private key (starts with 6P)
  • -p, --passphrase <passphrase> - Passphrase to decrypt the BIP38 key (optional)
  • -e, --env-vars <vars> - Environment variable names (comma-separated, up to 2)
  • -n, --network <network> - Bitcoin network: mainnet or testnet (default: mainnet)
  • -h, --help - Display help

Examples:

# Load from command-line
npm run wallet:load -- --private-key 6PnXXX... --passphrase "secret"

# Load from environment variables
npm run wallet:load -- --env-vars PRIVATE_KEY,PASSPHRASE

# Load from environment, override passphrase
npm run wallet:load -- --env-vars PRIVATE_KEY --passphrase "different-secret"

# Testnet wallet
npm run wallet:load -- --private-key 6PnXXX... --passphrase "secret" --network testnet

Output:

✅ Wallet loaded successfully!

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📍 Address:      bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh
🔑 Public Key:   02a1b2c3d4...
🌐 Network:      mainnet
💳 Type:         P2WPKH (Native SegWit)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

wallet:transact

Creates a Bitcoin transaction with optional OP_RETURN message.

Usage:

npm run wallet:transact -- [options]

Options:

  • -t, --to <address> - Required - Recipient Bitcoin address (bc1q...)
  • -a, --amount <amount> - Amount to send in BTC (default: 0)
  • -m, --message <message> - Message to store using OP_RETURN (max 80 bytes)
  • -k, --private-key <key> - BIP38 encrypted private key (starts with 6P)
  • -p, --passphrase <passphrase> - Passphrase to decrypt the BIP38 key
  • -e, --env-vars <vars> - Environment variable names (comma-separated, up to 2)
  • -n, --network <network> - Bitcoin network: mainnet or testnet (default: mainnet)
  • --utxos <utxos> - JSON string of UTXOs to spend (optional - auto-fetched if not provided)
  • -s, --sign-only - Only sign transaction without broadcasting (output hex for manual broadcast)
  • -h, --help - Display help

Note:

  • UTXOs are automatically fetched from the blockchain!
  • Transactions are automatically broadcast unless --sign-only is used!

Examples:

# Send BTC with message
npm run wallet:transact -- \
  --to bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh \
  --amount 0.0001 \
  --message "This will be stored using OP_RETURN" \
  --env-vars PRIVATE_KEY,PASSPHRASE

# Message-only transaction
npm run wallet:transact -- \
  --to bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh \
  --message "Storage only" \
  --private-key 6PnXXX... \
  --passphrase "secret"

# Send BTC without message
npm run wallet:transact -- \
  --to bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh \
  --amount 0.00005 \
  --env-vars PRIVATE_KEY,PASSPHRASE

# With UTXOs for broadcasting
npm run wallet:transact -- \
  --to bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh \
  --amount 0.0001 \
  --message "Hello" \
  --env-vars PRIVATE_KEY,PASSPHRASE \
  --utxos '[{"txid":"abc123...","vout":0,"value":100000}]'

UTXO Format:

[
  {
    "txid": "transaction_id_here",
    "vout": 0,
    "value": 100000
  }
]

Where:

  • txid - Transaction ID of the unspent output
  • vout - Output index (usually 0 or 1)
  • value - Amount in satoshis (100,000 satoshis = 0.001 BTC)

Output (with auto-broadcast):

🔐 Preparing transaction...

✅ Wallet loaded
📍 From:        bc1q...
📍 To:          bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh
💰 Amount:      0.0001 BTC
💬 Message:     This will be stored using OP_RETURN

📡 Broadcasting transaction to network...

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Transaction broadcast successfully!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

📄 Transaction ID (TXID):
abc123def456...

🔗 View on Blockstream:
https://blockstream.info/tx/abc123def456...

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💡 Transaction is now in the mempool
   It will be confirmed in the next block
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Output (with --sign-only):

🔐 Preparing transaction...

✅ Wallet loaded
📍 From:        bc1q...
📍 To:          bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh
💰 Amount:      0.0001 BTC

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Transaction created and signed!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

📄 Signed Transaction Hex:

0200000001...

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💡 Sign-only mode: Transaction not broadcast
   To broadcast manually:
   1. bitcoin-cli sendrawtransaction <hex>
   2. Or visit: https://blockstream.info/tx/push
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Automatic UTXO Fetching

Good news! UTXOs are now automatically fetched from the blockchain when you create a transaction. You don't need to manually provide them anymore!

The tool will:

  • ✅ Automatically query Blockstream API for your address
  • ✅ Select optimal UTXOs for your transaction
  • ✅ Display your balance before creating the transaction
  • ✅ Handle both mainnet and testnet

Manual UTXO Provision (Optional)

If you want to manually specify which UTXOs to use, you still can:

Using Bitcoin CLI:

bitcoin-cli listunspent 1 9999999 '["bc1qYOUR_ADDRESS_HERE"]'

Using Block Explorers:

  • Blockstream (Mainnet): https://blockstream.info/address/YOUR_ADDRESS
  • Blockstream (Testnet): https://blockstream.info/testnet/address/YOUR_ADDRESS

Using APIs:

# Blockstream API (Mainnet)
curl https://blockstream.info/api/address/bc1qYOUR_ADDRESS/utxo

# Blockstream API (Testnet)  
curl https://blockstream.info/testnet/api/address/YOUR_ADDRESS/utxo

Environment Variables

The utility supports loading keys and passphrases from environment variables for security.

Setting Up .env:

# Your BIP38 encrypted private key (starts with 6P)
PRIVATE_KEY=6PnXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

# Your passphrase for decrypting the BIP38 key
PASSPHRASE=your-secret-passphrase-here

Using Environment Variables:

The --env-vars flag accepts up to 2 comma-separated variable names:

  1. First variable: Private key (required)
  2. Second variable: Passphrase (optional)
# Both from environment
npm run wallet:load -- --env-vars PRIVATE_KEY,PASSPHRASE

# Only private key from environment
npm run wallet:load -- --env-vars PRIVATE_KEY --passphrase "cli-passphrase"

# Custom variable names
npm run wallet:load -- --env-vars MY_KEY,MY_PASS

Ballet Real Bitcoin Cards

This utility is designed to work with Ballet Real Bitcoin physical cryptocurrency cards. These cards use:

  • BIP38 Encryption - Private keys are encrypted with a passphrase
  • SegWit Addresses - Native SegWit (P2WPKH) format (bc1q...)
  • Physical Security - Cards have tamper-evident stickers

How to Use with Ballet Cards:

  1. Find Your Encrypted Key - Scratch off the passphrase panel and private key panel
  2. Load the Wallet - The private key starts with 6P...
  3. Decrypt - Use the passphrase from the card
  4. Transact - Create transactions using the loaded wallet
npm run wallet:load -- --private-key 6Pn... --passphrase "062T-..."

Technical Details

Address Types

This utility generates P2WPKH (Pay to Witness Public Key Hash) addresses:

  • Format: bc1q... (mainnet) or tb1q... (testnet)
  • Type: Native SegWit
  • Benefits: Lower fees, better privacy, increased security

OP_RETURN Messages

OP_RETURN is a Bitcoin script opcode used to store data on the blockchain:

  • Maximum size: ~80 bytes
  • Non-spendable output (data only)
  • Use cases: Timestamping, proof of existence, short messages

Transaction Structure

Inputs:  UTXOs from your address
Outputs: 
  - Recipient output (if amount > 0)
  - OP_RETURN output (if message provided)
  - Change output (back to your address)

Security Notes

⚠️ Important Security Considerations:

  1. Never share your private key or passphrase
  2. Use environment variables for sensitive data, not command-line arguments
  3. The .env file should never be committed to version control (already in .gitignore)
  4. Test with small amounts first on testnet
  5. Verify addresses before sending real BTC
  6. This tool does NOT broadcast transactions - you must do that separately

Development

Project Structure

bip38-messages/
├── src/
│   ├── lib/
│   │   └── wallet.ts          # Core wallet functions
│   ├── cli/
│   │   ├── wallet-load.ts     # Load wallet command
│   │   └── wallet-transact.ts # Transaction command
├── dist/                       # Compiled JavaScript
├── package.json
├── tsconfig.json
└── README.md

Building

npm run build

Running with tsx (Development)

npx tsx src/cli/wallet-load.ts --help
npx tsx src/cli/wallet-transact.ts --help

Troubleshooting

"Passphrase required for encrypted BIP38 keys"

  • Ensure you provide a passphrase for encrypted keys (starting with 6P)
  • Use --passphrase flag or second env var in --env-vars

"Invalid private key format"

  • Check that your key starts with 6P for BIP38
  • Or provide a valid WIF format key

"No UTXOs provided"

  • You need to query your address for unspent outputs
  • Use Bitcoin CLI or block explorer APIs
  • Provide UTXOs using --utxos flag

"Message too long"

  • OP_RETURN messages are limited to ~80 bytes
  • Keep your messages short

Future Enhancements

  • [ ] Support for additional address types (P2PKH, P2SH-P2WPKH)
  • [ ] Built-in UTXO fetching from block explorers
  • [ ] Automatic transaction broadcasting
  • [ ] Multi-signature support
  • [ ] Hardware wallet integration
  • [ ] QR code generation for addresses

License

MIT

Disclaimer

This software is provided "as is", without warranty of any kind. Use at your own risk. Always test with small amounts first.