| name | berrypay |
| description | Manage Nano (XNO) cryptocurrency wallet operations using BerryPay CLI. Use for checking balance, sending/receiving XNO, creating payment charges with webhooks, generating QR codes, and processing payments with automatic sweeping. |
BerryPay CLI - AI Agent Skill Guide
BerryPay is a Nano (XNO) cryptocurrency wallet CLI designed for AI agents. It provides passwordless operation, JSON output for parsing, and a payment processor for accepting payments with automatic sweeping.
Quick Reference
| Task | Command |
|---|
| Check balance | berrypay balance |
| Get address | berrypay address |
| Send XNO | berrypay send <address> <amount> --yes |
| Receive pending | berrypay receive |
| Create charge | berrypay charge create <amount> --webhook <url> |
| Check charge | berrypay charge status <id> |
| List charges | berrypay charge list |
Installation & Setup
Install globally
npm install -g berrypay
Initialize wallet (first time only)
berrypay init
This creates a new wallet with a random seed stored in ~/.berrypay/config.json.
Or use environment variable (recommended for agents)
export BERRYPAY_SEED=<64-character-hex-seed>
When BERRYPAY_SEED is set, it overrides the config file. This is the recommended approach for AI agents.
Import existing seed
berrypay import <64-character-hex-seed>
Environment Variables
| Variable | Description | Default |
|---|
BERRYPAY_SEED | 64-char hex seed (overrides config) | - |
BERRYPAY_RPC_URL | Nano RPC node URL | https://uk1.public.xnopay.com/proxy |
BERRYPAY_WS_URL | WebSocket URL for confirmations | wss://uk1.public.xnopay.com/ws |
Core Wallet Commands
Get Wallet Address
berrypay address
Output:
{
"address": "nano_1abc...",
"index": 0
}
With QR code (for sharing/display):
berrypay address --qr
Displays QR code in terminal.
Save QR code as PNG image:
berrypay address --qr --output /path/to/qr.png
Creates a 400x400 PNG image of the QR code. Useful for sending via Telegram or other messaging.
Check Balance
berrypay balance
Output:
{
"address": "nano_1abc...",
"balance": "1.5",
"balanceRaw": "1500000000000000000000000000000",
"pending": "0.0",
"pendingRaw": "0"
}
Note: This command auto-receives any pending funds before showing balance.
JSON-only output (for parsing):
berrypay balance --json
Send XNO
berrypay send <recipient_address> <amount> --yes
Parameters:
<recipient_address>: Nano address starting with nano_
<amount>: Amount in XNO (e.g., 0.1, 1.5, 100)
--yes or -y: Skip confirmation prompt (required for automation)
Example:
berrypay send nano_1abc123... 0.5 --yes
Output:
{
"hash": "ABC123...",
"to": "nano_1abc...",
"amount": "0.5",
"amountRaw": "500000000000000000000000000000"
}
Note: Auto-receives pending funds before sending to ensure full balance is available.
Receive Pending Funds
berrypay receive
Receives all pending incoming transactions. Called automatically by balance and send, but can be run manually.
Output:
{
"received": 2,
"blocks": [
{"hash": "ABC...", "amount": "0.1"},
{"hash": "DEF...", "amount": "0.05"}
]
}
Watch for Incoming Payments (Real-time)
berrypay watch
Monitors the wallet address via WebSocket and auto-receives incoming payments. Runs continuously until Ctrl+C.
Payment Processor (Charges)
The payment processor creates ephemeral addresses for each payment request, monitors for payments, and automatically sweeps funds to the main wallet.
Flow
1. Create charge → Ephemeral address generated
2. Customer/payer sends XNO to ephemeral address
3. Listener detects payment via WebSocket
4. Auto-receive → Funds received to ephemeral address
5. Auto-sweep → Funds sent to main wallet (index 0)
6. Webhook called → Your server notified
7. Listener auto-stops when no active charges remain
Create a Charge
berrypay charge create <amount> [options]
Parameters:
<amount>: Amount in XNO to request
Options:
| Option | Description |
|---|
-t, --timeout <minutes> | Timeout in minutes (default: 30) |
-w, --webhook <url> | URL to POST when payment completes |
-m, --metadata <json> | JSON metadata included in webhook |
--qr | Display QR code in terminal |
-o, --output <path> | Save QR code as PNG image |
Example - Basic charge:
berrypay charge create 0.1
Example - With webhook and metadata:
berrypay charge create 1.5 \
--webhook http://localhost:3000/api/payment-callback \
--metadata '{"orderId": "order_123", "userId": "user_456"}'
Example - With QR code image:
berrypay charge create 0.5 --qr --output /tmp/payment-qr.png
Output:
{
"id": "chg_abc123def456...",
"address": "nano_3ephemeral...",
"amount": "0.5",
"amountRaw": "500000000000000000000000000000",
"expiresAt": "2026-01-30T12:30:00.000Z",
"webhookUrl": "http://localhost:3000/callback",
"metadata": {"orderId": "order_123"}
}
Important: Creating a charge automatically starts the background listener if not already running.
Check Charge Status
berrypay charge status <charge_id>
Example:
berrypay charge status chg_abc123def456
Output:
{
"id": "chg_abc123def456",
"address": "nano_3ephemeral...",
"status": "completed",
"required": "0.5",
"requiredRaw": "500000000000000000000000000000",
"onChainBalance": "0.5",
"onChainPending": "0.0",
"isPaid": true,
"remaining": "0.0",
"swept": true,
"sweepHash": "XYZ789..."
}
Status values:
| Status | Description |
|---|
pending | Waiting for payment |
partial | Some payment received, not complete |
completed | Full payment received |
swept | Funds transferred to main wallet |
expired | Timeout reached without full payment |
Note: Running charge status will:
- Check blockchain for actual balance/pending
- Auto-receive any pending blocks
- Auto-sweep if fully paid (unless
--no-sweep flag)
List All Charges
berrypay charge list
Filter by status:
berrypay charge list --status pending
berrypay charge list --status completed
berrypay charge list --status swept
Output:
{
"charges": [
{"id": "chg_abc...", "status": "swept", "amount": "0.5", "received": "0.5"},
{"id": "chg_def...", "status": "pending", "amount": "1.0", "received": "0.0"}
]
}
Manually Sweep a Charge
berrypay charge sweep <charge_id>
Forces immediate sweep of funds from charge's ephemeral address to main wallet.
Verbose mode (for debugging):
berrypay charge sweep <charge_id> --verbose
Listener Management
Check if listener is running:
berrypay charge listener
Output:
{
"running": true,
"pid": 12345
}
Manually stop listener:
berrypay charge stop
Manually start listener (usually not needed):
berrypay charge listen
Note: Listener auto-starts on charge create and auto-stops when no active charges remain.
Clean Up Old Charges
berrypay charge cleanup
Removes swept charges from history to free up storage.
Webhook Payload
When a charge is completed and swept, BerryPay POSTs to your webhook URL:
Request:
POST /your-webhook-endpoint HTTP/1.1
Content-Type: application/json
{
"event": "charge.completed",
"charge": {
"id": "chg_abc123def456",
"address": "nano_3ephemeral...",
"amountNano": "0.5",
"amountRaw": "500000000000000000000000000000",
"receivedNano": "0.5",
"receivedRaw": "500000000000000000000000000000",
"status": "swept",
"sweepTxHash": "ABC123...",
"sweptAmountNano": "0.5",
"sweptAmountRaw": "500000000000000000000000000000",
"completedAt": "2026-01-30T12:15:00.000Z",
"sweptAt": "2026-01-30T12:15:05.000Z",
"metadata": {
"orderId": "order_123",
"userId": "user_456"
}
},
"timestamp": "2026-01-30T12:15:05.000Z"
}
Your webhook should return HTTP 200 to confirm receipt.
Storage Locations
| File | Purpose |
|---|
~/.berrypay/config.json | Wallet seed and settings |
~/.berrypay/charges.json | Charge history and state |
~/.berrypay/listener.pid | Background listener PID |
Common Agent Workflows
Workflow 1: Accept Payment for a Service
berrypay charge create 0.1 \
--webhook http://localhost:3000/api/payment-complete \
--metadata '{"jobId": "job_abc123"}'
Workflow 2: Check if Payment Received
berrypay charge status chg_abc123def456
Workflow 3: Send Payment to Another Agent
berrypay balance
berrypay send nano_1recipient... 0.5 --yes
Workflow 4: Generate Payment QR for User
berrypay charge create 1.0 \
--qr \
--output /tmp/payment_qr.png \
--webhook http://localhost:3000/callback
Workflow 5: Programmatic Integration (Node.js)
import { BerryPayWallet, PaymentProcessor } from 'berrypay';
const wallet = new BerryPayWallet({
seed: process.env.BERRYPAY_SEED
});
const { balance, pending } = await wallet.getBalance();
console.log(`Balance: ${BerryPayWallet.rawToNano(balance)} XNO`);
const result = await wallet.send(
'nano_1recipient...',
BerryPayWallet.nanoToRaw('0.5')
);
console.log(`Sent! Hash: ${result.hash}`);
const processor = new PaymentProcessor({
wallet,
autoSweep: true
});
processor.on('charge:completed', (charge) => {
console.log(`Payment received for ${charge.id}`);
});
processor.on('charge:swept', ({ charge, hash }) => {
console.log(`Swept to main wallet: ${hash}`);
});
await processor.start();
const charge = await processor.createCharge({
amountNano: '1.0',
webhookUrl: 'http://localhost:3000/callback',
metadata: { orderId: '123' }
});
console.log(`Pay to: ${charge.address}`);
Error Handling
All commands output JSON with error information on failure:
{
"error": "Insufficient balance. Have: 0.05 XNO"
}
Common errors:
| Error | Cause | Solution |
|---|
| "No wallet found" | Wallet not initialized | Run berrypay init or set BERRYPAY_SEED |
| "Insufficient balance" | Not enough XNO | Check balance, wait for pending |
| "Invalid Nano address" | Bad recipient address | Verify address starts with nano_ |
| "Account not opened" | Sending from empty account | Receive some XNO first |
| "Charge not found" | Invalid charge ID | Check charge list for valid IDs |
Tips for AI Agents
- Always use
--yes flag when sending to skip interactive prompts
- Parse JSON output - all commands output JSON for easy parsing
- Use webhooks for charge notifications instead of polling
- Store charge IDs - needed for status checks and sweeping
- Use environment variables -
BERRYPAY_SEED for secure seed management
- Auto-receive is enabled -
balance and send auto-receive pending funds
- Listener auto-manages - starts on charge create, stops when done
- QR images - use
--output to save QR codes for sharing with users
Unit Conversions
| Unit | Value |
|---|
| 1 XNO (Nano) | 10^30 raw |
| 1 raw | Smallest unit |
In code:
BerryPayWallet.nanoToRaw('1.5')
BerryPayWallet.rawToNano('1500000000000000000000000000000')
Network Information
- Currency: Nano (XNO)
- Transaction fees: Zero (feeless)
- Confirmation time: ~0.5 seconds
- Default RPC:
https://uk1.public.xnopay.com/proxy
- Default WebSocket:
wss://uk1.public.xnopay.com/ws
- Representative:
nano_1xnopay1bfmyx5eit8ut4gg1j488kt8bjukijerbn37jh3wdm81y6mxjg8qj