Skip to content

Add token balance to get-address JSON output#7

Merged
juntao merged 4 commits intomainfrom
get-address-json-balance
Jan 31, 2026
Merged

Add token balance to get-address JSON output#7
juntao merged 4 commits intomainfrom
get-address-json-balance

Conversation

@juntao
Copy link
Member

@juntao juntao commented Jan 31, 2026

Summary

  • Update get-address tool to return JSON with both address and token balance
  • Query token balance from blockchain when network is configured
  • Update all documentation

Changes

get-address/Cargo.toml:

  • Add alloy, tokio, serde, serde_json dependencies

get-address/src/main.rs:

  • Make async with tokio runtime
  • Query token balance from RPC endpoint
  • Output JSON instead of plain text

Documentation:

  • get-address/README.md - New output format
  • skill/skill.md - Updated get-address section
  • README.md - Updated description

Example Output

With network configured:

{
  "address": "0x742d35Cc6634C0532925a3b844Bc9e7595f12345",
  "balance": "1000000",
  "token": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
  "token_symbol": "USDC",
  "network": "base-sepolia"
}

Without network configured:

{
  "address": "0x742d35Cc6634C0532925a3b844Bc9e7595f12345"
}

Test plan

  • Build succeeds: cargo build -p get-address
  • Run with configured network to verify balance query
  • Run without network config to verify address-only output

🤖 Generated with Claude Code

Update get-address tool to return JSON with both address and token balance:

- Add alloy, tokio, serde dependencies for blockchain queries
- Query token balance from configured RPC endpoint
- Output JSON with address, balance, token, token_symbol, network
- Balance is included only if network and token are configured
- Update get-address/README.md with new output format
- Update skill/skill.md with new output format
- Update main README.md description

Example output:
```json
{
  "address": "0x742d35Cc...",
  "balance": "1000000",
  "token": "0x036CbD53...",
  "token_symbol": "USDC",
  "network": "base-sepolia"
}
```

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the get-address CLI to emit JSON output including the wallet address plus (optionally) the configured token balance, and refreshes documentation to match the new output format.

Changes:

  • Converted get-address to an async Tokio-based CLI that can query an ERC-20 balanceOf via RPC.
  • Changed get-address output from plain text to pretty-printed JSON with optional balance/token/network fields.
  • Updated user-facing documentation to describe the JSON output and new --config option.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
get-address/src/main.rs Implements async JSON output and optional ERC-20 balance query via RPC.
get-address/Cargo.toml Adds Tokio/Alloy/Serde dependencies needed for async RPC + JSON serialization.
get-address/README.md Documents new JSON output shape, fields, and (updated) exit code expectations.
skill/skill.md Updates the skill docs to describe JSON output for get-address.
README.md Updates top-level docs to mention token balance querying and JSON output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +57 to +61
If no network is configured, the output only includes the address:

```json
{
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f12345"
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section states that when no network is configured the output only includes the address, but the current implementation can still include a network field if network.name is set while network.rpc_url/payment.default_token are unset. Either tighten the code to omit network in that case, or adjust this doc/example to match actual behavior.

Suggested change
If no network is configured, the output only includes the address:
```json
{
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f12345"
If no RPC URL and no default token are configured, the output always includes the address and may also include the network name (if `network.name` is set):
```json
{
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f12345",
"network": "base-sepolia"

Copilot uses AI. Check for mistakes.
Comment on lines 52 to 60
match run(args).await {
Ok(info) => {
println!("{}", serde_json::to_string_pretty(&info).unwrap());
ExitCode::SUCCESS
}
Err(e) => {
eprintln!("Error: {}", e);
ExitCode::from(e.exit_code() as u8)
ExitCode::from(1)
}
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the CLI’s exit-code behavior from the project’s standard e.exit_code() mapping (e.g., WalletNotFound => 12, MissingConfig => 10). Other binaries still use that convention (e.g., create-wallet/src/main.rs:34-42, x402-config/src/main.rs:46-55). Consider returning/propagating x402_common::Error (or a wrapper enum) from run so you can keep ExitCode::from(e.exit_code() as u8) for config/wallet errors while still mapping RPC/balance failures to code 1.

Copilot uses AI. Check for mistakes.

async fn run(args: Args) -> Result<WalletInfo, Box<dyn std::error::Error>> {
// Load config
let config = Config::load_from(args.config.as_deref()).unwrap_or_default();
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Config::load_from(...).unwrap_or_default() silently ignores TOML/IO errors when a config file exists (including when the user explicitly passes --config). This can mask misconfiguration and lead to surprising output. Suggest: if --config is provided, fail on load errors; otherwise, default only when the config file is missing (matching Config::load_from semantics).

Suggested change
let config = Config::load_from(args.config.as_deref()).unwrap_or_default();
let config = match Config::load_from(args.config.as_deref()) {
Ok(cfg) => cfg,
Err(e) => {
if args.config.is_some() {
// If the user explicitly provided a config file, fail on load errors
return Err(Box::new(e));
}
// If no config was provided, fall back to defaults on load errors
Config::default()
}
};

Copilot uses AI. Check for mistakes.
| 0 | Success |
| 12 | Wallet not found |
| 1 | Other error |
| 1 | Error (wallet not found, network error, etc.) |
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exit-code table documents only 0 and 1, but the shared error type supports specific exit codes (MissingConfig=10, Config=11, WalletNotFound=12, etc. in x402-common/src/error.rs). If get-address keeps those codes (recommended for consistency with other tools), please document them here; if not, this README should explicitly call out that get-address intentionally collapses all failures to exit code 1.

Suggested change
| 1 | Error (wallet not found, network error, etc.) |
| 10 | Missing configuration (e.g., no config file found) |
| 11 | Configuration error (e.g., invalid or unreadable config) |
| 12 | Wallet not found |
| 1 | Other error (network error, unexpected failure, etc.) |

Copilot uses AI. Check for mistakes.
juntao and others added 3 commits February 1, 2026 06:39
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@juntao juntao merged commit d89e879 into main Jan 31, 2026
10 of 11 checks passed
@juntao juntao deleted the get-address-json-balance branch January 31, 2026 22:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant