Repository files navigation

Agentic AQUA

MCP server and CLI for managing Bitcoin and Liquid Network wallets through AI assistants like Claude. One seed backs both networks (unified wallet). Agentic AQUA can also operate on the Lightning Network.

Features

  • Generate & Import - Create new wallets or import existing seeds
  • Unified Wallet - One seed (mnemonic) for Bitcoin and Liquid; unified_balance shows both
  • Bitcoin (onchain) - BIP84 wallets, balance and send via btc_* tools (BDK)
  • Watch-Only - Import CT descriptors for balance monitoring
  • Send & Receive - Full transaction support (L-BTC, BTC, and Liquid assets like USDt)
  • Lightning - Send and receive via Lightning using L-BTC
  • Assets - Native support for L-BTC, USDt, and all Liquid assets
  • Swaps & Pegs - Convert BTC ↔ L-BTC and swap Liquid/cross-chain assets via SideSwap, SideShift, and Changelly
  • JAN3 Account - Login, Lightning Address, and WapuPay (pay ARS bank accounts with USDT) via your JAN3 account
  • Secure - Encrypted storage, no remote servers for keys

Installation

Quickest way: just ask your AI agent directly:

Install this MCP server: https://pypi.org/project/agentic-aqua/

Python 3.13 required.

Recommended (uv tool install)

If you don't have uv installed:

# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Install Agentic AQUA:

uv tool install --python 3.13 agentic-aqua

This creates a permanent agentic-aqua executable. Find its full path with:

which agentic-aqua
# Example: /Users/yourname/.local/bin/agentic-aqua

Configure Claude Desktop (~/.claude/claude_desktop_config.json) using that path:

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/agentic-aqua",
"args": []
}
}
}

Restart Claude Desktop and you're ready to use Bitcoin and Liquid wallets.

Updating / removing:uv tool upgrade agentic-aqua to update, uv tool uninstall agentic-aqua to remove.

For Developers

Clone and install from source:

git clone https://github.com/jan3dev/agentic-aqua.git
cd agentic-aqua
uv python install 3.13
uv sync --python 3.13

Configure Claude Desktop using the full path to uv (find with which uv):

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/uv",
"args": ["run", "--python", "3.13", "--directory", "/absolute/path/to/agentic-aqua", "python", "-m", "aqua.server"]
}
}
}

Quick Start

Once connected, you can ask Claude to:

  • "Create a new wallet" (creates both Bitcoin and Liquid wallets from one seed)
  • "Show my balance" / "What's my Bitcoin balance?"
  • "Generate a receive address" (Liquid or Bitcoin)
  • "Send 10,000 Sats to bc1..." / "Send 0.001 L-BTC to lq1..."
  • "Pay this Lightning invoice: lnbc..."
  • "Receive 50,000 Sats via Lightning"
  • "Delete my wallet"

Available Tools

Wallet Management

ToolDescription
lw_generate_mnemonicGenerate new BIP39 seed
lw_import_mnemonicImport wallet from seed (also creates Bitcoin wallet)
lw_import_descriptorImport watch-only Liquid wallet from CT descriptor
lw_export_descriptorExport Liquid CT descriptor for watch-only use
btc_import_descriptorImport watch-only Bitcoin wallet from BIP84 descriptor
btc_export_descriptorExport Bitcoin BIP84 descriptors + xpub
lw_list_walletsList all wallets
delete_walletDelete a wallet and all its cached data

⚠️ Bitcoin and Liquid descriptors cannot be derived from each other (different BIP84 paths + Liquid's SLIP-77 blinding key). To watch a unified wallet, import both descriptors separately.

Liquid (lw_*)

ToolDescription
lw_balanceGet wallet balances (all assets)
lw_addressGenerate Liquid receive address (lq1...)
lw_sendSend L-BTC
lw_send_assetSend any Liquid asset (USDt, etc.)
lw_sweepSweep the entire L-BTC (or one asset) balance to one address
lw_list_assetsList known Liquid assets (asset_id, ticker, name, precision)
lw_transactionsTransaction history
lw_tx_statusGet transaction status (txid or explorer URL)

Bitcoin (btc_*)

ToolDescription
btc_balanceGet Bitcoin balance (sats)
btc_addressGenerate Bitcoin receive address (bc1...)
btc_transactionsBitcoin transaction history
btc_sendSend BTC
btc_sweepSweep the entire Bitcoin balance to one address

Unified

ToolDescription
unified_balanceGet balance for both Bitcoin and Liquid

Lightning

ToolDescription
lightning_receiveGenerate a Lightning invoice to receive L-BTC (100–25,000,000 Sats)
lightning_sendPay a Lightning invoice using L-BTC via Boltz (~0.1% fee)
lightning_transaction_statusCheck status of a Lightning swap (send or receive)
lightning_decodeDecode a BOLT11 invoice without paying it

Swaps — SideSwap (sideswap_*) — BTC ↔ L-BTC pegs and atomic Liquid asset swaps

ToolDescription
sideswap_server_statusLive fees, peg minimums, hot-wallet balance
sideswap_recommendRecommend a peg vs an instant swap for a BTC ↔ L-BTC conversion
sideswap_peg_quoteQuote the receive amount for a peg at current fees
sideswap_peg_inPeg BTC → L-BTC
sideswap_peg_outPeg L-BTC → BTC
sideswap_peg_statusCheck status of a peg order
sideswap_list_assetsList Liquid assets SideSwap supports for atomic swaps
sideswap_quoteRead-only price quote for a Liquid asset swap
sideswap_execute_swapExecute an atomic Liquid asset swap (L-BTC ↔ USDt, etc.)
sideswap_swap_statusCheck status of an atomic asset swap

Swaps — SideShift (sideshift_*) — custodial cross-chain swaps (USDt across chains, BTC ↔ USDt-on-X)

ToolDescription
sideshift_list_coinsList supported coins and networks
sideshift_pair_infoRate / min / max for a pair
sideshift_quoteFixed-rate quote (~15 min TTL)
sideshift_recommendRecommend SideSwap vs SideShift for a pair
sideshift_sendSend funds from the wallet via a fixed-rate shift
sideshift_receiveReceive into the wallet via a variable-rate shift
sideshift_statusCheck status of a shift order

Swaps — Changelly (changelly_*) — USDt-Liquid ↔ USDt on Ethereum/Tron/BSC/Solana/Polygon

ToolDescription
changelly_list_currenciesList currencies Changelly supports
changelly_quoteFixed-rate quote for a USDt-Liquid ↔ USDt-on-X swap
changelly_sendSend USDt-Liquid out to USDt on another chain
changelly_receiveReceive USDt-Liquid from USDt on another chain
changelly_statusCheck status of a swap order

WapuPay (wapupay_*) — pay Argentine bank accounts in ARS, funded with USDT on Liquid

ToolDescription
wapupay_exchange_ratesCurrent exchange rates (e.g. USDT/ARS); public, no key needed
wapupay_quotePreview USDT cost, fee, and rate for an ARS payment
wapupay_create_orderCreate a direct-fiat order; returns a Liquid USDT funding address
wapupay_fund_orderRe-issue funding instructions for an existing order
wapupay_order_statusCheck a direct-fiat order's status
wapupay_ordersList locally-tracked orders
wapupay_transactionsList WapuPay transactions
wapupay_transactionGet a single transaction by id
wapupay_spending_limitMonthly spending limit (USDT) for the account/key
wapupay_provision_accountProvision a WapuPay API key via your JAN3 account

JAN3 Account (jan3_*) — login, sessions, and Lightning Address for your JAN3 account

ToolDescription
jan3_login / jan3_verifyDefault login flow: email OTP → verify, saves the session
jan3_login_start / jan3_login_completeFallback paid captchaless login flow
jan3_session_infoStatus/metadata for a persisted session
jan3_list_sessionsList all persisted sessions
jan3_logoutDelete a persisted session
jan3_user_infoAccount profile + Lightning Address status
jan3_enable_lightning_addressEnable/disable the Lightning Address
jan3_rebind_walletRe-bind Lightning Address delivery to a different wallet (destructive)
jan3_ln_check_usernameCheck if a Lightning username is available
jan3_purchase_ln_usernameBuy/update the Lightning username (on-chain payment)

Utilities

ToolDescription
qr_generateGenerate a PNG QR code for any content (address, invoice, URI)
qr_decodeDecode a QR code from an image file
doctorDiagnose (and optionally repair) the ~/.aqua/config.json config file

CLI

Agentic AQUA also ships with a Click-based CLI (aqua) for direct, scriptable wallet operations. It exposes the same operations as the MCP tools.

# Discover commands
aqua --help
aqua wallet --help
aqua btc --help
aqua liquid --help
aqua lightning --help
aqua sideswap --help
aqua sideshift --help
aqua changelly --help
aqua wapupay --help
aqua jan3 --help
aqua qr --help
# Wallet management
aqua wallet generate-mnemonic
aqua wallet import-mnemonic --mnemonic-stdin --wallet-name default --network mainnet --password-stdin
aqua wallet list
aqua wallet delete --wallet-name old
# Watch-only descriptors (Bitcoin and Liquid are separate)
aqua btc export-descriptor --wallet-name default
aqua btc import-descriptor --wallet-name cold --descriptor "wpkh([fp/84h/0h/0h]xpub.../0/*)#cs"
aqua liquid export-descriptor --wallet-name default
aqua liquid import-descriptor --wallet-name cold --descriptor "ct(slip77(...),elwpkh(...))"# Balances
aqua balance # unified (BTC + Liquid)
aqua btc balance --wallet-name default
aqua liquid balance --wallet-name default
# Receive addresses
aqua btc address
aqua liquid address
# Send (--wallet-name is required for on-chain sends)
aqua btc send --wallet-name default --address bc1... --amount 10000
aqua liquid send --wallet-name default --address lq1... --amount 50000
aqua liquid send-asset --wallet-name default --address lq1... --amount 1000000 --asset-id <asset_id># (or use --asset-ticker USDt instead of --asset-id)# Transaction history & status
aqua btc transactions
aqua liquid transactions
aqua liquid tx-status --tx <txid|explorer_url># Lightning (L-BTC via Boltz / Ankara)
aqua lightning receive --amount 50000
aqua lightning send --invoice lnbc...
aqua lightning status --swap-id <id>
aqua lightning decode --invoice lnbc...
# Swaps & pegs
aqua sideswap peg-in --wallet-name default # BTC -> L-BTC
aqua sideswap peg-out --amount 50000 --btc-address bc1... --wallet-name default
aqua sideswap swap --asset-ticker USDt --amount 50000 --wallet-name default
aqua sideshift send --deposit-coin btc --deposit-network liquid --settle-coin usdt --settle-network tron \
--settle-address T... --deposit-amount 0.001 --wallet-name default
aqua changelly send --external-network tron --settle-address T... --amount-from 100 --wallet-name default
# WapuPay (pay ARS bank accounts, funded with USDT on Liquid)
aqua wapupay quote --amount-ars 10000 --alias some.alias
aqua wapupay create-order --amount-ars 10000 --alias some.alias --wallet-name default
# then fund the returned address:
aqua liquid send-asset --wallet-name default --address <funding_address> --amount <amount> --asset-ticker USDt
# QR
aqua qr decode ./invoice-qr.png
# Run as MCP stdio server
aqua serve # recommended
aqua-mcp # direct MCP entrypoint

Output defaults to a human-readable table on the terminal and JSON when piped. Force a format with --format json or --format pretty.

Loading seeds safely

Avoid pasting seeds into the chat with your agent. Because it will persist in logs and will be sent to the AI provider, agent transcripts may persist them. The recommended workflow is to use this command that hides the text input:

aqua wallet import-mnemonic --mnemonic-stdin --wallet-name defaultx --network mainnet --password-stdin

The CLI honors these variables out of the box:

VariableUsed by
AQUA_MNEMONICwallet import-mnemonic
AQUA_PASSWORDwallet import-mnemonic, btc send, liquid send, liquid send-asset, lightning send, lightning receive
AQUA_<OPTION>Any CLI option (Click auto_envvar_prefix="AQUA") — e.g. AQUA_WALLET_NAME=default

If you would rather pipe secrets from a password manager, every secret-bearing command also accepts --mnemonic-stdin / --password-stdin:

pass show crypto/aqua-mnemonic | aqua-cli wallet import-mnemonic --mnemonic-stdin

Tips:

  • Never commit .env or secrets.env files (the project's .gitignore already excludes them).
  • Prefer set -a; . file; set +a over export $(cat file) — the former tolerates spaces and quotes inside values.
  • After importing a wallet, the seed is no longer needed for day-to-day operations; only AQUA_PASSWORD is used to sign transactions.

JAN3 account login

Two login flows, both multi-account (one session per email), ending with a locally saved session:

# Default (free email-OTP)
aqua jan3 login --email you@example.com # emails an OTP
aqua jan3 verify --email you@example.com --otp 123456
# Fallback (paid captchaless), for accounts that can't use the free flow
aqua jan3 login-start --email you@example.com --wallet-name default --password-stdin
aqua jan3 login-complete --email you@example.com --otp 123456

Once logged in:

aqua jan3 list-sessions
aqua jan3 user-info --email you@example.com
aqua jan3 logout --email you@example.com

Configuration

Default config location: ~/.aqua/config.json

Migrating from aqua-mcp? The config dir moved from ~/.aqua-mcp to ~/.aqua. There is no automatic migration. To carry over your wallets, run once:

mv ~/.aqua-mcp ~/.aqua
{
"network": "mainnet",
"default_wallet": "default",
"electrum_url": null,
"auto_sync": true
}

Security

Seeds are encrypted at rest using a password (PBKDF2 + Fernet). Without a password, the seed is stored base64-encoded only — use a password for real funds. Note: this password is NOT a BIP39 passphrase; the derived Liquid/Bitcoin keys depend solely on the seed, so the same seed restores identical descriptors in any BIP39-compliant wallet (AQUA, Blockstream App, Jade, etc.).

For maximum security you can:

  1. Generate wallet on an air-gapped device
  2. Export the CT descriptor
  3. Import as watch-only on your daily machine

All private key operations happen locally. Only blockchain sync uses Blockstream's public servers.

Development

# Install with dev dependencies
uv python install 3.13
uv sync --python 3.13 --all-extras
# Run tests
uv run --python 3.13 python -m pytest tests/
# Format code
uv run black src/
uv run ruff check src/

Architecture

AI Assistant ←→ MCP Server (Python) ←→ LWK (Liquid) ──→ Electrum/Esplora
│
├──→ BDK (Bitcoin) ──→ Esplora (Blockstream)
│
└──→ Boltz / Ankara ──→ Lightning

Credits

Built with:

  • LWK - Liquid Wallet Kit by Blockstream
  • BDK - Bitcoin Development Kit
  • MCP - Model Context Protocol
  • Boltz - Submarine swaps for Lightning

About

MCP server and CLI to manage assets in Bitcoin and Liquid

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Agentic AQUA

MCP server and CLI for managing Bitcoin and Liquid Network wallets through AI assistants like Claude. One seed backs both networks (unified wallet). Agentic AQUA can also operate on the Lightning Network.

Features

  • Generate & Import - Create new wallets or import existing seeds
  • Unified Wallet - One seed (mnemonic) for Bitcoin and Liquid; unified_balance shows both
  • Bitcoin (onchain) - BIP84 wallets, balance and send via btc_* tools (BDK)
  • Watch-Only - Import CT descriptors for balance monitoring
  • Send & Receive - Full transaction support (L-BTC, BTC, and Liquid assets like USDt)
  • Lightning - Send and receive via Lightning using L-BTC
  • Assets - Native support for L-BTC, USDt, and all Liquid assets
  • Swaps & Pegs - Convert BTC ↔ L-BTC and swap Liquid/cross-chain assets via SideSwap, SideShift, and Changelly
  • JAN3 Account - Login, Lightning Address, and WapuPay (pay ARS bank accounts with USDT) via your JAN3 account
  • Secure - Encrypted storage, no remote servers for keys

Installation

Quickest way: just ask your AI agent directly:

Install this MCP server: https://pypi.org/project/agentic-aqua/

Python 3.13 required.

Recommended (uv tool install)

If you don't have uv installed:

# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Install Agentic AQUA:

uv tool install --python 3.13 agentic-aqua

This creates a permanent agentic-aqua executable. Find its full path with:

which agentic-aqua
# Example: /Users/yourname/.local/bin/agentic-aqua

Configure Claude Desktop (~/.claude/claude_desktop_config.json) using that path:

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/agentic-aqua",
"args": []
}
}
}

