@@ -5,6 +5,7 @@ import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
55import { AzethKit , type AzethKitConfig } from '@azeth/sdk' ;
66import { isValidChainName , TOKENS , type Guardrails , type SupportedChainName } from '@azeth/common' ;
77import { printHeader , printField , printSuccess , printError } from '../utils/display.js' ;
8+ import { saveKey } from '../utils/key-persistence.js' ;
89
910const DEFAULT_SERVER_URL = 'https://api.azeth.ai' ;
1011
@@ -62,6 +63,7 @@ export const quickstartCommand = new Command('quickstart')
6263 } else {
6364 privateKey = generatePrivateKey ( ) ;
6465 generated = true ;
66+ saveKey ( privateKey ) ;
6567 }
6668
6769 const account = privateKeyToAccount ( privateKey ) ;
@@ -83,13 +85,16 @@ export const quickstartCommand = new Command('quickstart')
8385 }
8486
8587 // Step 4: Build AzethKitConfig directly (no env vars required)
88+ const serverUrl = process . env [ 'AZETH_SERVER_URL' ] ?? DEFAULT_SERVER_URL ;
8689 const config : AzethKitConfig = {
8790 privateKey,
8891 chain,
89- serverUrl : process . env [ 'AZETH_SERVER_URL' ] ?? DEFAULT_SERVER_URL ,
92+ serverUrl,
9093 } ;
9194
92- const spinner = ora ( `Deploying smart account on ${ chain } (gas sponsored by Azeth)...` ) . start ( ) ;
95+ // SDK auto-tries gasless relay (createAccountWithSignature) before falling back
96+ // to direct on-chain tx. No need to sponsor gas separately.
97+ const spinner = ora ( `Deploying smart account on ${ chain } ...` ) . start ( ) ;
9398 kit = await AzethKit . create ( config ) ;
9499
95100 // Step 5: Deploy smart account + register on ERC-8004
@@ -127,7 +132,6 @@ export const quickstartCommand = new Command('quickstart')
127132 spinner . stop ( ) ;
128133
129134 // Step 6: Print results
130- const serverUrl = config . serverUrl ?? DEFAULT_SERVER_URL ;
131135 const tokenIdStr = result . tokenId . toString ( ) ;
132136 const badgeUrl = `${ serverUrl } /badge/${ tokenIdStr } ` ;
133137 const profileUrl = `https://azeth.ai/agent/${ result . account } ` ;
@@ -142,38 +146,10 @@ export const quickstartCommand = new Command('quickstart')
142146 printField ( 'Profile' , profileUrl ) ;
143147 printField ( 'Badge' , badgeUrl ) ;
144148 console . log ( ) ;
145- printSuccess ( 'Gas sponsored by Azeth testnet — no ETH required.' ) ;
149+ printSuccess ( 'Account deployed — zero gas required from you .' ) ;
146150 console . log ( ) ;
147151
148- // Step 6b: Fund the smart account with testnet USDC via faucet (testnet only)
149- if ( isTestnet ) {
150- try {
151- const faucetSpinner = ora ( 'Funding account with testnet USDC...' ) . start ( ) ;
152- const faucetRes = await fetch ( `${ serverUrl } /api/v1/faucet` , {
153- method : 'POST' ,
154- headers : { 'Content-Type' : 'application/json' } ,
155- body : JSON . stringify ( { address : result . account } ) ,
156- signal : AbortSignal . timeout ( 60_000 ) ,
157- } ) ;
158- if ( faucetRes . ok ) {
159- const faucetBody = await faucetRes . json ( ) as { data ?: { amount ?: string ; txHash ?: string } } ;
160- faucetSpinner . stop ( ) ;
161- printSuccess ( `Funded with ${ faucetBody . data ?. amount ?? '1.00 USDC' } for demo calls.` ) ;
162- console . log ( ) ;
163- } else {
164- faucetSpinner . stop ( ) ;
165- // Non-fatal: show manual funding instructions
166- console . log ( chalk . gray ( ' Faucet unavailable — send testnet USDC to your smart account to try paid services.' ) ) ;
167- console . log ( ) ;
168- }
169- } catch {
170- // Non-fatal — faucet unreachable
171- console . log ( chalk . gray ( ' Could not reach faucet — send testnet USDC to your smart account to try paid services.' ) ) ;
172- console . log ( ) ;
173- }
174- }
175-
176- // Step 6c: Demo the live ecosystem — call the free catalog
152+ // Step 6b: Demo the live ecosystem — call the free catalog
177153 const catalogUrl = `${ serverUrl } /api/v1/pricing` ;
178154 try {
179155 const catalogSpinner = ora ( 'Discovering live services...' ) . start ( ) ;
@@ -190,9 +166,6 @@ export const quickstartCommand = new Command('quickstart')
190166 console . log ( ` ${ chalk . cyan ( item . name ?? '?' ) } ${ chalk . gray ( item . pricing ?? '' ) } ${ chalk . white ( item . description ?? '' ) } ` ) ;
191167 }
192168 console . log ( ) ;
193- console . log ( chalk . gray ( ' Try a paid call now' + ( isTestnet ? ' (your account is funded)' : '' ) + ':' ) ) ;
194- console . log ( chalk . cyan ( ` azeth call ${ serverUrl } /api/v1/pricing/ethereum` ) ) ;
195- console . log ( ) ;
196169 }
197170 } else {
198171 catalogSpinner . stop ( ) ;
@@ -201,6 +174,26 @@ export const quickstartCommand = new Command('quickstart')
201174 // Non-fatal — catalog fetch failed, just skip the demo
202175 }
203176
177+ // Step 6d: Make a live paid API call to demonstrate x402 (testnet only)
178+ if ( isTestnet ) {
179+ try {
180+ const demoSpinner = ora ( 'Making your first paid API call...' ) . start ( ) ;
181+ const demoRes = await kit . fetch402 ( `${ serverUrl } /api/v1/pricing/ethereum` ) ;
182+ demoSpinner . stop ( ) ;
183+ if ( demoRes . response . ok ) {
184+ const body = await demoRes . response . json ( ) as { data ?: { symbol ?: string ; price ?: string } } ;
185+ const price = body ?. data ?. price ;
186+ const costStr = demoRes . amount !== undefined
187+ ? `$${ ( Number ( demoRes . amount ) / 1_000_000 ) . toFixed ( 2 ) } `
188+ : '$0.01' ;
189+ printSuccess ( `First paid call complete! ETH = ${ price ?? 'N/A' } (cost: ${ costStr } )` ) ;
190+ console . log ( ) ;
191+ }
192+ } catch {
193+ // Non-fatal — the demo call is a nice-to-have
194+ }
195+ }
196+
204197 console . log ( chalk . gray ( ' Next steps:' ) ) ;
205198 console . log ( chalk . gray ( ' azeth status — Check your account' ) ) ;
206199 console . log ( chalk . gray ( ' azeth find "price feed" — Discover services' ) ) ;
@@ -209,11 +202,8 @@ export const quickstartCommand = new Command('quickstart')
209202
210203 // Step 7: Print key persistence instructions (only for generated keys)
211204 if ( generated ) {
212- console . log ( chalk . bold ( ' To continue using this account:' ) ) ;
213- console . log ( chalk . cyan ( ` export AZETH_PRIVATE_KEY=${ privateKey } ` ) ) ;
214- console . log ( ) ;
215- console . log ( chalk . gray ( ' Or add to .env:' ) ) ;
216- console . log ( chalk . gray ( ` echo 'AZETH_PRIVATE_KEY=${ privateKey } ' >> .env` ) ) ;
205+ console . log ( chalk . gray ( ' Key saved to ~/.azeth/key' ) ) ;
206+ console . log ( chalk . gray ( ' To use in other terminals: export AZETH_PRIVATE_KEY=$(cat ~/.azeth/key)' ) ) ;
217207 console . log ( ) ;
218208 }
219209 } catch ( err ) {
0 commit comments