agenta-monero
Use when making or receiving Monero (XMR) payments. Generates addresses, sends payments, checks balances, verifies transactions, generates and verifies payment proofs, estimates fe…
oen
@tibbar-etihw
Install
$ openclaw skills install @tibbar-etihw/agenta-moneroAgenta-Monero
Shell wrappers over monero-wallet-rpc for autonomous Monero (XMR) payments. All scripts emit JSON to stdout (success) or a structured error JSON to stderr; they compose into receive/send/verify/sweep workflows. Money math is integer piconeros internally; XMR decimal strings appear in output.
WARNING — IRREVERSIBLE FINANCIAL OPERATIONS
- Monero transactions are irreversible. Once broadcast, funds cannot be recovered.
send_xmr.shandsweep_all.shrequire--confirmto broadcast. Without it, they refuse to relay. Use--dry-runto preview without--confirm.sweep_all.shtransfers all unlocked funds from the wallet (or subaddress) to a single destination. A mistaken or maliciously triggered sweep can drain the entire balance.- Always validate the recipient address (
validate_address.sh) and confirm the amount before executing a send or sweep.- The
.envfile containsMONERO_WALLET_PASSWORDand RPC credentials. It is created withchmod 600, but on multi-user systems, shared CI, or agent workspaces with broad read access, an attacker who reads.envcan access the wallet and move funds. Secure the file and the system accordingly.
Use when: generating receive addresses, sending/sweeping XMR, checking balance, verifying an incoming payment or a payment proof, estimating fees, or reconciling transactions by hash.
Prerequisites
- Install Monero CLI tools (≥ 0.18.0): download from https://getmonero.org/downloads/ — you need at minimum
monero-wallet-rpc. Also create a wallet file:monero-wallet-cli --generate-new-wallet ~/Monero/wallets/main --password 'PASS'(write down the 25-word seed). - Bash ≥ 4,
curl,jq,flock(util-linux) — standard on Linux/macOS (brew install jqon macOS). - First-time setup: run
./scripts/interactive_setup.sh(interactive prompts) or tell the Hermes agent "Set up the Agenta-Monero skill" (agent-driven; see First-Time Setup below). Both paths generate RPC credentials, write.env, startmonero-wallet-rpc, and verify readiness. - After setup, every script runs from the skill root. Invoke
./setup.shagain after changing.env.
Permissions & Capabilities
This skill performs the following actions. Operators should review these before approving or invoking the skill in automated workflows:
| Capability | Details |
|---|---|
| Shell execution | Runs curl, jq, flock, monero-wallet-rpc, and standard shell utilities |
| File writes | .env (chmod 600), .netrc (chmod 600, ephemeral), PID/port files, lock files, refresh timestamp |
| Process management | Starts and stops monero-wallet-rpc as a background daemon (PID tracked in $MONERO_LOCK_DIR) |
| Network access | HTTP POST to $MONERO_RPC_URL/json_rpc (localhost by default; can be configured for remote) |
| Credential access | Reads .env for RPC user/password and wallet password; writes .netrc for curl auth; never emits credentials in stdout |
All credential files are created with restrictive permissions (0600 for files, 0700 for the lock directory). The .env file is parsed safely (never sourced) and shell metacharacters are rejected.
First-Time Setup
When a user asks to set up the Agenta-Monero skill, follow this workflow.
Path A — Agent-driven (recommended):
- Ask: "What's the path to your wallet file?"
- Ask: "What's the wallet password?"
- Ask: "Local daemon or remote node?"
- If remote: "What's the daemon address? (e.g. node.example.com:18081)"
- Check:
command -v monero-wallet-rpc— if missing, print install guidance (https://getmonero.org/downloads/) and stop. - Run:
./scripts/interactive_setup.sh --wallet-path "PATH" --wallet-password "PASS" --network mainnet --daemon-type local [--daemon-address "HOST:PORT" if remote] --force - Read the JSON output. If
ready:true→ done. Ifready:false→ checkwarningsand troubleshoot. - To check wallet-rpc status later:
./scripts/wallet_rpc_status.sh. To stop it:./scripts/stop_wallet_rpc.sh.
Path B — Manual interactive script:
Tell the user to run ./scripts/interactive_setup.sh and follow the prompts.
Both paths:
- Generate random RPC credentials (12-char user, 24-char password).
- Write
.env(chmod 600) with all values includingMONERO_WALLET_PASSWORD.- Caution:
.envpersists on disk and contains the wallet password. On multi-user systems or CI, ensure the file is not world-readable, not committed to version control, and not included in backups or log captures.
- Caution:
- Start
monero-wallet-rpcas a background process (PID stored in$MONERO_LOCK_DIR/wallet-rpc.pid). - Run
./setup.shand report readiness. - Credentials are not emitted in stdout JSON. They exist only in
.env(chmod 600). If the user needs to see them, read from.envdirectly.
Quick reference
One compact block per operation. Load references/rpc-reference.md when you need exact JSON-RPC params, full output field lists, or per-operation refresh classification.
create_address.sh --label "Payment from Alice" [--account 0] -> {address, address_index, account}
send_xmr.sh --address ADDR --amount "1.5" -> {tx_hash, fee, amount[, tx_key]}
[--priority 0] [--get-tx-key] [--dry-run] [--confirm]
[--dest '[{"address":"A","amount":"1.0"}]']
estimate_fee.sh --address ADDR --amount "1.5" [--priority 0] -> {fee, amount, priority, num_destinations}
sweep_all.sh --address ADDR [--account 0] [--subaddress N]-->{tx_hash, fee, amount}
[--priority 0] [--dry-run] [--confirm]
check_balance.sh [--account 0] -> {balance, unlocked_balance, blocks_to_unlock, time_to_unlock, account}
get_transfer.sh --tx-hash HASH -> {tx_hash, amount, fee, direction, confirmations, address, address_index, timestamp, confirmed, unlock_time}
verify_payment.sh --tx-hash HASH | --address ADDR --expected-amount "1.5" -> {verified, confirmations, tx_hash, address, address_index, confirmed, amount}
get_tx_proof.sh --tx-hash HASH --address ADDR -> {tx_hash, address, proof}
check_tx_proof.sh --tx-hash HASH --address ADDR --proof PROOF -> {verified, confirmations, amount, tx_hash, address}
list_incoming.sh [--confirmed-only|--all] [--since-block N] -> [{tx_hash, amount, confirmations, address, address_index, timestamp, confirmed, unlock_time}]
[--since-timestamp N] [--limit 100] [--account 0]
list_outgoing.sh [--since-block N] [--since-timestamp N] -> [{tx_hash, amount, fee, timestamp, address, address_index, unlock_time}]
[--limit 100] [--account 0]
list_addresses.sh [--account 0] -> [{index, address, label, balance, unlocked_balance}]
validate_address.sh --address ADDR -> {valid, network, network_match, subaddress, integrated}
sync_status.sh -> {height, daemon_connected, wallet_version}
Concrete output examples (stdout; success is one JSON object per line):
// create_address.sh
{"address":"88bc...","address_index":5,"account":0}
// send_xmr.sh --address ... --amount "1.5"
{"tx_hash":"7663438...","fee":"0.0000869","amount":"1.5"}
// estimate_fee.sh --address ... --amount "1.5"
{"fee":"0.0000869","amount":"1.5","priority":0,"num_destinations":1}
// sweep_all.sh --address DEST --dry-run
{"tx_hash":"","fee":"0.0000869","amount":"8.2"}
// check_balance.sh
{"balance":"10.5","unlocked_balance":"8.2","blocks_to_unlock":42,"time_to_unlock":30240,"account":0}
// get_transfer.sh --tx-hash ...
{"tx_hash":"c36258a...","amount":"1.5","fee":"0.0000435","direction":"in","confirmations":15,"address":"77Vx9cs...","address_index":3,"timestamp":1535918400,"confirmed":true,"unlock_time":0}
// verify_payment.sh --tx-hash ...
{"verified":true,"confirmations":12,"tx_hash":"c36258a...","address":"77Vx9cs...","address_index":3,"confirmed":true,"amount":"1.5"}
// get_tx_proof.sh --tx-hash ... --address ...
{"tx_hash":"c36258a...","address":"77Vx9cs...","proof":"ProofV1..."}
// check_tx_proof.sh --tx-hash ... --address ... --proof ...
{"verified":true,"confirmations":15,"amount":"1.5","tx_hash":"c36258a...","address":"77Vx9cs..."}
// validate_address.sh --address ...
{"valid":true,"network":"mainnet","network_match":true,"subaddress":false,"integrated":false}
// sync_status.sh
{"height":1523651,"daemon_connected":true,"wallet_version":196613}
// list_incoming.sh (array element)
{"tx_hash":"c36258a...","amount":"1.5","confirmations":15,"address":"77Vx9cs...","address_index":3,"timestamp":1535918400,"confirmed":true,"unlock_time":0}
Amounts in outputs are XMR decimal strings (e.g. "1.5"). --dry-run and estimate_fee preview without broadcasting.
Gotchas (verified facts — get these right)
- No
syncRPC. The wallet refreshes from the daemon viarefresh, which can take seconds-to-minutes. Refresh is operation-aware: balance/transfer/verify ops auto-refresh; address-management,validate_address,estimate_fee,get_tx_proof, andsync_statusdo not. Override with--no-refreshon any auto-refresh op (--no-refreshworks in any argument position). blocks_to_unlock/time_to_unlockare nativeget_balancefields. Read them directly — never derive them.check_balancesurfaces both. They are0when no funds are locked, ornullif the wallet omits them — treat0/nullas "nothing locked".- Priority values:
0=default, 1=unimportant, 2=normal, 3=elevated, 4=priority. The default is0(wallet decides). Do not default to1— that literally means "unimportant". Send/sweep/estimate accept--priority 0-4. - Single
/json_rpcendpoint. Every wallet method this skill uses — includingget_heightandget_version— is POSTed to$MONERO_RPC_URL/json_rpc. There is no root-path call anywhere. validate_addressuses real RPC fields. The RPC is called withany_net_type:trueso the realnettypeis returned;network_matchis derived client-side by comparingnettypetoMONERO_NETWORK. There is nochecksum_validfield (the checksum is part ofvalid). This keepsINVALID_ADDRESS(bad format/checksum) distinct fromNETWORK_MISMATCH(valid but wrong network).- Money is integer piconeros (1 XMR = 10^12). Never use floating-point for amounts. All arithmetic is integer piconero; the XMR decimal strings in output come from the scripts' string-based conversion. Amounts must be positive and have <=12 decimals.
- Sends and sweeps are not idempotent and are NOT auto-retried. On timeout/uncertain result, check
get_transfer.sh --tx-hashbefore retrying (see retry-safety workflow). Use--dry-run/estimate_feeto preview. - Credentials use netrc (never
curl -u);.envis parsed, never sourced. The netrc lives at$MONERO_LOCK_DIR/.netrc(mode0600). All user values are passed to the RPC viajq --arg/--argjson— never by string interpolation.
Workflows
Workflows are rendered as checklists. Money/identity paths (send, sweep, verify) are prescriptive: follow the order. Every destructive workflow ends with a verify-after-act step.
Receive a Payment
-
scripts/create_address.sh --label "Payment from Alice"— note the returnedaddress. - Share
addresswith the payer. -
scripts/check_balance.sh(orscripts/list_incoming.sh --since-block <height>). -
scripts/verify_payment.sh --address "ADDR" --expected-amount "1.5"— wait untilverified:true. -
scripts/get_tx_proof.sh --tx-hash "HASH" --address "ADDR"— hand the payer theprooffor their records.
Send a Payment (plan -> validate -> execute)
Irreversible:
send_xmr.shrequires--confirmto broadcast. Use--dry-runto preview without--confirm. Always validate the address and confirm the amount before executing.
- Plan:
scripts/estimate_fee.sh --address "RECIPIENT" --amount "2.5"— previewfee. - Validate:
scripts/validate_address.sh --address "RECIPIENT"— confirmvalid:trueandnetwork_match:true. - Balance:
scripts/check_balance.sh— confirmunlocked_balance >= 2.5. - Preview (optional):
scripts/send_xmr.sh --address "RECIPIENT" --amount "2.5" --dry-run— confirm fee/amount without broadcasting. - Execute:
scripts/send_xmr.sh --address "RECIPIENT" --amount "2.5" --confirm— note thetx_hash. - Verify:
scripts/get_transfer.sh --tx-hash "<tx_hash>"— confirm it was recorded (andconfirmedonce enough blocks pass).
Send a Payment — retry safety (DECISION GATE)
Sends are not idempotent. Never retry blindly on timeout. Run this gate first:
- Attempt:
scripts/send_xmr.sh --address "RECIPIENT" --amount "2.5" --confirm. - If it returns a
tx_hash(success) -> done; do NOT re-send. - If it times out / returns an uncertain result, whether you can use
get_transferdepends on having a hash:- You have a
tx_hash(from the send response, or a prior attempt you're unsure about) -> callscripts/get_transfer.sh --tx-hash "<tx_hash>"and branch on the error code:TX_NOT_FOUND-> the transaction is genuinely absent from the wallet -> safe to retry the send.RPC_UNREACHABLE-> the wallet RPC / daemon could not be reached -> the transaction status is unknown, not absent -> do NOT retry the send; fix connectivity (sync_status.sh, restartmonero-wallet-rpc/monerod) and re-checkget_transferbefore doing anything else.- any success result -> the tx exists -> do NOT re-send.
- You have NO
tx_hash(pure transport failure /RPC_UNREACHABLEwith no payload) -> there is nothing to look up; status is unknown. Do NOT retry the send. Fix connectivity first, then reconcile withscripts/list_outgoing.sh(match by amount/timestamp) to detect any tx that may have been created before re-evaluating.
- You have a
Verify a Payment Proof
- Collect from the payer:
tx_hash,address, andproofstring. -
scripts/check_tx_proof.sh --tx-hash "HASH" --address "ADDR" --proof "PROOF". - Act on
verified:true=> proof is cryptographically valid (readamount,confirmations).false/PROOF_INVALID=> reject and ask the payer to re-issue.
Sweep Funds (plan -> validate -> execute)
Irreversible and high-impact:
sweep_all.shrequires--confirmto broadcast. Use--dry-runto preview without--confirm. A mistaken address can drain the entire wallet.
-
scripts/check_balance.sh— readunlocked_balance(the sweepable amount). -
scripts/validate_address.sh --address "DESTINATION"—valid:true+network_match:true. -
scripts/sweep_all.sh --address "DESTINATION" --dry-run— previewamount+feewithout sending. -
scripts/sweep_all.sh --address "DESTINATION" --confirm— execute; notetx_hash. - (Optional)
scripts/get_transfer.sh --tx-hash "<tx_hash>"— confirm. Same retry-safety caveat as sends applies.
Check for Payments (with filtering)
-
scripts/sync_status.sh— confirmdaemon_connected:trueand thatheightis recent (else data may be stale).list_incomingauto-refreshes unlessMONERO_AUTO_REFRESH=falseor you pass--no-refresh; if auto-refresh is off and you need fresh data, re-enable it (there is no standalone refresh script). -
scripts/list_incoming.sh --since-block <height> --limit 50— recent incoming transfers. - Read
confirmations/confirmedper row (threshold =MONERO_CONFIRMATIONS, default10). - To pin a specific payment:
scripts/verify_payment.sh --tx-hash "HASH"(or--address+--expected-amount).
Error codes
Every error is a JSON object on stderr plus a non-zero exit. It is compact (single-line) — but always parse it with jq, never line-by-line. The object has exactly error, code, and message (the suggestion key is reserved in the emitter but not currently populated; use the table below for recovery text):
{
"error": true,
"code": "TX_NOT_FOUND",
"message": "no transfer found for txid 7663438…"
}
Load references/error-runbook.md when a script returns an error code and you need detailed, per-code recovery steps.
| Code | Meaning | Retryable | One-line recovery |
|---|---|---|---|
CONFIG_MISSING | Required env var / arg not set | No | Run ./setup.sh; supply the missing --flag. |
CONFIG_INVALID | .env has bad syntax/metachars | No | Inspect .env; fix malformed lines; do not source it. |
CONFIRM_REQUIRED | --confirm not provided for destructive operation | No | Add --confirm to broadcast, or --dry-run to preview without broadcasting. |
RPC_UNREACHABLE | Cannot reach monero-wallet-rpc | Yes | Start/check monero-wallet-rpc; re-check. (Do NOT treat a send timeout with this code as "tx absent".) |
WALLET_NOT_LOADED | Wallet name != loaded wallet | No | open_wallet the right wallet; check MONERO_WALLET_NAME. |
WALLET_LOCKED | Wallet file locked elsewhere | No | Find/kill the holder (lsof | grep wallet.keys) or wait. |
DAEMON_DISCONNECTED | Wallet RPC can't reach daemon | Yes | Check/restart monerod. |
INSUFFICIENT_BALANCE | Not enough unlocked funds | No | check_balance.sh; wait for unlocks or reduce amount. |
AMOUNT_INVALID | Amount <=0 / >12 decimals / >balance | No | Correct the amount string. |
INVALID_ADDRESS | Bad format/checksum | No | Re-check the address; do not use. |
NETWORK_MISMATCH | Valid address, wrong network | No | Use an address for MONERO_NETWORK (mainnet/stagenet). |
INVALID_INPUT | Bad flag value (e.g. priority 0-4, tx-hash, label) | No | Correct the argument value. |
SYNC_FAILED / REFRESH_FAILED | Wallet sync/refresh failed | Yes | sync_status.sh; may need to restart wallet RPC. |
TX_RELAY_FAILED | Tx created but not broadcast | No | get_transfer.sh --tx-hash; may need manual relay. |
RATE_LIMITED | Lock acquisition timed out / daemon busy | Yes | Wait; reduce call frequency. |
TX_NOT_FOUND | Hash unknown to this wallet | No | Re-check the hash; for sends this means "safe to retry" (see retry-safety). |
PROOF_INVALID | Payment proof verification failed | No | Reject; ask payer to re-issue proof. |
Transient codes (RPC_UNREACHABLE, DAEMON_DISCONNECTED, SYNC_FAILED, REFRESH_FAILED, RATE_LIMITED) surface immediately — they are not auto-retried by the scripts. The retry helper (lib/retry.sh) exists and is unit-tested, but is not currently applied to any script RPC call (all scripts call rpc_call directly). send_xmr/sweep_all are intentionally never retried (non-idempotent). get_transfer and check_tx_proof are intentionally direct so they don't mask the retry-safety probe / proof classification. If a read-only op returns a transient code, the agent should retry it itself (never retry sends/sweeps — drive those via the decision gate above).
Refresh & concurrency
- Refresh: controlled by
MONERO_AUTO_REFRESH(defaulttrue) andMONERO_REFRESH_MIN_INTERVAL(default30s; a refresh is skipped if one happened within this window). Auto-refreshing ops accept--no-refreshto skip. The last-refresh timestamp lives in$MONERO_LOCK_DIR/.last_refresh. - Concurrency: every script takes an exclusive
flockon$MONERO_LOCK_DIR/agenta-monero.lock(timeoutMONERO_LOCK_TIMEOUT, default60s) before any RPC; lock contention surfaces asRATE_LIMITED. The lock is released on exit, coordinating multiple local agent processes against the wallet RPC's own serialization.
Load references/env-reference.md when you need the full environment-variable table (connection, network, refresh, retry, concurrency, TLS knobs) or the complete refresh-strategy / retry-backoff details.
Top skills in this category
Stock Analysis
@udiedrichsenAnalyze stocks and cryptocurrencies using Yahoo Finance data. Supports portfolio management, watchlists with alerts, dividend analysis, 8-dimension stock scoring, viral trend detection (Hot Scanner), and rumor/early signal detection. Use for stock analysis, portfolio tracking, earnings reactions, crypto monitoring, trending stocks, or finding rumors before they hit mainstream.
Stock Market Pro
@kys42Yahoo Finance (yfinance) powered stock analysis skill: quotes, fundamentals, ASCII trends, high-resolution charts (RSI/MACD/BB/VWAP/ATR), plus optional web a...
A股量化 AkShare
@mbpzA股量化数据分析工具,基于AkShare库获取A股行情、财务数据、板块信息等。用于回答关于A股股票查询、行情数据、财务分析、选股等问题。
Stock Watcher
@robin797860Manage and monitor a personal stock watchlist with support for adding, removing, listing stocks, and summarizing their recent performance using data from 10jqka.com.cn. Use when the user wants to track specific stocks, get performance summaries, or manage their watchlist.
Intelligent Stocks Screener
@financial-ai-analyst基于东方财富数据库,支持通过自然语言输入筛选A港美股、基金、债券等多种资产,支持多元指标筛选,含技术面、消息面、基本面及市场情绪等,可用于全球资产速筛、跨市场监控、投资组合构建、策略回测等场景。返回结果包含数据说明及 csv 文件。Natural language screener for investment...