Restart Claude Desktop and you're ready to use Bitcoin and Liquid wallets.

Updating / removing:uv tool upgrade agentic-aqua to update, uv tool uninstall agentic-aqua to remove.

For Developers

Clone and install from source:

git clone https://github.com/jan3dev/agentic-aqua.git
cd agentic-aqua
uv python install 3.13
uv sync --python 3.13

Configure Claude Desktop using the full path to uv (find with which uv):

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/uv",
"args": ["run", "--python", "3.13", "--directory", "/absolute/path/to/agentic-aqua", "python", "-m", "aqua.server"]
}
}
}

Quick Start

Once connected, you can ask Claude to:

  • "Create a new wallet" (creates both Bitcoin and Liquid wallets from one seed)
  • "Show my balance" / "What's my Bitcoin balance?"
  • "Generate a receive address" (Liquid or Bitcoin)
  • "Send 10,000 Sats to bc1..." / "Send 0.001 L-BTC to lq1..."
  • "Pay this Lightning invoice: lnbc..."
  • "Receive 50,000 Sats via Lightning"
  • "Delete my wallet"

Available Tools

Wallet Management

ToolDescription
lw_generate_mnemonicGenerate new BIP39 seed
lw_import_mnemonicImport wallet from seed (also creates Bitcoin wallet)
lw_import_descriptorImport watch-only Liquid wallet from CT descriptor
lw_export_descriptorExport Liquid CT descriptor for watch-only use
btc_import_descriptorImport watch-only Bitcoin wallet from BIP84 descriptor
btc_export_descriptorExport Bitcoin BIP84 descriptors + xpub
lw_list_walletsList all wallets
delete_walletDelete a wallet and all its cached data

⚠️ Bitcoin and Liquid descriptors cannot be derived from each other (different BIP84 paths + Liquid's SLIP-77 blinding key). To watch a unified wallet, import both descriptors separately.

Liquid (lw_*)

ToolDescription
lw_balanceGet wallet balances (all assets)
lw_addressGenerate Liquid receive address (lq1...)
lw_sendSend L-BTC
lw_send_assetSend any Liquid asset (USDt, etc.)
lw_sweepSweep the entire L-BTC (or one asset) balance to one address
lw_list_assetsList known Liquid assets (asset_id, ticker, name, precision)
lw_transactionsTransaction history
lw_tx_statusGet transaction status (txid or explorer URL)

Bitcoin (btc_*)

ToolDescription
btc_balanceGet Bitcoin balance (sats)
btc_addressGenerate Bitcoin receive address (bc1...)
btc_transactionsBitcoin transaction history
btc_sendSend BTC
btc_sweepSweep the entire Bitcoin balance to one address

Unified

ToolDescription
unified_balanceGet balance for both Bitcoin and Liquid

Lightning

ToolDescription
lightning_receiveGenerate a Lightning invoice to receive L-BTC (100–25,000,000 Sats)
lightning_sendPay a Lightning invoice using L-BTC via Boltz (~0.1% fee)
lightning_transaction_statusCheck status of a Lightning swap (send or receive)
lightning_decodeDecode a BOLT11 invoice without paying it

Swaps — SideSwap (sideswap_*) — BTC ↔ L-BTC pegs and atomic Liquid asset swaps

ToolDescription
sideswap_server_statusLive fees, peg minimums, hot-wallet balance
sideswap_recommendRecommend a peg vs an instant swap for a BTC ↔ L-BTC conversion
sideswap_peg_quoteQuote the receive amount for a peg at current fees
sideswap_peg_inPeg BTC → L-BTC
sideswap_peg_outPeg L-BTC → BTC
sideswap_peg_statusCheck status of a peg order
sideswap_list_assetsList Liquid assets SideSwap supports for atomic swaps
sideswap_quoteRead-only price quote for a Liquid asset swap
sideswap_execute_swapExecute an atomic Liquid asset swap (L-BTC ↔ USDt, etc.)
sideswap_swap_statusCheck status of an atomic asset swap

Swaps — SideShift (sideshift_*) — custodial cross-chain swaps (USDt across chains, BTC ↔ USDt-on-X)

ToolDescription
sideshift_list_coinsList supported coins and networks
sideshift_pair_infoRate / min / max for a pair
sideshift_quoteFixed-rate quote (~15 min TTL)
sideshift_recommendRecommend SideSwap vs SideShift for a pair
sideshift_sendSend funds from the wallet via a fixed-rate shift
sideshift_receiveReceive into the wallet via a variable-rate shift
sideshift_statusCheck status of a shift order

Swaps — Changelly (changelly_*) — USDt-Liquid ↔ USDt on Ethereum/Tron/BSC/Solana/Polygon

ToolDescription
changelly_list_currenciesList currencies Changelly supports
changelly_quoteFixed-rate quote for a USDt-Liquid ↔ USDt-on-X swap
changelly_sendSend USDt-Liquid out to USDt on another chain
changelly_receiveReceive USDt-Liquid from USDt on another chain
changelly_statusCheck status of a swap order

WapuPay (wapupay_*) — pay Argentine bank accounts in ARS, funded with USDT on Liquid

ToolDescription
wapupay_exchange_ratesCurrent exchange rates (e.g. USDT/ARS); public, no key needed
wapupay_quotePreview USDT cost, fee, and rate for an ARS payment
wapupay_create_orderCreate a direct-fiat order; returns a Liquid USDT funding address
wapupay_fund_orderRe-issue funding instructions for an existing order
wapupay_order_statusCheck a direct-fiat order's status
wapupay_ordersList locally-tracked orders
wapupay_transactionsList WapuPay transactions
wapupay_transactionGet a single transaction by id
wapupay_spending_limitMonthly spending limit (USDT) for the account/key
wapupay_provision_accountProvision a WapuPay API key via your JAN3 account

JAN3 Account (jan3_*) — login, sessions, and Lightning Address for your JAN3 account

ToolDescription
jan3_login / jan3_verifyDefault login flow: email OTP → verify, saves the session
jan3_login_start / jan3_login_completeFallback paid captchaless login flow
jan3_session_infoStatus/metadata for a persisted session
jan3_list_sessionsList all persisted sessions
jan3_logoutDelete a persisted session
jan3_user_infoAccount profile + Lightning Address status
jan3_enable_lightning_addressEnable/disable the Lightning Address
jan3_rebind_walletRe-bind Lightning Address delivery to a different wallet (destructive)
jan3_ln_check_usernameCheck if a Lightning username is available
jan3_purchase_ln_usernameBuy/update the Lightning username (on-chain payment)

Utilities

ToolDescription
qr_generateGenerate a PNG QR code for any content (address, invoice, URI)
qr_decodeDecode a QR code from an image file
doctorDiagnose (and optionally repair) the ~/.aqua/config.json config file

CLI

Agentic AQUA also ships with a Click-based CLI (aqua) for direct, scriptable wallet operations. It exposes the same operations as the MCP tools.

# Discover commands
aqua --help
aqua wallet --help
aqua btc --help
aqua liquid --help
aqua lightning --help
aqua sideswap --help
aqua sideshift --help
aqua changelly --help
aqua wapupay --help
aqua jan3 --help
aqua qr --help
# Wallet management
aqua wallet generate-mnemonic
aqua wallet import-mnemonic --mnemonic-stdin --wallet-name default --network mainnet --password-stdin
aqua wallet list
aqua wallet delete --wallet-name old
# Watch-only descriptors (Bitcoin and Liquid are separate)
aqua btc export-descriptor --wallet-name default
aqua btc import-descriptor --wallet-name cold --descriptor "wpkh([fp/84h/0h/0h]xpub.../0/*)#cs"
aqua liquid export-descriptor --wallet-name default
aqua liquid import-descriptor --wallet-name cold --descriptor "ct(slip77(...),elwpkh(...))"# Balances
aqua balance # unified (BTC + Liquid)
aqua btc balance --wallet-name default
aqua liquid balance --wallet-name default
# Receive addresses
aqua btc address
aqua liquid address
# Send (--wallet-name is required for on-chain sends)
aqua btc send --wallet-name default --address bc1... --amount 10000
aqua liquid send --wallet-name default --address lq1... --amount 50000
aqua liquid send-asset --wallet-name default --address lq1... --amount 1000000 --asset-id <asset_id># (or use --asset-ticker USDt instead of --asset-id)# Transaction history & status
aqua btc transactions
aqua liquid transactions
aqua liquid tx-status --tx <txid|explorer_url># Lightning (L-BTC via Boltz / Ankara)
aqua lightning receive --amount 50000
aqua lightning send --invoice lnbc...
aqua lightning status --swap-id <id>
aqua lightning decode --invoice lnbc...
# Swaps & pegs
aqua sideswap peg-in --wallet-name default # BTC -> L-BTC
aqua sideswap peg-out --amount 50000 --btc-address bc1... --wallet-name default
aqua sideswap swap --asset-ticker USDt --amount 50000 --wallet-name default
aqua sideshift send --deposit-coin btc --deposit-network liquid --settle-coin usdt --settle-network tron \
--settle-address T... --deposit-amount 0.001 --wallet-name default
aqua changelly send --external-network tron --settle-address T... --amount-from 100 --wallet-name default
# WapuPay (pay ARS bank accounts, funded with USDT on Liquid)
aqua wapupay quote --amount-ars 10000 --alias some.alias
aqua wapupay create-order --amount-ars 10000 --alias some.alias --wallet-name default
# then fund the returned address:
aqua liquid send-asset --wallet-name default --address <funding_address> --amount <amount> --asset-ticker USDt
# QR
aqua qr decode ./invoice-qr.png
# Run as MCP stdio server
aqua serve # recommended
aqua-mcp # direct MCP entrypoint

Output defaults to a human-readable table on the terminal and JSON when piped. Force a format with --format json or --format pretty.

Loading seeds safely

Avoid pasting seeds into the chat with your agent. Because it will persist in logs and will be sent to the AI provider, agent transcripts may persist them. The recommended workflow is to use this command that hides the text input:

aqua wallet import-mnemonic --mnemonic-stdin --wallet-name defaultx --network mainnet --password-stdin

The CLI honors these variables out of the box:

VariableUsed by
AQUA_MNEMONICwallet import-mnemonic
AQUA_PASSWORDwallet import-mnemonic, btc send, liquid send, liquid send-asset, lightning send, lightning receive
AQUA_<OPTION>Any CLI option (Click auto_envvar_prefix="AQUA") — e.g. AQUA_WALLET_NAME=default

If you would rather pipe secrets from a password manager, every secret-bearing command also accepts --mnemonic-stdin / --password-stdin:

pass show crypto/aqua-mnemonic | aqua-cli wallet import-mnemonic --mnemonic-stdin

Tips:

  • Never commit .env or secrets.env files (the project's .gitignore already excludes them).
  • Prefer set -a; . file; set +a over export $(cat file) — the former tolerates spaces and quotes inside values.
  • After importing a wallet, the seed is no longer needed for day-to-day operations; only AQUA_PASSWORD is used to sign transactions.

JAN3 account login

Two login flows, both multi-account (one session per email), ending with a locally saved session:

# Default (free email-OTP)
aqua jan3 login --email you@example.com # emails an OTP
aqua jan3 verify --email you@example.com --otp 123456
# Fallback (paid captchaless), for accounts that can't use the free flow
aqua jan3 login-start --email you@example.com --wallet-name default --password-stdin
aqua jan3 login-complete --email you@example.com --otp 123456

Once logged in:

aqua jan3 list-sessions
aqua jan3 user-info --email you@example.com
aqua jan3 logout --email you@example.com

Configuration

Default config location: ~/.aqua/config.json

Migrating from aqua-mcp? The config dir moved from ~/.aqua-mcp to ~/.aqua. There is no automatic migration. To carry over your wallets, run once:

mv ~/.aqua-mcp ~/.aqua
{
"network": "mainnet",
"default_wallet": "default",
"electrum_url": null,
"auto_sync": true
}

Security

Seeds are encrypted at rest using a password (PBKDF2 + Fernet). Without a password, the seed is stored base64-encoded only — use a password for real funds. Note: this password is NOT a BIP39 passphrase; the derived Liquid/Bitcoin keys depend solely on the seed, so the same seed restores identical descriptors in any BIP39-compliant wallet (AQUA, Blockstream App, Jade, etc.).

For maximum security you can:

  1. Generate wallet on an air-gapped device
  2. Export the CT descriptor
  3. Import as watch-only on your daily machine

All private key operations happen locally. Only blockchain sync uses Blockstream's public servers.

Development

# Install with dev dependencies
uv python install 3.13
uv sync --python 3.13 --all-extras
# Run tests
uv run --python 3.13 python -m pytest tests/
# Format code
uv run black src/
uv run ruff check src/

Architecture

AI Assistant ←→ MCP Server (Python) ←→ LWK (Liquid) ──→ Electrum/Esplora
│
├──→ BDK (Bitcoin) ──→ Esplora (Blockstream)
│
└──→ Boltz / Ankara ──→ Lightning

Credits

Built with:

  • LWK - Liquid Wallet Kit by Blockstream
  • BDK - Bitcoin Development Kit
  • MCP - Model Context Protocol
  • Boltz - Submarine swaps for Lightning

About

MCP server and CLI to manage assets in Bitcoin and Liquid

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Agentic AQUA

MCP server and CLI for managing Bitcoin and Liquid Network wallets through AI assistants like Claude. One seed backs both networks (unified wallet). Agentic AQUA can also operate on the Lightning Network.

Features

  • Generate & Import - Create new wallets or import existing seeds
  • Unified Wallet - One seed (mnemonic) for Bitcoin and Liquid; unified_balance shows both
  • Bitcoin (onchain) - BIP84 wallets, balance and send via btc_* tools (BDK)
  • Watch-Only - Import CT descriptors for balance monitoring
  • Send & Receive - Full transaction support (L-BTC, BTC, and Liquid assets like USDt)
  • Lightning - Send and receive via Lightning using L-BTC
  • Assets - Native support for L-BTC, USDt, and all Liquid assets
  • Swaps & Pegs - Convert BTC ↔ L-BTC and swap Liquid/cross-chain assets via SideSwap, SideShift, and Changelly
  • JAN3 Account - Login, Lightning Address, and WapuPay (pay ARS bank accounts with USDT) via your JAN3 account
  • Secure - Encrypted storage, no remote servers for keys

Installation

Quickest way: just ask your AI agent directly:

Install this MCP server: https://pypi.org/project/agentic-aqua/

Python 3.13 required.

Recommended (uv tool install)

If you don't have uv installed:

# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Install Agentic AQUA:

uv tool install --python 3.13 agentic-aqua

This creates a permanent agentic-aqua executable. Find its full path with:

which agentic-aqua
# Example: /Users/yourname/.local/bin/agentic-aqua

Configure Claude Desktop (~/.claude/claude_desktop_config.json) using that path:

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/agentic-aqua",
"args": []
}
}
}

Restart Claude Desktop and you're ready to use Bitcoin and Liquid wallets.

Updating / removing:uv tool upgrade agentic-aqua to update, uv tool uninstall agentic-aqua to remove.

For Developers

Clone and install from source:

git clone https://github.com/jan3dev/agentic-aqua.git
cd agentic-aqua
uv python install 3.13
uv sync --python 3.13

Configure Claude Desktop using the full path to uv (find with which uv):

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/uv",
"args": ["run", "--python", "3.13", "--directory", "/absolute/path/to/agentic-aqua", "python", "-m", "aqua.server"]
}
}
}

Quick Start

Once connected, you can ask Claude to:

  • "Create a new wallet" (creates both Bitcoin and Liquid wallets from one seed)
  • "Show my balance" / "What's my Bitcoin balance?"
  • "Generate a receive address" (Liquid or Bitcoin)
  • "Send 10,000 Sats to bc1..." / "Send 0.001 L-BTC to lq1..."
  • "Pay this Lightning invoice: lnbc..."
  • "Receive 50,000 Sats via Lightning"
  • "Delete my wallet"

Available Tools

Wallet Management

ToolDescription
lw_generate_mnemonicGenerate new BIP39 seed
lw_import_mnemonicImport wallet from seed (also creates Bitcoin wallet)
lw_import_descriptorImport watch-only Liquid wallet from CT descriptor
lw_export_descriptorExport Liquid CT descriptor for watch-only use
btc_import_descriptorImport watch-only Bitcoin wallet from BIP84 descriptor
btc_export_descriptorExport Bitcoin BIP84 descriptors + xpub
lw_list_walletsList all wallets
delete_walletDelete a wallet and all its cached data

⚠️ Bitcoin and Liquid descriptors cannot be derived from each other (different BIP84 paths + Liquid's SLIP-77 blinding key). To watch a unified wallet, import both descriptors separately.

Liquid (lw_*)

ToolDescription
lw_balanceGet wallet balances (all assets)
lw_addressGenerate Liquid receive address (lq1...)
lw_sendSend L-BTC
lw_send_assetSend any Liquid asset (USDt, etc.)
lw_sweepSweep the entire L-BTC (or one asset) balance to one address
lw_list_assetsList known Liquid assets (asset_id, ticker, name, precision)
lw_transactionsTransaction history
lw_tx_statusGet transaction status (txid or explorer URL)

Bitcoin (btc_*)

ToolDescription
btc_balanceGet Bitcoin balance (sats)
btc_addressGenerate Bitcoin receive address (bc1...)
btc_transactionsBitcoin transaction history
btc_sendSend BTC
btc_sweepSweep the entire Bitcoin balance to one address

Unified

ToolDescription
unified_balanceGet balance for both Bitcoin and Liquid

Lightning

ToolDescription
lightning_receiveGenerate a Lightning invoice to receive L-BTC (100–25,000,000 Sats)
lightning_sendPay a Lightning invoice using L-BTC via Boltz (~0.1% fee)
lightning_transaction_statusCheck status of a Lightning swap (send or receive)
lightning_decodeDecode a BOLT11 invoice without paying it

Swaps — SideSwap (sideswap_*) — BTC ↔ L-BTC pegs and atomic Liquid asset swaps

ToolDescription
sideswap_server_statusLive fees, peg minimums, hot-wallet balance
sideswap_recommendRecommend a peg vs an instant swap for a BTC ↔ L-BTC conversion
sideswap_peg_quoteQuote the receive amount for a peg at current fees
sideswap_peg_inPeg BTC → L-BTC
sideswap_peg_outPeg L-BTC → BTC
sideswap_peg_statusCheck status of a peg order
sideswap_list_assetsList Liquid assets SideSwap supports for atomic swaps
sideswap_quoteRead-only price quote for a Liquid asset swap
sideswap_execute_swapExecute an atomic Liquid asset swap (L-BTC ↔ USDt, etc.)
sideswap_swap_statusCheck status of an atomic asset swap

Swaps — SideShift (sideshift_*) — custodial cross-chain swaps (USDt across chains, BTC ↔ USDt-on-X)

ToolDescription
sideshift_list_coinsList supported coins and networks
sideshift_pair_infoRate / min / max for a pair
sideshift_quoteFixed-rate quote (~15 min TTL)
sideshift_recommendRecommend SideSwap vs SideShift for a pair
sideshift_sendSend funds from the wallet via a fixed-rate shift
sideshift_receiveReceive into the wallet via a variable-rate shift
sideshift_statusCheck status of a shift order

Swaps — Changelly (changelly_*) — USDt-Liquid ↔ USDt on Ethereum/Tron/BSC/Solana/Polygon

ToolDescription
changelly_list_currenciesList currencies Changelly supports
changelly_quoteFixed-rate quote for a USDt-Liquid ↔ USDt-on-X swap
changelly_sendSend USDt-Liquid out to USDt on another chain
changelly_receiveReceive USDt-Liquid from USDt on another chain
changelly_statusCheck status of a swap order

WapuPay (wapupay_*) — pay Argentine bank accounts in ARS, funded with USDT on Liquid

ToolDescription
wapupay_exchange_ratesCurrent exchange rates (e.g. USDT/ARS); public, no key needed
wapupay_quotePreview USDT cost, fee, and rate for an ARS payment
wapupay_create_orderCreate a direct-fiat order; returns a Liquid USDT funding address
wapupay_fund_orderRe-issue funding instructions for an existing order
wapupay_order_statusCheck a direct-fiat order's status
wapupay_ordersList locally-tracked orders
wapupay_transactionsList WapuPay transactions
wapupay_transactionGet a single transaction by id
wapupay_spending_limitMonthly spending limit (USDT) for the account/key
wapupay_provision_accountProvision a WapuPay API key via your JAN3 account

JAN3 Account (jan3_*) — login, sessions, and Lightning Address for your JAN3 account

ToolDescription
jan3_login / jan3_verifyDefault login flow: email OTP → verify, saves the session
jan3_login_start / jan3_login_completeFallback paid captchaless login flow
jan3_session_infoStatus/metadata for a persisted session
jan3_list_sessionsList all persisted sessions
jan3_logoutDelete a persisted session
jan3_user_infoAccount profile + Lightning Address status
jan3_enable_lightning_addressEnable/disable the Lightning Address
jan3_rebind_walletRe-bind Lightning Address delivery to a different wallet (destructive)
jan3_ln_check_usernameCheck if a Lightning username is available
jan3_purchase_ln_usernameBuy/update the Lightning username (on-chain payment)

Utilities

ToolDescription
qr_generateGenerate a PNG QR code for any content (address, invoice, URI)
qr_decodeDecode a QR code from an image file
doctorDiagnose (and optionally repair) the ~/.aqua/config.json config file

CLI

Agentic AQUA also ships with a Click-based CLI (aqua) for direct, scriptable wallet operations. It exposes the same operations as the MCP tools.

# Discover commands
aqua --help
aqua wallet --help
aqua btc --help
aqua liquid --help
aqua lightning --help
aqua sideswap --help
aqua sideshift --help
aqua changelly --help
aqua wapupay --help
aqua jan3 --help
aqua qr --help
# Wallet management
aqua wallet generate-mnemonic
aqua wallet import-mnemonic --mnemonic-stdin --wallet-name default --network mainnet --password-stdin
aqua wallet list
aqua wallet delete --wallet-name old
# Watch-only descriptors (Bitcoin and Liquid are separate)
aqua btc export-descriptor --wallet-name default
aqua btc import-descriptor --wallet-name cold --descriptor "wpkh([fp/84h/0h/0h]xpub.../0/*)#cs"
aqua liquid export-descriptor --wallet-name default
aqua liquid import-descriptor --wallet-name cold --descriptor "ct(slip77(...),elwpkh(...))"# Balances
aqua balance # unified (BTC + Liquid)
aqua btc balance --wallet-name default
aqua liquid balance --wallet-name default
# Receive addresses
aqua btc address
aqua liquid address
# Send (--wallet-name is required for on-chain sends)
aqua btc send --wallet-name default --address bc1... --amount 10000
aqua liquid send --wallet-name default --address lq1... --amount 50000
aqua liquid send-asset --wallet-name default --address lq1... --amount 1000000 --asset-id <asset_id># (or use --asset-ticker USDt instead of --asset-id)# Transaction history & status
aqua btc transactions
aqua liquid transactions
aqua liquid tx-status --tx <txid|explorer_url># Lightning (L-BTC via Boltz / Ankara)
aqua lightning receive --amount 50000
aqua lightning send --invoice lnbc...
aqua lightning status --swap-id <id>
aqua lightning decode --invoice lnbc...
# Swaps & pegs
aqua sideswap peg-in --wallet-name default # BTC -> L-BTC
aqua sideswap peg-out --amount 50000 --btc-address bc1... --wallet-name default
aqua sideswap swap --asset-ticker USDt --amount 50000 --wallet-name default
aqua sideshift send --deposit-coin btc --deposit-network liquid --settle-coin usdt --settle-network tron \
--settle-address T... --deposit-amount 0.001 --wallet-name default
aqua changelly send --external-network tron --settle-address T... --amount-from 100 --wallet-name default
# WapuPay (pay ARS bank accounts, funded with USDT on Liquid)
aqua wapupay quote --amount-ars 10000 --alias some.alias
aqua wapupay create-order --amount-ars 10000 --alias some.alias --wallet-name default
# then fund the returned address:
aqua liquid send-asset --wallet-name default --address <funding_address> --amount <amount> --asset-ticker USDt
# QR
aqua qr decode ./invoice-qr.png
# Run as MCP stdio server
aqua serve # recommended
aqua-mcp # direct MCP entrypoint

Output defaults to a human-readable table on the terminal and JSON when piped. Force a format with --format json or --format pretty.

Loading seeds safely

Avoid pasting seeds into the chat with your agent. Because it will persist in logs and will be sent to the AI provider, agent transcripts may persist them. The recommended workflow is to use this command that hides the text input:

aqua wallet import-mnemonic --mnemonic-stdin --wallet-name defaultx --network mainnet --password-stdin

The CLI honors these variables out of the box:

VariableUsed by
AQUA_MNEMONICwallet import-mnemonic
AQUA_PASSWORDwallet import-mnemonic, btc send, liquid send, liquid send-asset, lightning send, lightning receive
AQUA_<OPTION>Any CLI option (Click auto_envvar_prefix="AQUA") — e.g. AQUA_WALLET_NAME=default

If you would rather pipe secrets from a password manager, every secret-bearing command also accepts --mnemonic-stdin / --password-stdin:

pass show crypto/aqua-mnemonic | aqua-cli wallet import-mnemonic --mnemonic-stdin

Tips:

  • Never commit .env or secrets.env files (the project's .gitignore already excludes them).
  • Prefer set -a; . file; set +a over export $(cat file) — the former tolerates spaces and quotes inside values.
  • After importing a wallet, the seed is no longer needed for day-to-day operations; only AQUA_PASSWORD is used to sign transactions.

JAN3 account login

Two login flows, both multi-account (one session per email), ending with a locally saved session:

# Default (free email-OTP)
aqua jan3 login --email you@example.com # emails an OTP
aqua jan3 verify --email you@example.com --otp 123456
# Fallback (paid captchaless), for accounts that can't use the free flow
aqua jan3 login-start --email you@example.com --wallet-name default --password-stdin
aqua jan3 login-complete --email you@example.com --otp 123456

Once logged in:

aqua jan3 list-sessions
aqua jan3 user-info --email you@example.com
aqua jan3 logout --email you@example.com

Configuration

Default config location: ~/.aqua/config.json

Migrating from aqua-mcp? The config dir moved from ~/.aqua-mcp to ~/.aqua. There is no automatic migration. To carry over your wallets, run once:

mv ~/.aqua-mcp ~/.aqua
{
"network": "mainnet",
"default_wallet": "default",
"electrum_url": null,
"auto_sync": true
}

Security

Seeds are encrypted at rest using a password (PBKDF2 + Fernet). Without a password, the seed is stored base64-encoded only — use a password for real funds. Note: this password is NOT a BIP39 passphrase; the derived Liquid/Bitcoin keys depend solely on the seed, so the same seed restores identical descriptors in any BIP39-compliant wallet (AQUA, Blockstream App, Jade, etc.).

For maximum security you can:

  1. Generate wallet on an air-gapped device
  2. Export the CT descriptor
  3. Import as watch-only on your daily machine

All private key operations happen locally. Only blockchain sync uses Blockstream's public servers.

Development

# Install with dev dependencies
uv python install 3.13
uv sync --python 3.13 --all-extras
# Run tests
uv run --python 3.13 python -m pytest tests/
# Format code
uv run black src/
uv run ruff check src/

Architecture

AI Assistant ←→ MCP Server (Python) ←→ LWK (Liquid) ──→ Electrum/Esplora
│
├──→ BDK (Bitcoin) ──→ Esplora (Blockstream)
│
└──→ Boltz / Ankara ──→ Lightning

Credits

Built with:

  • LWK - Liquid Wallet Kit by Blockstream
  • BDK - Bitcoin Development Kit
  • MCP - Model Context Protocol
  • Boltz - Submarine swaps for Lightning

About

MCP server and CLI to manage assets in Bitcoin and Liquid

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Agentic AQUA

MCP server and CLI for managing Bitcoin and Liquid Network wallets through AI assistants like Claude. One seed backs both networks (unified wallet). Agentic AQUA can also operate on the Lightning Network.

Features

  • Generate & Import - Create new wallets or import existing seeds
  • Unified Wallet - One seed (mnemonic) for Bitcoin and Liquid; unified_balance shows both
  • Bitcoin (onchain) - BIP84 wallets, balance and send via btc_* tools (BDK)
  • Watch-Only - Import CT descriptors for balance monitoring
  • Send & Receive - Full transaction support (L-BTC, BTC, and Liquid assets like USDt)
  • Lightning - Send and receive via Lightning using L-BTC
  • Assets - Native support for L-BTC, USDt, and all Liquid assets
  • Swaps & Pegs - Convert BTC ↔ L-BTC and swap Liquid/cross-chain assets via SideSwap, SideShift, and Changelly
  • JAN3 Account - Login, Lightning Address, and WapuPay (pay ARS bank accounts with USDT) via your JAN3 account
  • Secure - Encrypted storage, no remote servers for keys

Installation

Quickest way: just ask your AI agent directly:

Install this MCP server: https://pypi.org/project/agentic-aqua/

Python 3.13 required.

Recommended (uv tool install)

If you don't have uv installed:

# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Install Agentic AQUA:

uv tool install --python 3.13 agentic-aqua

This creates a permanent agentic-aqua executable. Find its full path with:

which agentic-aqua
# Example: /Users/yourname/.local/bin/agentic-aqua

Configure Claude Desktop (~/.claude/claude_desktop_config.json) using that path:

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/agentic-aqua",
"args": []
}
}
}

Restart Claude Desktop and you're ready to use Bitcoin and Liquid wallets.

Updating / removing:uv tool upgrade agentic-aqua to update, uv tool uninstall agentic-aqua to remove.

For Developers

Clone and install from source:

git clone https://github.com/jan3dev/agentic-aqua.git
cd agentic-aqua
uv python install 3.13
uv sync --python 3.13

Configure Claude Desktop using the full path to uv (find with which uv):

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/uv",
"args": ["run", "--python", "3.13", "--directory", "/absolute/path/to/agentic-aqua", "python", "-m", "aqua.server"]
}
}
}

Quick Start

Once connected, you can ask Claude to:

  • "Create a new wallet" (creates both Bitcoin and Liquid wallets from one seed)
  • "Show my balance" / "What's my Bitcoin balance?"
  • "Generate a receive address" (Liquid or Bitcoin)
  • "Send 10,000 Sats to bc1..." / "Send 0.001 L-BTC to lq1..."
  • "Pay this Lightning invoice: lnbc..."
  • "Receive 50,000 Sats via Lightning"
  • "Delete my wallet"

Available Tools

Wallet Management

ToolDescription
lw_generate_mnemonicGenerate new BIP39 seed
lw_import_mnemonicImport wallet from seed (also creates Bitcoin wallet)
lw_import_descriptorImport watch-only Liquid wallet from CT descriptor
lw_export_descriptorExport Liquid CT descriptor for watch-only use
btc_import_descriptorImport watch-only Bitcoin wallet from BIP84 descriptor
btc_export_descriptorExport Bitcoin BIP84 descriptors + xpub
lw_list_walletsList all wallets
delete_walletDelete a wallet and all its cached data

⚠️ Bitcoin and Liquid descriptors cannot be derived from each other (different BIP84 paths + Liquid's SLIP-77 blinding key). To watch a unified wallet, import both descriptors separately.

Liquid (lw_*)

ToolDescription
lw_balanceGet wallet balances (all assets)
lw_addressGenerate Liquid receive address (lq1...)
lw_sendSend L-BTC
lw_send_assetSend any Liquid asset (USDt, etc.)
lw_sweepSweep the entire L-BTC (or one asset) balance to one address
lw_list_assetsList known Liquid assets (asset_id, ticker, name, precision)
lw_transactionsTransaction history
lw_tx_statusGet transaction status (txid or explorer URL)

Bitcoin (btc_*)

ToolDescription
btc_balanceGet Bitcoin balance (sats)
btc_addressGenerate Bitcoin receive address (bc1...)
btc_transactionsBitcoin transaction history
btc_sendSend BTC
btc_sweepSweep the entire Bitcoin balance to one address

Unified

ToolDescription
unified_balanceGet balance for both Bitcoin and Liquid

Lightning

ToolDescription
lightning_receiveGenerate a Lightning invoice to receive L-BTC (100–25,000,000 Sats)
lightning_sendPay a Lightning invoice using L-BTC via Boltz (~0.1% fee)
lightning_transaction_statusCheck status of a Lightning swap (send or receive)
lightning_decodeDecode a BOLT11 invoice without paying it

Swaps — SideSwap (sideswap_*) — BTC ↔ L-BTC pegs and atomic Liquid asset swaps

ToolDescription
sideswap_server_statusLive fees, peg minimums, hot-wallet balance
sideswap_recommendRecommend a peg vs an instant swap for a BTC ↔ L-BTC conversion
sideswap_peg_quoteQuote the receive amount for a peg at current fees
sideswap_peg_inPeg BTC → L-BTC
sideswap_peg_outPeg L-BTC → BTC
sideswap_peg_statusCheck status of a peg order
sideswap_list_assetsList Liquid assets SideSwap supports for atomic swaps
sideswap_quoteRead-only price quote for a Liquid asset swap
sideswap_execute_swapExecute an atomic Liquid asset swap (L-BTC ↔ USDt, etc.)
sideswap_swap_statusCheck status of an atomic asset swap

Swaps — SideShift (sideshift_*) — custodial cross-chain swaps (USDt across chains, BTC ↔ USDt-on-X)

ToolDescription
sideshift_list_coinsList supported coins and networks
sideshift_pair_infoRate / min / max for a pair
sideshift_quoteFixed-rate quote (~15 min TTL)
sideshift_recommendRecommend SideSwap vs SideShift for a pair
sideshift_sendSend funds from the wallet via a fixed-rate shift
sideshift_receiveReceive into the wallet via a variable-rate shift
sideshift_statusCheck status of a shift order

Swaps — Changelly (changelly_*) — USDt-Liquid ↔ USDt on Ethereum/Tron/BSC/Solana/Polygon

ToolDescription
changelly_list_currenciesList currencies Changelly supports
changelly_quoteFixed-rate quote for a USDt-Liquid ↔ USDt-on-X swap
changelly_sendSend USDt-Liquid out to USDt on another chain
changelly_receiveReceive USDt-Liquid from USDt on another chain
changelly_statusCheck status of a swap order

WapuPay (wapupay_*) — pay Argentine bank accounts in ARS, funded with USDT on Liquid

ToolDescription
wapupay_exchange_ratesCurrent exchange rates (e.g. USDT/ARS); public, no key needed
wapupay_quotePreview USDT cost, fee, and rate for an ARS payment
wapupay_create_orderCreate a direct-fiat order; returns a Liquid USDT funding address
wapupay_fund_orderRe-issue funding instructions for an existing order
wapupay_order_statusCheck a direct-fiat order's status
wapupay_ordersList locally-tracked orders
wapupay_transactionsList WapuPay transactions
wapupay_transactionGet a single transaction by id
wapupay_spending_limitMonthly spending limit (USDT) for the account/key
wapupay_provision_accountProvision a WapuPay API key via your JAN3 account

JAN3 Account (jan3_*) — login, sessions, and Lightning Address for your JAN3 account

ToolDescription
jan3_login / jan3_verifyDefault login flow: email OTP → verify, saves the session
jan3_login_start / jan3_login_completeFallback paid captchaless login flow
jan3_session_infoStatus/metadata for a persisted session
jan3_list_sessionsList all persisted sessions
jan3_logoutDelete a persisted session
jan3_user_infoAccount profile + Lightning Address status
jan3_enable_lightning_addressEnable/disable the Lightning Address
jan3_rebind_walletRe-bind Lightning Address delivery to a different wallet (destructive)
jan3_ln_check_usernameCheck if a Lightning username is available
jan3_purchase_ln_usernameBuy/update the Lightning username (on-chain payment)

Utilities

ToolDescription
qr_generateGenerate a PNG QR code for any content (address, invoice, URI)
qr_decodeDecode a QR code from an image file
doctorDiagnose (and optionally repair) the ~/.aqua/config.json config file

CLI

Agentic AQUA also ships with a Click-based CLI (aqua) for direct, scriptable wallet operations. It exposes the same operations as the MCP tools.

# Discover commands
aqua --help
aqua wallet --help
aqua btc --help
aqua liquid --help
aqua lightning --help
aqua sideswap --help
aqua sideshift --help
aqua changelly --help
aqua wapupay --help
aqua jan3 --help
aqua qr --help
# Wallet management
aqua wallet generate-mnemonic
aqua wallet import-mnemonic --mnemonic-stdin --wallet-name default --network mainnet --password-stdin
aqua wallet list
aqua wallet delete --wallet-name old
# Watch-only descriptors (Bitcoin and Liquid are separate)
aqua btc export-descriptor --wallet-name default
aqua btc import-descriptor --wallet-name cold --descriptor "wpkh([fp/84h/0h/0h]xpub.../0/*)#cs"
aqua liquid export-descriptor --wallet-name default
aqua liquid import-descriptor --wallet-name cold --descriptor "ct(slip77(...),elwpkh(...))"# Balances
aqua balance # unified (BTC + Liquid)
aqua btc balance --wallet-name default
aqua liquid balance --wallet-name default
# Receive addresses
aqua btc address
aqua liquid address
# Send (--wallet-name is required for on-chain sends)
aqua btc send --wallet-name default --address bc1... --amount 10000
aqua liquid send --wallet-name default --address lq1... --amount 50000
aqua liquid send-asset --wallet-name default --address lq1... --amount 1000000 --asset-id <asset_id># (or use --asset-ticker USDt instead of --asset-id)# Transaction history & status
aqua btc transactions
aqua liquid transactions
aqua liquid tx-status --tx <txid|explorer_url># Lightning (L-BTC via Boltz / Ankara)
aqua lightning receive --amount 50000
aqua lightning send --invoice lnbc...
aqua lightning status --swap-id <id>
aqua lightning decode --invoice lnbc...
# Swaps & pegs
aqua sideswap peg-in --wallet-name default # BTC -> L-BTC
aqua sideswap peg-out --amount 50000 --btc-address bc1... --wallet-name default
aqua sideswap swap --asset-ticker USDt --amount 50000 --wallet-name default
aqua sideshift send --deposit-coin btc --deposit-network liquid --settle-coin usdt --settle-network tron \
--settle-address T... --deposit-amount 0.001 --wallet-name default
aqua changelly send --external-network tron --settle-address T... --amount-from 100 --wallet-name default
# WapuPay (pay ARS bank accounts, funded with USDT on Liquid)
aqua wapupay quote --amount-ars 10000 --alias some.alias
aqua wapupay create-order --amount-ars 10000 --alias some.alias --wallet-name default
# then fund the returned address:
aqua liquid send-asset --wallet-name default --address <funding_address> --amount <amount> --asset-ticker USDt
# QR
aqua qr decode ./invoice-qr.png
# Run as MCP stdio server
aqua serve # recommended
aqua-mcp # direct MCP entrypoint

Output defaults to a human-readable table on the terminal and JSON when piped. Force a format with --format json or --format pretty.

Loading seeds safely

Avoid pasting seeds into the chat with your agent. Because it will persist in logs and will be sent to the AI provider, agent transcripts may persist them. The recommended workflow is to use this command that hides the text input:

aqua wallet import-mnemonic --mnemonic-stdin --wallet-name defaultx --network mainnet --password-stdin

The CLI honors these variables out of the box:

VariableUsed by
AQUA_MNEMONICwallet import-mnemonic
AQUA_PASSWORDwallet import-mnemonic, btc send, liquid send, liquid send-asset, lightning send, lightning receive
AQUA_<OPTION>Any CLI option (Click auto_envvar_prefix="AQUA") — e.g. AQUA_WALLET_NAME=default

If you would rather pipe secrets from a password manager, every secret-bearing command also accepts --mnemonic-stdin / --password-stdin:

pass show crypto/aqua-mnemonic | aqua-cli wallet import-mnemonic --mnemonic-stdin

Tips:

  • Never commit .env or secrets.env files (the project's .gitignore already excludes them).
  • Prefer set -a; . file; set +a over export $(cat file) — the former tolerates spaces and quotes inside values.
  • After importing a wallet, the seed is no longer needed for day-to-day operations; only AQUA_PASSWORD is used to sign transactions.

JAN3 account login

Two login flows, both multi-account (one session per email), ending with a locally saved session:

# Default (free email-OTP)
aqua jan3 login --email you@example.com # emails an OTP
aqua jan3 verify --email you@example.com --otp 123456
# Fallback (paid captchaless), for accounts that can't use the free flow
aqua jan3 login-start --email you@example.com --wallet-name default --password-stdin
aqua jan3 login-complete --email you@example.com --otp 123456

Once logged in:

aqua jan3 list-sessions
aqua jan3 user-info --email you@example.com
aqua jan3 logout --email you@example.com

Configuration

Default config location: ~/.aqua/config.json

Migrating from aqua-mcp? The config dir moved from ~/.aqua-mcp to ~/.aqua. There is no automatic migration. To carry over your wallets, run once:

mv ~/.aqua-mcp ~/.aqua
{
"network": "mainnet",
"default_wallet": "default",
"electrum_url": null,
"auto_sync": true
}

Security

Seeds are encrypted at rest using a password (PBKDF2 + Fernet). Without a password, the seed is stored base64-encoded only — use a password for real funds. Note: this password is NOT a BIP39 passphrase; the derived Liquid/Bitcoin keys depend solely on the seed, so the same seed restores identical descriptors in any BIP39-compliant wallet (AQUA, Blockstream App, Jade, etc.).

For maximum security you can:

  1. Generate wallet on an air-gapped device
  2. Export the CT descriptor
  3. Import as watch-only on your daily machine

All private key operations happen locally. Only blockchain sync uses Blockstream's public servers.

Development

# Install with dev dependencies
uv python install 3.13
uv sync --python 3.13 --all-extras
# Run tests
uv run --python 3.13 python -m pytest tests/
# Format code
uv run black src/
uv run ruff check src/

Architecture

AI Assistant ←→ MCP Server (Python) ←→ LWK (Liquid) ──→ Electrum/Esplora
│
├──→ BDK (Bitcoin) ──→ Esplora (Blockstream)
│
└──→ Boltz / Ankara ──→ Lightning

Credits

Built with:

  • LWK - Liquid Wallet Kit by Blockstream
  • BDK - Bitcoin Development Kit
  • MCP - Model Context Protocol
  • Boltz - Submarine swaps for Lightning

About

MCP server and CLI to manage assets in Bitcoin and Liquid

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Agentic AQUA

MCP server and CLI for managing Bitcoin and Liquid Network wallets through AI assistants like Claude. One seed backs both networks (unified wallet). Agentic AQUA can also operate on the Lightning Network.

Features

  • Generate & Import - Create new wallets or import existing seeds
  • Unified Wallet - One seed (mnemonic) for Bitcoin and Liquid; unified_balance shows both
  • Bitcoin (onchain) - BIP84 wallets, balance and send via btc_* tools (BDK)
  • Watch-Only - Import CT descriptors for balance monitoring
  • Send & Receive - Full transaction support (L-BTC, BTC, and Liquid assets like USDt)
  • Lightning - Send and receive via Lightning using L-BTC
  • Assets - Native support for L-BTC, USDt, and all Liquid assets
  • Swaps & Pegs - Convert BTC ↔ L-BTC and swap Liquid/cross-chain assets via SideSwap, SideShift, and Changelly
  • JAN3 Account - Login, Lightning Address, and WapuPay (pay ARS bank accounts with USDT) via your JAN3 account
  • Secure - Encrypted storage, no remote servers for keys

Installation

Quickest way: just ask your AI agent directly:

Install this MCP server: https://pypi.org/project/agentic-aqua/

Python 3.13 required.

Recommended (uv tool install)

If you don't have uv installed:

# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Install Agentic AQUA:

uv tool install --python 3.13 agentic-aqua

This creates a permanent agentic-aqua executable. Find its full path with:

which agentic-aqua
# Example: /Users/yourname/.local/bin/agentic-aqua

Configure Claude Desktop (~/.claude/claude_desktop_config.json) using that path:

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/agentic-aqua",
"args": []
}
}
}

