--- 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
--yes` | | Receive pending | `berrypay receive` | | Create charge | `berrypay charge create --webhook ` | | Check charge | `berrypay charge status ` | | List charges | `berrypay charge list` | --- ## Installation & Setup ### Install globally ```bash npm install -g berrypay ``` ### Initialize wallet (first time only) ```bash berrypay init ``` This creates a new wallet with a random seed stored in `~/.berrypay/config.json`. ### Or use environment variable (recommended for agents) ```bash 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 ```bash 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 ```bash berrypay address ``` **Output:** ```json { "address": "nano_1abc...", "index": 0 } ``` **With QR code (for sharing/display):** ```bash berrypay address --qr ``` Displays QR code in terminal. **Save QR code as PNG image:** ```bash 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 ```bash berrypay balance ``` **Output:** ```json { "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):** ```bash berrypay balance --json ``` ### Send XNO ```bash berrypay send --yes ``` **Parameters:** - ``: Nano address starting with `nano_` - ``: Amount in XNO (e.g., `0.1`, `1.5`, `100`) - `--yes` or `-y`: Skip confirmation prompt (required for automation) **Example:** ```bash berrypay send nano_1abc123... 0.5 --yes ``` **Output:** ```json { "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 ```bash berrypay receive ``` Receives all pending incoming transactions. Called automatically by `balance` and `send`, but can be run manually. **Output:** ```json { "received": 2, "blocks": [ {"hash": "ABC...", "amount": "0.1"}, {"hash": "DEF...", "amount": "0.05"} ] } ``` ### Watch for Incoming Payments (Real-time) ```bash 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 ```bash berrypay charge create [options] ``` **Parameters:** - ``: Amount in XNO to request **Options:** | Option | Description | |--------|-------------| | `-t, --timeout ` | Timeout in minutes (default: 30) | | `-w, --webhook ` | URL to POST when payment completes | | `-m, --metadata ` | JSON metadata included in webhook | | `--qr` | Display QR code in terminal | | `-o, --output ` | Save QR code as PNG image | **Example - Basic charge:** ```bash berrypay charge create 0.1 ``` **Example - With webhook and metadata:** ```bash berrypay charge create 1.5 \ --webhook http://localhost:3000/api/payment-callback \ --metadata '{"orderId": "order_123", "userId": "user_456"}' ``` **Example - With QR code image:** ```bash berrypay charge create 0.5 --qr --output /tmp/payment-qr.png ``` **Output:** ```json { "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 ```bash berrypay charge status ``` **Example:** ```bash berrypay charge status chg_abc123def456 ``` **Output:** ```json { "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: 1. Check blockchain for actual balance/pending 2. Auto-receive any pending blocks 3. Auto-sweep if fully paid (unless `--no-sweep` flag) ### List All Charges ```bash berrypay charge list ``` **Filter by status:** ```bash berrypay charge list --status pending berrypay charge list --status completed berrypay charge list --status swept ``` **Output:** ```json { "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 ```bash berrypay charge sweep ``` Forces immediate sweep of funds from charge's ephemeral address to main wallet. **Verbose mode (for debugging):** ```bash berrypay charge sweep --verbose ``` ### Listener Management **Check if listener is running:** ```bash berrypay charge listener ``` **Output:** ```json { "running": true, "pid": 12345 } ``` **Manually stop listener:** ```bash berrypay charge stop ``` **Manually start listener (usually not needed):** ```bash berrypay charge listen ``` Note: Listener auto-starts on `charge create` and auto-stops when no active charges remain. ### Clean Up Old Charges ```bash 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:** ```http 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 ```bash # 1. Create charge with webhook berrypay charge create 0.1 \ --webhook http://localhost:3000/api/payment-complete \ --metadata '{"jobId": "job_abc123"}' # 2. Parse the output to get charge address # 3. Share the address with the payer # 4. Your webhook will be called when payment completes # 5. Funds are automatically in your main wallet ``` ### Workflow 2: Check if Payment Received ```bash # Check charge status (also triggers sweep if paid) berrypay charge status chg_abc123def456 # Parse JSON output, check "isPaid" field ``` ### Workflow 3: Send Payment to Another Agent ```bash # 1. Check balance berrypay balance # 2. Send payment (--yes to skip confirmation) berrypay send nano_1recipient... 0.5 --yes # 3. Parse output to get transaction hash ``` ### Workflow 4: Generate Payment QR for User ```bash # Create charge with QR image berrypay charge create 1.0 \ --qr \ --output /tmp/payment_qr.png \ --webhook http://localhost:3000/callback # The QR image at /tmp/payment_qr.png can be sent to user via Telegram, etc. ``` ### Workflow 5: Programmatic Integration (Node.js) ```typescript import { BerryPayWallet, PaymentProcessor } from 'berrypay'; // Create wallet from environment const wallet = new BerryPayWallet({ seed: process.env.BERRYPAY_SEED }); // Check balance const { balance, pending } = await wallet.getBalance(); console.log(`Balance: ${BerryPayWallet.rawToNano(balance)} XNO`); // Send payment const result = await wallet.send( 'nano_1recipient...', BerryPayWallet.nanoToRaw('0.5') ); console.log(`Sent! Hash: ${result.hash}`); // Payment processor 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(); // Create charge 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: ```json { "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 1. **Always use `--yes` flag** when sending to skip interactive prompts 2. **Parse JSON output** - all commands output JSON for easy parsing 3. **Use webhooks** for charge notifications instead of polling 4. **Store charge IDs** - needed for status checks and sweeping 5. **Use environment variables** - `BERRYPAY_SEED` for secure seed management 6. **Auto-receive is enabled** - `balance` and `send` auto-receive pending funds 7. **Listener auto-manages** - starts on charge create, stops when done 8. **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:** ```typescript BerryPayWallet.nanoToRaw('1.5') // "1500000000000000000000000000000" BerryPayWallet.rawToNano('1500000000000000000000000000000') // "1.5" ``` --- ## 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`