From 60ec340e9283f6d4719afdcf527c1e130c67766c Mon Sep 17 00:00:00 2001 From: aitbc Date: Wed, 20 May 2026 10:38:53 +0200 Subject: [PATCH] feat: add wallet fund command using blockchain faucet - Add 'wallet fund' CLI command to fund wallets via blockchain faucet - Uses POST /faucet endpoint to request test tokens - Supports custom amount and chain_id parameters - Auto-creates account if it doesn't exist - Rate-limited to 10 requests per hour per IP --- cli/aitbc_cli/commands/wallet.py | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/cli/aitbc_cli/commands/wallet.py b/cli/aitbc_cli/commands/wallet.py index 5f45d732..d6f9cf34 100644 --- a/cli/aitbc_cli/commands/wallet.py +++ b/cli/aitbc_cli/commands/wallet.py @@ -1488,3 +1488,50 @@ def rewards(ctx): }, ctx.obj.get("output_format", "table"), ) + + +@wallet.command() +@click.argument("address") +@click.option("--amount", default=1000000, help="Amount to request from faucet (default: 1000000)") +@click.option("--chain-id", help="Chain ID (defaults to node's chain)") +@click.pass_context +def fund(ctx, address: str, amount: int, chain_id: str): + """Fund wallet using blockchain faucet""" + import httpx + from ..utils.chain_id import get_chain_id + from ..config import get_config + + config = get_config() + rpc_url = config.blockchain_rpc_url if hasattr(config, 'blockchain_rpc_url') else 'http://localhost:8006' + + # Get chain_id + if not chain_id: + chain_id = get_chain_id(rpc_url) + + # Normalize address + address = address.lower().strip() + if not address.startswith("0x"): + address = "0x" + address + + # Call faucet endpoint + faucet_url = f"{rpc_url}/faucet" + faucet_data = { + "address": address, + "amount": amount, + "chain_id": chain_id + } + + try: + response = httpx.post(faucet_url, json=faucet_data, timeout=10) + response.raise_for_status() + result = response.json() + + if result.get("success"): + success(f"Successfully funded wallet {address} with {amount} units") + output(result, ctx.obj.get("output_format", "table")) + else: + error(f"Failed to fund wallet: {result.get('message', 'Unknown error')}") + except httpx.HTTPError as e: + error(f"HTTP error calling faucet: {e}") + except Exception as e: + error(f"Error funding wallet: {e}")