@@ -9,7 +9,7 @@ Subcommands:
99 status Show wallet address, network, and funding status
1010 create Generate a new wallet and save it locally
1111 fund Request test USDC from the Run402 faucet (Base Sepolia)
12- balance Check billing balance for this wallet
12+ balance Show on-chain USDC (mainnet + testnet) and Run402 billing balance
1313 export Print the wallet address (useful for scripting)
1414
1515Notes:
@@ -24,11 +24,15 @@ Examples:
2424 run402 wallet export
2525` ;
2626
27+ const USDC_ABI = [ { name : "balanceOf" , type : "function" , stateMutability : "view" , inputs : [ { name : "account" , type : "address" } ] , outputs : [ { name : "" , type : "uint256" } ] } ] ;
28+ const USDC_MAINNET = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" ;
29+ const USDC_SEPOLIA = "0x036CbD53842c5426634e7929541eC2318f3dCF7e" ;
30+
2731async function loadDeps ( ) {
2832 const { generatePrivateKey, privateKeyToAccount } = await import ( "viem/accounts" ) ;
2933 const { createPublicClient, http } = await import ( "viem" ) ;
30- const { baseSepolia } = await import ( "viem/chains" ) ;
31- return { generatePrivateKey, privateKeyToAccount, createPublicClient, http, baseSepolia } ;
34+ const { base , baseSepolia } = await import ( "viem/chains" ) ;
35+ return { generatePrivateKey, privateKeyToAccount, createPublicClient, http, base , baseSepolia } ;
3236}
3337
3438async function status ( ) {
@@ -37,7 +41,7 @@ async function status() {
3741 console . log ( JSON . stringify ( { status : "no_wallet" , message : "No wallet found. Run: run402 wallet create" } ) ) ;
3842 return ;
3943 }
40- console . log ( JSON . stringify ( { status : "ok" , address : w . address , created : w . created , funded : w . funded || false } ) ) ;
44+ console . log ( JSON . stringify ( { status : "ok" , address : w . address , created : w . created , funded : w . funded || false , path : WALLET_FILE } ) ) ;
4145}
4246
4347async function create ( ) {
@@ -66,13 +70,35 @@ async function fund() {
6670 }
6771}
6872
73+ async function readUsdcBalance ( client , usdc , address ) {
74+ const raw = await client . readContract ( { address : usdc , abi : USDC_ABI , functionName : "balanceOf" , args : [ address ] } ) ;
75+ return Number ( raw ) / 1e6 ;
76+ }
77+
6978async function balance ( ) {
7079 const w = readWallet ( ) ;
7180 if ( ! w ) { console . log ( JSON . stringify ( { status : "error" , message : "No wallet. Run: run402 wallet create" } ) ) ; process . exit ( 1 ) ; }
72- const res = await fetch ( `${ API } /v1/billing/accounts/${ w . address . toLowerCase ( ) } ` ) ;
73- const data = await res . json ( ) ;
74- if ( ! res . ok ) { console . error ( JSON . stringify ( { status : "error" , http : res . status , ...data } ) ) ; process . exit ( 1 ) ; }
75- console . log ( JSON . stringify ( data , null , 2 ) ) ;
81+
82+ const { createPublicClient, http, base, baseSepolia } = await loadDeps ( ) ;
83+ const mainnetClient = createPublicClient ( { chain : base , transport : http ( ) } ) ;
84+ const sepoliaClient = createPublicClient ( { chain : baseSepolia , transport : http ( ) } ) ;
85+
86+ const [ mainnetUsdc , sepoliaUsdc , billingRes ] = await Promise . all ( [
87+ readUsdcBalance ( mainnetClient , USDC_MAINNET , w . address ) . catch ( ( ) => null ) ,
88+ readUsdcBalance ( sepoliaClient , USDC_SEPOLIA , w . address ) . catch ( ( ) => null ) ,
89+ fetch ( `${ API } /v1/billing/accounts/${ w . address . toLowerCase ( ) } ` ) ,
90+ ] ) ;
91+
92+ const billing = billingRes . ok ? await billingRes . json ( ) : null ;
93+
94+ console . log ( JSON . stringify ( {
95+ address : w . address ,
96+ onchain : {
97+ "base-mainnet" : mainnetUsdc !== null ? `${ mainnetUsdc } USDC` : "unavailable" ,
98+ "base-sepolia" : sepoliaUsdc !== null ? `${ sepoliaUsdc } USDC` : "unavailable" ,
99+ } ,
100+ run402 : billing || "no billing account" ,
101+ } , null , 2 ) ) ;
76102}
77103
78104async function exportAddr ( ) {
0 commit comments