Restart Claude Desktop and you're ready to use Bitcoin and Liquid wallets.

Updating / removing:uv tool upgrade agentic-aqua to update, uv tool uninstall agentic-aqua to remove.

For Developers

Clone and install from source:

git clone https://github.com/jan3dev/agentic-aqua.git
cd agentic-aqua
uv python install 3.13
uv sync --python 3.13

Configure Claude Desktop using the full path to uv (find with which uv):

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/uv",
"args": ["run", "--python", "3.13", "--directory", "/absolute/path/to/agentic-aqua", "python", "-m", "aqua.server"]
}
}
}

Quick Start

Once connected, you can ask Claude to:

  • "Create a new wallet" (creates both Bitcoin and Liquid wallets from one seed)
  • "Show my balance" / "What's my Bitcoin balance?"
  • "Generate a receive address" (Liquid or Bitcoin)
  • "Send 10,000 Sats to bc1..." / "Send 0.001 L-BTC to lq1..."
  • "Pay this Lightning invoice: lnbc..."
  • "Receive 50,000 Sats via Lightning"
  • "Delete my wallet"

Available Tools

Wallet Management

ToolDescription
lw_generate_mnemonicGenerate new BIP39 seed
lw_import_mnemonicImport wallet from seed (also creates Bitcoin wallet)
lw_import_descriptorImport watch-only Liquid wallet from CT descriptor
lw_export_descriptorExport Liquid CT descriptor for watch-only use
btc_import_descriptorImport watch-only Bitcoin wallet from BIP84 descriptor
btc_export_descriptorExport Bitcoin BIP84 descriptors + xpub
lw_list_walletsList all wallets
delete_walletDelete a wallet and all its cached data

⚠️ Bitcoin and Liquid descriptors cannot be derived from each other (different BIP84 paths + Liquid's SLIP-77 blinding key). To watch a unified wallet, import both descriptors separately.

Liquid (lw_*)

ToolDescription
lw_balanceGet wallet balances (all assets)
lw_addressGenerate Liquid receive address (lq1...)
lw_sendSend L-BTC
lw_send_assetSend any Liquid asset (USDt, etc.)
lw_sweepSweep the entire L-BTC (or one asset) balance to one address
lw_list_assetsList known Liquid assets (asset_id, ticker, name, precision)
lw_transactionsTransaction history
lw_tx_statusGet transaction status (txid or explorer URL)

Bitcoin (btc_*)

ToolDescription
btc_balanceGet Bitcoin balance (sats)
btc_addressGenerate Bitcoin receive address (bc1...)
btc_transactionsBitcoin transaction history
btc_sendSend BTC
btc_sweepSweep the entire Bitcoin balance to one address

Unified

ToolDescription
unified_balanceGet balance for both Bitcoin and Liquid

Lightning

ToolDescription
lightning_receiveGenerate a Lightning invoice to receive L-BTC (100–25,000,000 Sats)
lightning_sendPay a Lightning invoice using L-BTC via Boltz (~0.1% fee)
lightning_transaction_statusCheck status of a Lightning swap (send or receive)
lightning_decodeDecode a BOLT11 invoice without paying it

Swaps — SideSwap (sideswap_*) — BTC ↔ L-BTC pegs and atomic Liquid asset swaps

ToolDescription
sideswap_server_statusLive fees, peg minimums, hot-wallet balance
sideswap_recommendRecommend a peg vs an instant swap for a BTC ↔ L-BTC conversion
sideswap_peg_quoteQuote the receive amount for a peg at current fees
sideswap_peg_inPeg BTC → L-BTC
sideswap_peg_outPeg L-BTC → BTC
sideswap_peg_statusCheck status of a peg order
sideswap_list_assetsList Liquid assets SideSwap supports for atomic swaps
sideswap_quoteRead-only price quote for a Liquid asset swap
sideswap_execute_swapExecute an atomic Liquid asset swap (L-BTC ↔ USDt, etc.)
sideswap_swap_statusCheck status of an atomic asset swap

Swaps — SideShift (sideshift_*) — custodial cross-chain swaps (USDt across chains, BTC ↔ USDt-on-X)

ToolDescription
sideshift_list_coinsList supported coins and networks
sideshift_pair_infoRate / min / max for a pair
sideshift_quoteFixed-rate quote (~15 min TTL)
sideshift_recommendRecommend SideSwap vs SideShift for a pair
sideshift_sendSend funds from the wallet via a fixed-rate shift
sideshift_receiveReceive into the wallet via a variable-rate shift
sideshift_statusCheck status of a shift order

Swaps — Changelly (changelly_*) — USDt-Liquid ↔ USDt on Ethereum/Tron/BSC/Solana/Polygon

ToolDescription
changelly_list_currenciesList currencies Changelly supports
changelly_quoteFixed-rate quote for a USDt-Liquid ↔ USDt-on-X swap
changelly_sendSend USDt-Liquid out to USDt on another chain
changelly_receiveReceive USDt-Liquid from USDt on another chain
changelly_statusCheck status of a swap order

WapuPay (wapupay_*) — pay Argentine bank accounts in ARS, funded with USDT on Liquid

ToolDescription
wapupay_exchange_ratesCurrent exchange rates (e.g. USDT/ARS); public, no key needed
wapupay_quotePreview USDT cost, fee, and rate for an ARS payment
wapupay_create_orderCreate a direct-fiat order; returns a Liquid USDT funding address
wapupay_fund_orderRe-issue funding instructions for an existing order
wapupay_order_statusCheck a direct-fiat order's status
wapupay_ordersList locally-tracked orders
wapupay_transactionsList WapuPay transactions
wapupay_transactionGet a single transaction by id
wapupay_spending_limitMonthly spending limit (USDT) for the account/key
wapupay_provision_accountProvision a WapuPay API key via your JAN3 account

JAN3 Account (jan3_*) — login, sessions, and Lightning Address for your JAN3 account

ToolDescription
jan3_login / jan3_verifyDefault login flow: email OTP → verify, saves the session
jan3_login_start / jan3_login_completeFallback paid captchaless login flow
jan3_session_infoStatus/metadata for a persisted session
jan3_list_sessionsList all persisted sessions
jan3_logoutDelete a persisted session
jan3_user_infoAccount profile + Lightning Address status
jan3_enable_lightning_addressEnable/disable the Lightning Address
jan3_rebind_walletRe-bind Lightning Address delivery to a different wallet (destructive)
jan3_ln_check_usernameCheck if a Lightning username is available
jan3_purchase_ln_usernameBuy/update the Lightning username (on-chain payment)

Utilities

ToolDescription
qr_generateGenerate a PNG QR code for any content (address, invoice, URI)
qr_decodeDecode a QR code from an image file
doctorDiagnose (and optionally repair) the ~/.aqua/config.json config file

CLI

Agentic AQUA also ships with a Click-based CLI (aqua) for direct, scriptable wallet operations. It exposes the same operations as the MCP tools.

# Discover commands
aqua --help
aqua wallet --help
aqua btc --help
aqua liquid --help
aqua lightning --help
aqua sideswap --help
aqua sideshift --help
aqua changelly --help
aqua wapupay --help
aqua jan3 --help
aqua qr --help
# Wallet management
aqua wallet generate-mnemonic
aqua wallet import-mnemonic --mnemonic-stdin --wallet-name default --network mainnet --password-stdin
aqua wallet list
aqua wallet delete --wallet-name old
# Watch-only descriptors (Bitcoin and Liquid are separate)
aqua btc export-descriptor --wallet-name default
aqua btc import-descriptor --wallet-name cold --descriptor "wpkh([fp/84h/0h/0h]xpub.../0/*)#cs"
aqua liquid export-descriptor --wallet-name default
aqua liquid import-descriptor --wallet-name cold --descriptor "ct(slip77(...),elwpkh(...))"# Balances
aqua balance # unified (BTC + Liquid)
aqua btc balance --wallet-name default
aqua liquid balance --wallet-name default
# Receive addresses
aqua btc address
aqua liquid address
# Send (--wallet-name is required for on-chain sends)
aqua btc send --wallet-name default --address bc1... --amount 10000
aqua liquid send --wallet-name default --address lq1... --amount 50000
aqua liquid send-asset --wallet-name default --address lq1... --amount 1000000 --asset-id <asset_id># (or use --asset-ticker USDt instead of --asset-id)# Transaction history & status
aqua btc transactions
aqua liquid transactions
aqua liquid tx-status --tx <txid|explorer_url># Lightning (L-BTC via Boltz / Ankara)
aqua lightning receive --amount 50000
aqua lightning send --invoice lnbc...
aqua lightning status --swap-id <id>
aqua lightning decode --invoice lnbc...
# Swaps & pegs
aqua sideswap peg-in --wallet-name default # BTC -> L-BTC
aqua sideswap peg-out --amount 50000 --btc-address bc1... --wallet-name default
aqua sideswap swap --asset-ticker USDt --amount 50000 --wallet-name default
aqua sideshift send --deposit-coin btc --deposit-network liquid --settle-coin usdt --settle-network tron \
--settle-address T... --deposit-amount 0.001 --wallet-name default
aqua changelly send --external-network tron --settle-address T... --amount-from 100 --wallet-name default
# WapuPay (pay ARS bank accounts, funded with USDT on Liquid)
aqua wapupay quote --amount-ars 10000 --alias some.alias
aqua wapupay create-order --amount-ars 10000 --alias some.alias --wallet-name default
# then fund the returned address:
aqua liquid send-asset --wallet-name default --address <funding_address> --amount <amount> --asset-ticker USDt
# QR
aqua qr decode ./invoice-qr.png
# Run as MCP stdio server
aqua serve # recommended
aqua-mcp # direct MCP entrypoint

Output defaults to a human-readable table on the terminal and JSON when piped. Force a format with --format json or --format pretty.

Loading seeds safely

Avoid pasting seeds into the chat with your agent. Because it will persist in logs and will be sent to the AI provider, agent transcripts may persist them. The recommended workflow is to use this command that hides the text input:

aqua wallet import-mnemonic --mnemonic-stdin --wallet-name defaultx --network mainnet --password-stdin

The CLI honors these variables out of the box:

VariableUsed by
AQUA_MNEMONICwallet import-mnemonic
AQUA_PASSWORDwallet import-mnemonic, btc send, liquid send, liquid send-asset, lightning send, lightning receive
AQUA_<OPTION>Any CLI option (Click auto_envvar_prefix="AQUA") — e.g. AQUA_WALLET_NAME=default

If you would rather pipe secrets from a password manager, every secret-bearing command also accepts --mnemonic-stdin / --password-stdin:

pass show crypto/aqua-mnemonic | aqua-cli wallet import-mnemonic --mnemonic-stdin

Tips:

  • Never commit .env or secrets.env files (the project's .gitignore already excludes them).
  • Prefer set -a; . file; set +a over export $(cat file) — the former tolerates spaces and quotes inside values.
  • After importing a wallet, the seed is no longer needed for day-to-day operations; only AQUA_PASSWORD is used to sign transactions.

JAN3 account login

Two login flows, both multi-account (one session per email), ending with a locally saved session:

# Default (free email-OTP)
aqua jan3 login --email you@example.com # emails an OTP
aqua jan3 verify --email you@example.com --otp 123456
# Fallback (paid captchaless), for accounts that can't use the free flow
aqua jan3 login-start --email you@example.com --wallet-name default --password-stdin
aqua jan3 login-complete --email you@example.com --otp 123456

Once logged in:

aqua jan3 list-sessions
aqua jan3 user-info --email you@example.com
aqua jan3 logout --email you@example.com

Configuration

Default config location: ~/.aqua/config.json

Migrating from aqua-mcp? The config dir moved from ~/.aqua-mcp to ~/.aqua. There is no automatic migration. To carry over your wallets, run once:

mv ~/.aqua-mcp ~/.aqua
{
"network": "mainnet",
"default_wallet": "default",
"electrum_url": null,
"auto_sync": true
}

Security

Seeds are encrypted at rest using a password (PBKDF2 + Fernet). Without a password, the seed is stored base64-encoded only — use a password for real funds. Note: this password is NOT a BIP39 passphrase; the derived Liquid/Bitcoin keys depend solely on the seed, so the same seed restores identical descriptors in any BIP39-compliant wallet (AQUA, Blockstream App, Jade, etc.).

For maximum security you can:

  1. Generate wallet on an air-gapped device
  2. Export the CT descriptor
  3. Import as watch-only on your daily machine

All private key operations happen locally. Only blockchain sync uses Blockstream's public servers.

Development

# Install with dev dependencies
uv python install 3.13
uv sync --python 3.13 --all-extras
# Run tests
uv run --python 3.13 python -m pytest tests/
# Format code
uv run black src/
uv run ruff check src/

Architecture

AI Assistant ←→ MCP Server (Python) ←→ LWK (Liquid) ──→ Electrum/Esplora
│
├──→ BDK (Bitcoin) ──→ Esplora (Blockstream)
│
└──→ Boltz / Ankara ──→ Lightning

Credits

Built with:

  • LWK - Liquid Wallet Kit by Blockstream
  • BDK - Bitcoin Development Kit
  • MCP - Model Context Protocol
  • Boltz - Submarine swaps for Lightning

About

MCP server and CLI to manage assets in Bitcoin and Liquid

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Agentic AQUA

MCP server and CLI for managing Bitcoin and Liquid Network wallets through AI assistants like Claude. One seed backs both networks (unified wallet). Agentic AQUA can also operate on the Lightning Network.

Features

  • Generate & Import - Create new wallets or import existing seeds
  • Unified Wallet - One seed (mnemonic) for Bitcoin and Liquid; unified_balance shows both
  • Bitcoin (onchain) - BIP84 wallets, balance and send via btc_* tools (BDK)
  • Watch-Only - Import CT descriptors for balance monitoring
  • Send & Receive - Full transaction support (L-BTC, BTC, and Liquid assets like USDt)
  • Lightning - Send and receive via Lightning using L-BTC
  • Assets - Native support for L-BTC, USDt, and all Liquid assets
  • Swaps & Pegs - Convert BTC ↔ L-BTC and swap Liquid/cross-chain assets via SideSwap, SideShift, and Changelly
  • JAN3 Account - Login, Lightning Address, and WapuPay (pay ARS bank accounts with USDT) via your JAN3 account
  • Secure - Encrypted storage, no remote servers for keys

Installation

Quickest way: just ask your AI agent directly:

Install this MCP server: https://pypi.org/project/agentic-aqua/

Python 3.13 required.

Recommended (uv tool install)

If you don't have uv installed:

# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Install Agentic AQUA:

uv tool install --python 3.13 agentic-aqua

This creates a permanent agentic-aqua executable. Find its full path with:

which agentic-aqua
# Example: /Users/yourname/.local/bin/agentic-aqua

Configure Claude Desktop (~/.claude/claude_desktop_config.json) using that path:

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/agentic-aqua",
"args": []
}
}
}

Restart Claude Desktop and you're ready to use Bitcoin and Liquid wallets.

Updating / removing:uv tool upgrade agentic-aqua to update, uv tool uninstall agentic-aqua to remove.

For Developers

Clone and install from source:

git clone https://github.com/jan3dev/agentic-aqua.git
cd agentic-aqua
uv python install 3.13
uv sync --python 3.13

Configure Claude Desktop using the full path to uv (find with which uv):

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/uv",
"args": ["run", "--python", "3.13", "--directory", "/absolute/path/to/agentic-aqua", "python", "-m", "aqua.server"]
}
}
}

Quick Start

Once connected, you can ask Claude to:

  • "Create a new wallet" (creates both Bitcoin and Liquid wallets from one seed)
  • "Show my balance" / "What's my Bitcoin balance?"
  • "Generate a receive address" (Liquid or Bitcoin)
  • "Send 10,000 Sats to bc1..." / "Send 0.001 L-BTC to lq1..."
  • "Pay this Lightning invoice: lnbc..."
  • "Receive 50,000 Sats via Lightning"
  • "Delete my wallet"

Available Tools

Wallet Management

ToolDescription
lw_generate_mnemonicGenerate new BIP39 seed
lw_import_mnemonicImport wallet from seed (also creates Bitcoin wallet)
lw_import_descriptorImport watch-only Liquid wallet from CT descriptor
lw_export_descriptorExport Liquid CT descriptor for watch-only use
btc_import_descriptorImport watch-only Bitcoin wallet from BIP84 descriptor
btc_export_descriptorExport Bitcoin BIP84 descriptors + xpub
lw_list_walletsList all wallets
delete_walletDelete a wallet and all its cached data

⚠️ Bitcoin and Liquid descriptors cannot be derived from each other (different BIP84 paths + Liquid's SLIP-77 blinding key). To watch a unified wallet, import both descriptors separately.

Liquid (lw_*)

ToolDescription
lw_balanceGet wallet balances (all assets)
lw_addressGenerate Liquid receive address (lq1...)
lw_sendSend L-BTC
lw_send_assetSend any Liquid asset (USDt, etc.)
lw_sweepSweep the entire L-BTC (or one asset) balance to one address
lw_list_assetsList known Liquid assets (asset_id, ticker, name, precision)
lw_transactionsTransaction history
lw_tx_statusGet transaction status (txid or explorer URL)

Bitcoin (btc_*)

ToolDescription
btc_balanceGet Bitcoin balance (sats)
btc_addressGenerate Bitcoin receive address (bc1...)
btc_transactionsBitcoin transaction history
btc_sendSend BTC
btc_sweepSweep the entire Bitcoin balance to one address

Unified

ToolDescription
unified_balanceGet balance for both Bitcoin and Liquid

Lightning

ToolDescription
lightning_receiveGenerate a Lightning invoice to receive L-BTC (100–25,000,000 Sats)
lightning_sendPay a Lightning invoice using L-BTC via Boltz (~0.1% fee)
lightning_transaction_statusCheck status of a Lightning swap (send or receive)
lightning_decodeDecode a BOLT11 invoice without paying it

Swaps — SideSwap (sideswap_*) — BTC ↔ L-BTC pegs and atomic Liquid asset swaps

ToolDescription
sideswap_server_statusLive fees, peg minimums, hot-wallet balance
sideswap_recommendRecommend a peg vs an instant swap for a BTC ↔ L-BTC conversion
sideswap_peg_quoteQuote the receive amount for a peg at current fees
sideswap_peg_inPeg BTC → L-BTC
sideswap_peg_outPeg L-BTC → BTC
sideswap_peg_statusCheck status of a peg order
sideswap_list_assetsList Liquid assets SideSwap supports for atomic swaps
sideswap_quoteRead-only price quote for a Liquid asset swap
sideswap_execute_swapExecute an atomic Liquid asset swap (L-BTC ↔ USDt, etc.)
sideswap_swap_statusCheck status of an atomic asset swap

Swaps — SideShift (sideshift_*) — custodial cross-chain swaps (USDt across chains, BTC ↔ USDt-on-X)

ToolDescription
sideshift_list_coinsList supported coins and networks
sideshift_pair_infoRate / min / max for a pair
sideshift_quoteFixed-rate quote (~15 min TTL)
sideshift_recommendRecommend SideSwap vs SideShift for a pair
sideshift_sendSend funds from the wallet via a fixed-rate shift
sideshift_receiveReceive into the wallet via a variable-rate shift
sideshift_statusCheck status of a shift order

Swaps — Changelly (changelly_*) — USDt-Liquid ↔ USDt on Ethereum/Tron/BSC/Solana/Polygon

ToolDescription
changelly_list_currenciesList currencies Changelly supports
changelly_quoteFixed-rate quote for a USDt-Liquid ↔ USDt-on-X swap
changelly_sendSend USDt-Liquid out to USDt on another chain
changelly_receiveReceive USDt-Liquid from USDt on another chain
changelly_statusCheck status of a swap order

WapuPay (wapupay_*) — pay Argentine bank accounts in ARS, funded with USDT on Liquid

ToolDescription
wapupay_exchange_ratesCurrent exchange rates (e.g. USDT/ARS); public, no key needed
wapupay_quotePreview USDT cost, fee, and rate for an ARS payment
wapupay_create_orderCreate a direct-fiat order; returns a Liquid USDT funding address
wapupay_fund_orderRe-issue funding instructions for an existing order
wapupay_order_statusCheck a direct-fiat order's status
wapupay_ordersList locally-tracked orders
wapupay_transactionsList WapuPay transactions
wapupay_transactionGet a single transaction by id
wapupay_spending_limitMonthly spending limit (USDT) for the account/key
wapupay_provision_accountProvision a WapuPay API key via your JAN3 account

JAN3 Account (jan3_*) — login, sessions, and Lightning Address for your JAN3 account

ToolDescription
jan3_login / jan3_verifyDefault login flow: email OTP → verify, saves the session
jan3_login_start / jan3_login_completeFallback paid captchaless login flow
jan3_session_infoStatus/metadata for a persisted session
jan3_list_sessionsList all persisted sessions
jan3_logoutDelete a persisted session
jan3_user_infoAccount profile + Lightning Address status
jan3_enable_lightning_addressEnable/disable the Lightning Address
jan3_rebind_walletRe-bind Lightning Address delivery to a different wallet (destructive)
jan3_ln_check_usernameCheck if a Lightning username is available
jan3_purchase_ln_usernameBuy/update the Lightning username (on-chain payment)

Utilities

ToolDescription
qr_generateGenerate a PNG QR code for any content (address, invoice, URI)
qr_decodeDecode a QR code from an image file
doctorDiagnose (and optionally repair) the ~/.aqua/config.json config file

CLI

Agentic AQUA also ships with a Click-based CLI (aqua) for direct, scriptable wallet operations. It exposes the same operations as the MCP tools.

# Discover commands
aqua --help
aqua wallet --help
aqua btc --help
aqua liquid --help
aqua lightning --help
aqua sideswap --help
aqua sideshift --help
aqua changelly --help
aqua wapupay --help
aqua jan3 --help
aqua qr --help
# Wallet management
aqua wallet generate-mnemonic
aqua wallet import-mnemonic --mnemonic-stdin --wallet-name default --network mainnet --password-stdin
aqua wallet list
aqua wallet delete --wallet-name old
# Watch-only descriptors (Bitcoin and Liquid are separate)
aqua btc export-descriptor --wallet-name default
aqua btc import-descriptor --wallet-name cold --descriptor "wpkh([fp/84h/0h/0h]xpub.../0/*)#cs"
aqua liquid export-descriptor --wallet-name default
aqua liquid import-descriptor --wallet-name cold --descriptor "ct(slip77(...),elwpkh(...))"# Balances
aqua balance # unified (BTC + Liquid)
aqua btc balance --wallet-name default
aqua liquid balance --wallet-name default
# Receive addresses
aqua btc address
aqua liquid address
# Send (--wallet-name is required for on-chain sends)
aqua btc send --wallet-name default --address bc1... --amount 10000
aqua liquid send --wallet-name default --address lq1... --amount 50000
aqua liquid send-asset --wallet-name default --address lq1... --amount 1000000 --asset-id <asset_id># (or use --asset-ticker USDt instead of --asset-id)# Transaction history & status
aqua btc transactions
aqua liquid transactions
aqua liquid tx-status --tx <txid|explorer_url># Lightning (L-BTC via Boltz / Ankara)
aqua lightning receive --amount 50000
aqua lightning send --invoice lnbc...
aqua lightning status --swap-id <id>
aqua lightning decode --invoice lnbc...
# Swaps & pegs
aqua sideswap peg-in --wallet-name default # BTC -> L-BTC
aqua sideswap peg-out --amount 50000 --btc-address bc1... --wallet-name default
aqua sideswap swap --asset-ticker USDt --amount 50000 --wallet-name default
aqua sideshift send --deposit-coin btc --deposit-network liquid --settle-coin usdt --settle-network tron \
--settle-address T... --deposit-amount 0.001 --wallet-name default
aqua changelly send --external-network tron --settle-address T... --amount-from 100 --wallet-name default
# WapuPay (pay ARS bank accounts, funded with USDT on Liquid)
aqua wapupay quote --amount-ars 10000 --alias some.alias
aqua wapupay create-order --amount-ars 10000 --alias some.alias --wallet-name default
# then fund the returned address:
aqua liquid send-asset --wallet-name default --address <funding_address> --amount <amount> --asset-ticker USDt
# QR
aqua qr decode ./invoice-qr.png
# Run as MCP stdio server
aqua serve # recommended
aqua-mcp # direct MCP entrypoint

Output defaults to a human-readable table on the terminal and JSON when piped. Force a format with --format json or --format pretty.

Loading seeds safely

Avoid pasting seeds into the chat with your agent. Because it will persist in logs and will be sent to the AI provider, agent transcripts may persist them. The recommended workflow is to use this command that hides the text input:

aqua wallet import-mnemonic --mnemonic-stdin --wallet-name defaultx --network mainnet --password-stdin

The CLI honors these variables out of the box:

VariableUsed by
AQUA_MNEMONICwallet import-mnemonic
AQUA_PASSWORDwallet import-mnemonic, btc send, liquid send, liquid send-asset, lightning send, lightning receive
AQUA_<OPTION>Any CLI option (Click auto_envvar_prefix="AQUA") — e.g. AQUA_WALLET_NAME=default

If you would rather pipe secrets from a password manager, every secret-bearing command also accepts --mnemonic-stdin / --password-stdin:

pass show crypto/aqua-mnemonic | aqua-cli wallet import-mnemonic --mnemonic-stdin

Tips:

  • Never commit .env or secrets.env files (the project's .gitignore already excludes them).
  • Prefer set -a; . file; set +a over export $(cat file) — the former tolerates spaces and quotes inside values.
  • After importing a wallet, the seed is no longer needed for day-to-day operations; only AQUA_PASSWORD is used to sign transactions.

JAN3 account login

Two login flows, both multi-account (one session per email), ending with a locally saved session:

# Default (free email-OTP)
aqua jan3 login --email you@example.com # emails an OTP
aqua jan3 verify --email you@example.com --otp 123456
# Fallback (paid captchaless), for accounts that can't use the free flow
aqua jan3 login-start --email you@example.com --wallet-name default --password-stdin
aqua jan3 login-complete --email you@example.com --otp 123456

Once logged in:

aqua jan3 list-sessions
aqua jan3 user-info --email you@example.com
aqua jan3 logout --email you@example.com

Configuration

Default config location: ~/.aqua/config.json

Migrating from aqua-mcp? The config dir moved from ~/.aqua-mcp to ~/.aqua. There is no automatic migration. To carry over your wallets, run once:

mv ~/.aqua-mcp ~/.aqua
{
"network": "mainnet",
"default_wallet": "default",
"electrum_url": null,
"auto_sync": true
}

Security

Seeds are encrypted at rest using a password (PBKDF2 + Fernet). Without a password, the seed is stored base64-encoded only — use a password for real funds. Note: this password is NOT a BIP39 passphrase; the derived Liquid/Bitcoin keys depend solely on the seed, so the same seed restores identical descriptors in any BIP39-compliant wallet (AQUA, Blockstream App, Jade, etc.).

For maximum security you can:

  1. Generate wallet on an air-gapped device
  2. Export the CT descriptor
  3. Import as watch-only on your daily machine

All private key operations happen locally. Only blockchain sync uses Blockstream's public servers.

Development

# Install with dev dependencies
uv python install 3.13
uv sync --python 3.13 --all-extras
# Run tests
uv run --python 3.13 python -m pytest tests/
# Format code
uv run black src/
uv run ruff check src/

Architecture

AI Assistant ←→ MCP Server (Python) ←→ LWK (Liquid) ──→ Electrum/Esplora
│
├──→ BDK (Bitcoin) ──→ Esplora (Blockstream)
│
└──→ Boltz / Ankara ──→ Lightning

Credits

Built with:

  • LWK - Liquid Wallet Kit by Blockstream
  • BDK - Bitcoin Development Kit
  • MCP - Model Context Protocol
  • Boltz - Submarine swaps for Lightning

About

MCP server and CLI to manage assets in Bitcoin and Liquid

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Agentic AQUA

MCP server and CLI for managing Bitcoin and Liquid Network wallets through AI assistants like Claude. One seed backs both networks (unified wallet). Agentic AQUA can also operate on the Lightning Network.

Features

  • Generate & Import - Create new wallets or import existing seeds
  • Unified Wallet - One seed (mnemonic) for Bitcoin and Liquid; unified_balance shows both
  • Bitcoin (onchain) - BIP84 wallets, balance and send via btc_* tools (BDK)
  • Watch-Only - Import CT descriptors for balance monitoring
  • Send & Receive - Full transaction support (L-BTC, BTC, and Liquid assets like USDt)
  • Lightning - Send and receive via Lightning using L-BTC
  • Assets - Native support for L-BTC, USDt, and all Liquid assets
  • Swaps & Pegs - Convert BTC ↔ L-BTC and swap Liquid/cross-chain assets via SideSwap, SideShift, and Changelly
  • JAN3 Account - Login, Lightning Address, and WapuPay (pay ARS bank accounts with USDT) via your JAN3 account
  • Secure - Encrypted storage, no remote servers for keys

Installation

Quickest way: just ask your AI agent directly:

Install this MCP server: https://pypi.org/project/agentic-aqua/

Python 3.13 required.

Recommended (uv tool install)

If you don't have uv installed:

# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Install Agentic AQUA:

uv tool install --python 3.13 agentic-aqua

This creates a permanent agentic-aqua executable. Find its full path with:

which agentic-aqua
# Example: /Users/yourname/.local/bin/agentic-aqua

Configure Claude Desktop (~/.claude/claude_desktop_config.json) using that path:

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/agentic-aqua",
"args": []
}
}
}

Restart Claude Desktop and you're ready to use Bitcoin and Liquid wallets.

Updating / removing:uv tool upgrade agentic-aqua to update, uv tool uninstall agentic-aqua to remove.

For Developers

Clone and install from source:

git clone https://github.com/jan3dev/agentic-aqua.git
cd agentic-aqua
uv python install 3.13
uv sync --python 3.13

Configure Claude Desktop using the full path to uv (find with which uv):

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/uv",
"args": ["run", "--python", "3.13", "--directory", "/absolute/path/to/agentic-aqua", "python", "-m", "aqua.server"]
}
}
}

Quick Start

Once connected, you can ask Claude to:

  • "Create a new wallet" (creates both Bitcoin and Liquid wallets from one seed)
  • "Show my balance" / "What's my Bitcoin balance?"
  • "Generate a receive address" (Liquid or Bitcoin)
  • "Send 10,000 Sats to bc1..." / "Send 0.001 L-BTC to lq1..."
  • "Pay this Lightning invoice: lnbc..."
  • "Receive 50,000 Sats via Lightning"
  • "Delete my wallet"

Available Tools

Wallet Management

ToolDescription
lw_generate_mnemonicGenerate new BIP39 seed
lw_import_mnemonicImport wallet from seed (also creates Bitcoin wallet)
lw_import_descriptorImport watch-only Liquid wallet from CT descriptor
lw_export_descriptorExport Liquid CT descriptor for watch-only use
btc_import_descriptorImport watch-only Bitcoin wallet from BIP84 descriptor
btc_export_descriptorExport Bitcoin BIP84 descriptors + xpub
lw_list_walletsList all wallets
delete_walletDelete a wallet and all its cached data

⚠️ Bitcoin and Liquid descriptors cannot be derived from each other (different BIP84 paths + Liquid's SLIP-77 blinding key). To watch a unified wallet, import both descriptors separately.

Liquid (lw_*)

ToolDescription
lw_balanceGet wallet balances (all assets)
lw_addressGenerate Liquid receive address (lq1...)
lw_sendSend L-BTC
lw_send_assetSend any Liquid asset (USDt, etc.)
lw_sweepSweep the entire L-BTC (or one asset) balance to one address
lw_list_assetsList known Liquid assets (asset_id, ticker, name, precision)
lw_transactionsTransaction history
lw_tx_statusGet transaction status (txid or explorer URL)

Bitcoin (btc_*)

ToolDescription
btc_balanceGet Bitcoin balance (sats)
btc_addressGenerate Bitcoin receive address (bc1...)
btc_transactionsBitcoin transaction history
btc_sendSend BTC
btc_sweepSweep the entire Bitcoin balance to one address

Unified

ToolDescription
unified_balanceGet balance for both Bitcoin and Liquid

Lightning

ToolDescription
lightning_receiveGenerate a Lightning invoice to receive L-BTC (100–25,000,000 Sats)
lightning_sendPay a Lightning invoice using L-BTC via Boltz (~0.1% fee)
lightning_transaction_statusCheck status of a Lightning swap (send or receive)
lightning_decodeDecode a BOLT11 invoice without paying it

Swaps — SideSwap (sideswap_*) — BTC ↔ L-BTC pegs and atomic Liquid asset swaps

ToolDescription
sideswap_server_statusLive fees, peg minimums, hot-wallet balance
sideswap_recommendRecommend a peg vs an instant swap for a BTC ↔ L-BTC conversion
sideswap_peg_quoteQuote the receive amount for a peg at current fees
sideswap_peg_inPeg BTC → L-BTC
sideswap_peg_outPeg L-BTC → BTC
sideswap_peg_statusCheck status of a peg order
sideswap_list_assetsList Liquid assets SideSwap supports for atomic swaps
sideswap_quoteRead-only price quote for a Liquid asset swap
sideswap_execute_swapExecute an atomic Liquid asset swap (L-BTC ↔ USDt, etc.)
sideswap_swap_statusCheck status of an atomic asset swap

Swaps — SideShift (sideshift_*) — custodial cross-chain swaps (USDt across chains, BTC ↔ USDt-on-X)

ToolDescription
sideshift_list_coinsList supported coins and networks
sideshift_pair_infoRate / min / max for a pair
sideshift_quoteFixed-rate quote (~15 min TTL)
sideshift_recommendRecommend SideSwap vs SideShift for a pair
sideshift_sendSend funds from the wallet via a fixed-rate shift
sideshift_receiveReceive into the wallet via a variable-rate shift
sideshift_statusCheck status of a shift order

Swaps — Changelly (changelly_*) — USDt-Liquid ↔ USDt on Ethereum/Tron/BSC/Solana/Polygon

ToolDescription
changelly_list_currenciesList currencies Changelly supports
changelly_quoteFixed-rate quote for a USDt-Liquid ↔ USDt-on-X swap
changelly_sendSend USDt-Liquid out to USDt on another chain
changelly_receiveReceive USDt-Liquid from USDt on another chain
changelly_statusCheck status of a swap order

WapuPay (wapupay_*) — pay Argentine bank accounts in ARS, funded with USDT on Liquid

ToolDescription
wapupay_exchange_ratesCurrent exchange rates (e.g. USDT/ARS); public, no key needed
wapupay_quotePreview USDT cost, fee, and rate for an ARS payment
wapupay_create_orderCreate a direct-fiat order; returns a Liquid USDT funding address
wapupay_fund_orderRe-issue funding instructions for an existing order
wapupay_order_statusCheck a direct-fiat order's status
wapupay_ordersList locally-tracked orders
wapupay_transactionsList WapuPay transactions
wapupay_transactionGet a single transaction by id
wapupay_spending_limitMonthly spending limit (USDT) for the account/key
wapupay_provision_accountProvision a WapuPay API key via your JAN3 account

JAN3 Account (jan3_*) — login, sessions, and Lightning Address for your JAN3 account

ToolDescription
jan3_login / jan3_verifyDefault login flow: email OTP → verify, saves the session
jan3_login_start / jan3_login_completeFallback paid captchaless login flow
jan3_session_infoStatus/metadata for a persisted session
jan3_list_sessionsList all persisted sessions
jan3_logoutDelete a persisted session
jan3_user_infoAccount profile + Lightning Address status
jan3_enable_lightning_addressEnable/disable the Lightning Address
jan3_rebind_walletRe-bind Lightning Address delivery to a different wallet (destructive)
jan3_ln_check_usernameCheck if a Lightning username is available
jan3_purchase_ln_usernameBuy/update the Lightning username (on-chain payment)

Utilities

ToolDescription
qr_generateGenerate a PNG QR code for any content (address, invoice, URI)
qr_decodeDecode a QR code from an image file
doctorDiagnose (and optionally repair) the ~/.aqua/config.json config file

CLI

Agentic AQUA also ships with a Click-based CLI (aqua) for direct, scriptable wallet operations. It exposes the same operations as the MCP tools.

# Discover commands
aqua --help
aqua wallet --help
aqua btc --help
aqua liquid --help
aqua lightning --help
aqua sideswap --help
aqua sideshift --help
aqua changelly --help
aqua wapupay --help
aqua jan3 --help
aqua qr --help
# Wallet management
aqua wallet generate-mnemonic
aqua wallet import-mnemonic --mnemonic-stdin --wallet-name default --network mainnet --password-stdin
aqua wallet list
aqua wallet delete --wallet-name old
# Watch-only descriptors (Bitcoin and Liquid are separate)
aqua btc export-descriptor --wallet-name default
aqua btc import-descriptor --wallet-name cold --descriptor "wpkh([fp/84h/0h/0h]xpub.../0/*)#cs"
aqua liquid export-descriptor --wallet-name default
aqua liquid import-descriptor --wallet-name cold --descriptor "ct(slip77(...),elwpkh(...))"# Balances
aqua balance # unified (BTC + Liquid)
aqua btc balance --wallet-name default
aqua liquid balance --wallet-name default
# Receive addresses
aqua btc address
aqua liquid address
# Send (--wallet-name is required for on-chain sends)
aqua btc send --wallet-name default --address bc1... --amount 10000
aqua liquid send --wallet-name default --address lq1... --amount 50000
aqua liquid send-asset --wallet-name default --address lq1... --amount 1000000 --asset-id <asset_id># (or use --asset-ticker USDt instead of --asset-id)# Transaction history & status
aqua btc transactions
aqua liquid transactions
aqua liquid tx-status --tx <txid|explorer_url># Lightning (L-BTC via Boltz / Ankara)
aqua lightning receive --amount 50000
aqua lightning send --invoice lnbc...
aqua lightning status --swap-id <id>
aqua lightning decode --invoice lnbc...
# Swaps & pegs
aqua sideswap peg-in --wallet-name default # BTC -> L-BTC
aqua sideswap peg-out --amount 50000 --btc-address bc1... --wallet-name default
aqua sideswap swap --asset-ticker USDt --amount 50000 --wallet-name default
aqua sideshift send --deposit-coin btc --deposit-network liquid --settle-coin usdt --settle-network tron \
--settle-address T... --deposit-amount 0.001 --wallet-name default
aqua changelly send --external-network tron --settle-address T... --amount-from 100 --wallet-name default
# WapuPay (pay ARS bank accounts, funded with USDT on Liquid)
aqua wapupay quote --amount-ars 10000 --alias some.alias
aqua wapupay create-order --amount-ars 10000 --alias some.alias --wallet-name default
# then fund the returned address:
aqua liquid send-asset --wallet-name default --address <funding_address> --amount <amount> --asset-ticker USDt
# QR
aqua qr decode ./invoice-qr.png
# Run as MCP stdio server
aqua serve # recommended
aqua-mcp # direct MCP entrypoint

Output defaults to a human-readable table on the terminal and JSON when piped. Force a format with --format json or --format pretty.

Loading seeds safely

Avoid pasting seeds into the chat with your agent. Because it will persist in logs and will be sent to the AI provider, agent transcripts may persist them. The recommended workflow is to use this command that hides the text input:

aqua wallet import-mnemonic --mnemonic-stdin --wallet-name defaultx --network mainnet --password-stdin

The CLI honors these variables out of the box:

VariableUsed by
AQUA_MNEMONICwallet import-mnemonic
AQUA_PASSWORDwallet import-mnemonic, btc send, liquid send, liquid send-asset, lightning send, lightning receive
AQUA_<OPTION>Any CLI option (Click auto_envvar_prefix="AQUA") — e.g. AQUA_WALLET_NAME=default

If you would rather pipe secrets from a password manager, every secret-bearing command also accepts --mnemonic-stdin / --password-stdin:

pass show crypto/aqua-mnemonic | aqua-cli wallet import-mnemonic --mnemonic-stdin

Tips:

  • Never commit .env or secrets.env files (the project's .gitignore already excludes them).
  • Prefer set -a; . file; set +a over export $(cat file) — the former tolerates spaces and quotes inside values.
  • After importing a wallet, the seed is no longer needed for day-to-day operations; only AQUA_PASSWORD is used to sign transactions.

JAN3 account login

Two login flows, both multi-account (one session per email), ending with a locally saved session:

# Default (free email-OTP)
aqua jan3 login --email you@example.com # emails an OTP
aqua jan3 verify --email you@example.com --otp 123456
# Fallback (paid captchaless), for accounts that can't use the free flow
aqua jan3 login-start --email you@example.com --wallet-name default --password-stdin
aqua jan3 login-complete --email you@example.com --otp 123456

Once logged in:

aqua jan3 list-sessions
aqua jan3 user-info --email you@example.com
aqua jan3 logout --email you@example.com

Configuration

Default config location: ~/.aqua/config.json

Migrating from aqua-mcp? The config dir moved from ~/.aqua-mcp to ~/.aqua. There is no automatic migration. To carry over your wallets, run once:

mv ~/.aqua-mcp ~/.aqua
{
"network": "mainnet",
"default_wallet": "default",
"electrum_url": null,
"auto_sync": true
}

Security

Seeds are encrypted at rest using a password (PBKDF2 + Fernet). Without a password, the seed is stored base64-encoded only — use a password for real funds. Note: this password is NOT a BIP39 passphrase; the derived Liquid/Bitcoin keys depend solely on the seed, so the same seed restores identical descriptors in any BIP39-compliant wallet (AQUA, Blockstream App, Jade, etc.).

For maximum security you can:

  1. Generate wallet on an air-gapped device
  2. Export the CT descriptor
  3. Import as watch-only on your daily machine

All private key operations happen locally. Only blockchain sync uses Blockstream's public servers.

Development

# Install with dev dependencies
uv python install 3.13
uv sync --python 3.13 --all-extras
# Run tests
uv run --python 3.13 python -m pytest tests/
# Format code
uv run black src/
uv run ruff check src/

Architecture

AI Assistant ←→ MCP Server (Python) ←→ LWK (Liquid) ──→ Electrum/Esplora
│
├──→ BDK (Bitcoin) ──→ Esplora (Blockstream)
│
└──→ Boltz / Ankara ──→ Lightning

Credits

Built with:

  • LWK - Liquid Wallet Kit by Blockstream
  • BDK - Bitcoin Development Kit
  • MCP - Model Context Protocol
  • Boltz - Submarine swaps for Lightning

About

MCP server and CLI to manage assets in Bitcoin and Liquid

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Agentic AQUA

MCP server and CLI for managing Bitcoin and Liquid Network wallets through AI assistants like Claude. One seed backs both networks (unified wallet). Agentic AQUA can also operate on the Lightning Network.

Features

  • Generate & Import - Create new wallets or import existing seeds
  • Unified Wallet - One seed (mnemonic) for Bitcoin and Liquid; unified_balance shows both
  • Bitcoin (onchain) - BIP84 wallets, balance and send via btc_* tools (BDK)
  • Watch-Only - Import CT descriptors for balance monitoring
  • Send & Receive - Full transaction support (L-BTC, BTC, and Liquid assets like USDt)
  • Lightning - Send and receive via Lightning using L-BTC
  • Assets - Native support for L-BTC, USDt, and all Liquid assets
  • Swaps & Pegs - Convert BTC ↔ L-BTC and swap Liquid/cross-chain assets via SideSwap, SideShift, and Changelly
  • JAN3 Account - Login, Lightning Address, and WapuPay (pay ARS bank accounts with USDT) via your JAN3 account
  • Secure - Encrypted storage, no remote servers for keys

Installation

Quickest way: just ask your AI agent directly:

Install this MCP server: https://pypi.org/project/agentic-aqua/

Python 3.13 required.

Recommended (uv tool install)

If you don't have uv installed:

# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Install Agentic AQUA:

uv tool install --python 3.13 agentic-aqua

This creates a permanent agentic-aqua executable. Find its full path with:

which agentic-aqua
# Example: /Users/yourname/.local/bin/agentic-aqua

Configure Claude Desktop (~/.claude/claude_desktop_config.json) using that path:

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/agentic-aqua",
"args": []
}
}
}

Restart Claude Desktop and you're ready to use Bitcoin and Liquid wallets.

Updating / removing:uv tool upgrade agentic-aqua to update, uv tool uninstall agentic-aqua to remove.

For Developers

Clone and install from source:

git clone https://github.com/jan3dev/agentic-aqua.git
cd agentic-aqua
uv python install 3.13
uv sync --python 3.13

Configure Claude Desktop using the full path to uv (find with which uv):

{
"mcpServers": {
"agentic-aqua": {
"command": "/full/path/to/uv",
"args": ["run", "--python", "3.13", "--directory", "/absolute/path/to/agentic-aqua", "python", "-m", "aqua.server"]
}
}
}

Quick Start

Once connected, you can ask Claude to:

  • "Create a new wallet" (creates both Bitcoin and Liquid wallets from one seed)
  • "Show my balance" / "What's my Bitcoin balance?"
  • "Generate a receive address" (Liquid or Bitcoin)
  • "Send 10,000 Sats to bc1..." / "Send 0.001 L-BTC to lq1..."
  • "Pay this Lightning invoice: lnbc..."
  • "Receive 50,000 Sats via Lightning"
  • "Delete my wallet"

Available Tools

Wallet Management

ToolDescription
lw_generate_mnemonicGenerate new BIP39 seed
lw_import_mnemonicImport wallet from seed (also creates Bitcoin wallet)
lw_import_descriptorImport watch-only Liquid wallet from CT descriptor
lw_export_descriptorExport Liquid CT descriptor for watch-only use
btc_import_descriptorImport watch-only Bitcoin wallet from BIP84 descriptor
btc_export_descriptorExport Bitcoin BIP84 descriptors + xpub
lw_list_walletsList all wallets
delete_walletDelete a wallet and all its cached data

⚠️ Bitcoin and Liquid descriptors cannot be derived from each other (different BIP84 paths + Liquid's SLIP-77 blinding key). To watch a unified wallet, import both descriptors separately.

Liquid (lw_*)

ToolDescription
lw_balanceGet wallet balances (all assets)
lw_addressGenerate Liquid receive address (lq1...)
lw_sendSend L-BTC
lw_send_assetSend any Liquid asset (USDt, etc.)
lw_sweepSweep the entire L-BTC (or one asset) balance to one address
lw_list_assetsList known Liquid assets (asset_id, ticker, name, precision)
lw_transactionsTransaction history
lw_tx_statusGet transaction status (txid or explorer URL)

Bitcoin (btc_*)

ToolDescription
btc_balanceGet Bitcoin balance (sats)
btc_addressGenerate Bitcoin receive address (bc1...)
btc_transactionsBitcoin transaction history
btc_sendSend BTC
btc_sweepSweep the entire Bitcoin balance to one address

Unified

ToolDescription
unified_balanceGet balance for both Bitcoin and Liquid

Lightning

ToolDescription
lightning_receiveGenerate a Lightning invoice to receive L-BTC (100–25,000,000 Sats)
lightning_sendPay a Lightning invoice using L-BTC via Boltz (~0.1% fee)
lightning_transaction_statusCheck status of a Lightning swap (send or receive)
lightning_decodeDecode a BOLT11 invoice without paying it

Swaps — SideSwap (sideswap_*) — BTC ↔ L-BTC pegs and atomic Liquid asset swaps

ToolDescription
sideswap_server_statusLive fees, peg minimums, hot-wallet balance
sideswap_recommendRecommend a peg vs an instant swap for a BTC ↔ L-BTC conversion
sideswap_peg_quoteQuote the receive amount for a peg at current fees
sideswap_peg_inPeg BTC → L-BTC
sideswap_peg_outPeg L-BTC → BTC
sideswap_peg_statusCheck status of a peg order
sideswap_list_assetsList Liquid assets SideSwap supports for atomic swaps
sideswap_quoteRead-only price quote for a Liquid asset swap
sideswap_execute_swapExecute an atomic Liquid asset swap (L-BTC ↔ USDt, etc.)
sideswap_swap_statusCheck status of an atomic asset swap

Swaps — SideShift (sideshift_*) — custodial cross-chain swaps (USDt across chains, BTC ↔ USDt-on-X)

ToolDescription
sideshift_list_coinsList supported coins and networks
sideshift_pair_infoRate / min / max for a pair
sideshift_quoteFixed-rate quote (~15 min TTL)
sideshift_recommendRecommend SideSwap vs SideShift for a pair
sideshift_sendSend funds from the wallet via a fixed-rate shift
sideshift_receiveReceive into the wallet via a variable-rate shift
sideshift_statusCheck status of a shift order

Swaps — Changelly (changelly_*) — USDt-Liquid ↔ USDt on Ethereum/Tron/BSC/Solana/Polygon

ToolDescription
changelly_list_currenciesList currencies Changelly supports
changelly_quoteFixed-rate quote for a USDt-Liquid ↔ USDt-on-X swap
changelly_sendSend USDt-Liquid out to USDt on another chain
changelly_receiveReceive USDt-Liquid from USDt on another chain
changelly_statusCheck status of a swap order

WapuPay (wapupay_*) — pay Argentine bank accounts in ARS, funded with USDT on Liquid

ToolDescription
wapupay_exchange_ratesCurrent exchange rates (e.g. USDT/ARS); public, no key needed
wapupay_quotePreview USDT cost, fee, and rate for an ARS payment
wapupay_create_orderCreate a direct-fiat order; returns a Liquid USDT funding address
wapupay_fund_orderRe-issue funding instructions for an existing order
wapupay_order_statusCheck a direct-fiat order's status
wapupay_ordersList locally-tracked orders
wapupay_transactionsList WapuPay transactions
wapupay_transactionGet a single transaction by id
wapupay_spending_limitMonthly spending limit (USDT) for the account/key
wapupay_provision_accountProvision a WapuPay API key via your JAN3 account

JAN3 Account (jan3_*) — login, sessions, and Lightning Address for your JAN3 account

ToolDescription
jan3_login / jan3_verifyDefault login flow: email OTP → verify, saves the session
jan3_login_start / jan3_login_completeFallback paid captchaless login flow
jan3_session_infoStatus/metadata for a persisted session
jan3_list_sessionsList all persisted sessions
jan3_logoutDelete a persisted session
jan3_user_infoAccount profile + Lightning Address status
jan3_enable_lightning_addressEnable/disable the Lightning Address
jan3_rebind_walletRe-bind Lightning Address delivery to a different wallet (destructive)
jan3_ln_check_usernameCheck if a Lightning username is available
jan3_purchase_ln_usernameBuy/update the Lightning username (on-chain payment)

Utilities

ToolDescription
qr_generateGenerate a PNG QR code for any content (address, invoice, URI)
qr_decodeDecode a QR code from an image file
doctorDiagnose (and optionally repair) the ~/.aqua/config.json config file

CLI

Agentic AQUA also ships with a Click-based CLI (aqua) for direct, scriptable wallet operations. It exposes the same operations as the MCP tools.

# Discover commands
aqua --help
aqua wallet --help
aqua btc --help
aqua liquid --help
aqua lightning --help
aqua sideswap --help
aqua sideshift --help
aqua changelly --help
aqua wapupay --help
aqua jan3 --help
aqua qr --help
# Wallet management
aqua wallet generate-mnemonic
aqua wallet import-mnemonic --mnemonic-stdin --wallet-name default --network mainnet --password-stdin
aqua wallet list
aqua wallet delete --wallet-name old
# Watch-only descriptors (Bitcoin and Liquid are separate)
aqua btc export-descriptor --wallet-name default
aqua btc import-descriptor --wallet-name cold --descriptor "wpkh([fp/84h/0h/0h]xpub.../0/*)#cs"
aqua liquid export-descriptor --wallet-name default
aqua liquid import-descriptor --wallet-name cold --descriptor "ct(slip77(...),elwpkh(...))"# Balances
aqua balance # unified (BTC + Liquid)
aqua btc balance --wallet-name default
aqua liquid balance --wallet-name default
# Receive addresses
aqua btc address
aqua liquid address
# Send (--wallet-name is required for on-chain sends)
aqua btc send --wallet-name default --address bc1... --amount 10000
aqua liquid send --wallet-name default --address lq1... --amount 50000
aqua liquid send-asset --wallet-name default --address lq1... --amount 1000000 --asset-id <asset_id># (or use --asset-ticker USDt instead of --asset-id)# Transaction history & status
aqua btc transactions
aqua liquid transactions
aqua liquid tx-status --tx <txid|explorer_url># Lightning (L-BTC via Boltz / Ankara)
aqua lightning receive --amount 50000
aqua lightning send --invoice lnbc...
aqua lightning status --swap-id <id>
aqua lightning decode --invoice lnbc...
# Swaps & pegs
aqua sideswap peg-in --wallet-name default # BTC -> L-BTC
aqua sideswap peg-out --amount 50000 --btc-address bc1... --wallet-name default
aqua sideswap swap --asset-ticker USDt --amount 50000 --wallet-name default
aqua sideshift send --deposit-coin btc --deposit-network liquid --settle-coin usdt --settle-network tron \
--settle-address T... --deposit-amount 0.001 --wallet-name default
aqua changelly send --external-network tron --settle-address T... --amount-from 100 --wallet-name default
# WapuPay (pay ARS bank accounts, funded with USDT on Liquid)
aqua wapupay quote --amount-ars 10000 --alias some.alias
aqua wapupay create-order --amount-ars 10000 --alias some.alias --wallet-name default
# then fund the returned address:
aqua liquid send-asset --wallet-name default --address <funding_address> --amount <amount> --asset-ticker USDt
# QR
aqua qr decode ./invoice-qr.png
# Run as MCP stdio server
aqua serve # recommended
aqua-mcp # direct MCP entrypoint

Output defaults to a human-readable table on the terminal and JSON when piped. Force a format with --format json or --format pretty.

Loading seeds safely

Avoid pasting seeds into the chat with your agent. Because it will persist in logs and will be sent to the AI provider, agent transcripts may persist them. The recommended workflow is to use this command that hides the text input:

aqua wallet import-mnemonic --mnemonic-stdin --wallet-name defaultx --network mainnet --password-stdin

The CLI honors these variables out of the box:

VariableUsed by
AQUA_MNEMONICwallet import-mnemonic
AQUA_PASSWORDwallet import-mnemonic, btc send, liquid send, liquid send-asset, lightning send, lightning receive
AQUA_<OPTION>Any CLI option (Click auto_envvar_prefix="AQUA") — e.g. AQUA_WALLET_NAME=default

If you would rather pipe secrets from a password manager, every secret-bearing command also accepts --mnemonic-stdin / --password-stdin:

pass show crypto/aqua-mnemonic | aqua-cli wallet import-mnemonic --mnemonic-stdin

Tips:

  • Never commit .env or secrets.env files (the project's .gitignore already excludes them).
  • Prefer set -a; . file; set +a over export $(cat file) — the former tolerates spaces and quotes inside values.
  • After importing a wallet, the seed is no longer needed for day-to-day operations; only AQUA_PASSWORD is used to sign transactions.

JAN3 account login

Two login flows, both multi-account (one session per email), ending with a locally saved session:

# Default (free email-OTP)
aqua jan3 login --email you@example.com # emails an OTP
aqua jan3 verify --email you@example.com --otp 123456
# Fallback (paid captchaless), for accounts that can't use the free flow
aqua jan3 login-start --email you@example.com --wallet-name default --password-stdin
aqua jan3 login-complete --email you@example.com --otp 123456

Once logged in:

aqua jan3 list-sessions
aqua jan3 user-info --email you@example.com
aqua jan3 logout --email you@example.com

Configuration

Default config location: ~/.aqua/config.json

Migrating from aqua-mcp? The config dir moved from ~/.aqua-mcp to ~/.aqua. There is no automatic migration. To carry over your wallets, run once:

mv ~/.aqua-mcp ~/.aqua
{
"network": "mainnet",
"default_wallet": "default",
"electrum_url": null,
"auto_sync": true
}

Security

Seeds are encrypted at rest using a password (PBKDF2 + Fernet). Without a password, the seed is stored base64-encoded only — use a password for real funds. Note: this password is NOT a BIP39 passphrase; the derived Liquid/Bitcoin keys depend solely on the seed, so the same seed restores identical descriptors in any BIP39-compliant wallet (AQUA, Blockstream App, Jade, etc.).

For maximum security you can:

  1. Generate wallet on an air-gapped device
  2. Export the CT descriptor
  3. Import as watch-only on your daily machine

All private key operations happen locally. Only blockchain sync uses Blockstream's public servers.

Development

# Install with dev dependencies
uv python install 3.13
uv sync --python 3.13 --all-extras
# Run tests
uv run --python 3.13 python -m pytest tests/
# Format code
uv run black src/
uv run ruff check src/

Architecture

AI Assistant ←→ MCP Server (Python) ←→ LWK (Liquid) ──→ Electrum/Esplora
│
├──→ BDK (Bitcoin) ──→ Esplora (Blockstream)
│
└──→ Boltz / Ankara ──→ Lightning

Credits

Built with:

  • LWK - Liquid Wallet Kit by Blockstream
  • BDK - Bitcoin Development Kit
  • MCP - Model Context Protocol
  • Boltz - Submarine swaps for Lightning

About

MCP server and CLI to manage assets in Bitcoin and Liquid

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages