// Public standalone Node 24+ example. npm install @x402/core@2.27.0 @x402/evm@2.27.0 viem@2.57.0 // Default: free preview only. Buy: --buy --approve-one-purchase with the two file variables below. import { createHash, randomUUID } from 'node:crypto'; import { readFileSync, existsSync, openSync, writeFileSync, fsyncSync, closeSync, unlinkSync } from 'node:fs'; import { dirname } from 'node:path'; import { privateKeyToAccount } from 'viem/accounts'; import { x402Client } from '@x402/core/client'; import { ExactEvmScheme } from '@x402/evm/exact/client'; import { decodePaymentRequiredHeader, encodePaymentSignatureHeader, decodePaymentResponseHeader } from '@x402/core/http'; const origin='https://datoka-agent.bhazarstudio.workers.dev'; const payTo='0x4a7a972f84e2a64b3b9b64ac1383df5c413c0e59'; const asset='0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'; const send=(input,payment)=>fetch(origin+'/v1/operations/issue_agent_receipt',{method:'POST',redirect:'error',signal:AbortSignal.timeout(40000),headers:{'content-type':'application/json',...(payment?{'PAYMENT-SIGNATURE':encodePaymentSignatureHeader(payment)}:{})},body:JSON.stringify(input)}); const hash=value=>({algorithm:'sha256',digest:createHash('sha256').update(value).digest('hex')}); const at=new Date().toISOString(); const input={event:{version:'datoka.agent.execution.v1',agentId:'example-agent',runId:'run-'+randomUUID(),stepId:'step-1',tool:'local.add',outcome:'success',startedAt:at,completedAt:at,inputHash:hash('{"a":2,"b":3}'),outputHash:hash('{"sum":5}')},idempotencyKey:'purchase-'+randomUUID()}; const safeTerms=t=>t.scheme==='exact'&&t.network==='eip155:8453'&&t.asset.toLowerCase()===asset&&t.payTo.toLowerCase()===payTo&&t.amount==='2000'&&t.maxTimeoutSeconds===60&&t.extra?.name==='USD Coin'&&t.extra?.version==='2'; function save(path,value){const fd=openSync(path,'wx',0o600);try{writeFileSync(fd,JSON.stringify(value));fsyncSync(fd);}finally{closeSync(fd);}const dir=openSync(dirname(path),'r');try{fsyncSync(dir);}finally{closeSync(dir);}} async function main(){ if(!process.argv.includes('--buy')){const response=await send(input);if(response.status!==402)throw Error();const offer=decodePaymentRequiredHeader(response.headers.get('payment-required'));if(!offer.accepts.some(safeTerms))throw Error();console.log(JSON.stringify({priceUSDC:'0.002',network:'Base',purchaseSubmitted:false}));return;} if(!process.argv.includes('--approve-one-purchase'))throw Error(); const path=process.env.DATOKA_PURCHASE_STATE;if(!path)throw Error(); const lock=openSync(path+'.lock','wx',0o600);closeSync(lock); try{ let saved; if(existsSync(path))saved=JSON.parse(readFileSync(path,'utf8')); else{ if(existsSync(path+'.receipt.json'))throw Error(); const wallet=JSON.parse(readFileSync(process.env.DATOKA_TEST_PRIVATE_KEY_FILE,'utf8')); const signer=privateKeyToAccount(wallet.privateKey);if(signer.address.toLowerCase()===payTo)throw Error(); const response=await send(input);if(response.status!==402)throw Error(); const offer=decodePaymentRequiredHeader(response.headers.get('payment-required')); const terms=offer.accepts.find(safeTerms);if(!terms||offer.resource.url!==origin+'/v1/operations/issue_agent_receipt')throw Error(); const client=new x402Client().register('eip155:8453',new ExactEvmScheme(signer)); saved={origin,input,payment:await client.createPaymentPayload({...offer,accepts:[terms]})};save(path,saved); } if(saved.origin!==origin||!safeTerms(saved.payment.accepted))throw Error(); const response=await send(saved.input,saved.payment);if(!response.ok)throw Error(); const result=await response.json(),payment=decodePaymentResponseHeader(response.headers.get('payment-response')); if(!payment.success||payment.network!=='eip155:8453'||payment.payer?.toLowerCase()!==saved.payment.payload.authorization.from.toLowerCase()||!/^0x[0-9a-f]{64}$/i.test(payment.transaction))throw Error(); if(!existsSync(path+'.receipt.json'))save(path+'.receipt.json',{result,payment}); // Verify declaration binding using the free service verifier; keep the receipt for independent verification. if(JSON.stringify(result.event)!==JSON.stringify(saved.input.event))throw Error(); const verification=await fetch(origin+'/v1/operations/verify_agent_receipt',{method:'POST',redirect:'error',signal:AbortSignal.timeout(40000),headers:{'content-type':'application/json'},body:JSON.stringify(result)}); if(!verification.ok||(await verification.json()).valid!==true)throw Error(); const replay=await send(saved.input,saved.payment);if(!replay.ok||JSON.stringify(await replay.json())!==JSON.stringify(result))throw Error(); const again=decodePaymentResponseHeader(replay.headers.get('payment-response'));if(again.transaction!==payment.transaction)throw Error(); console.log(JSON.stringify({receiptId:result.receipt.body.id,transaction:payment.transaction,priceUSDC:'0.002',sameReceiptOnRetry:true})); }finally{unlinkSync(path+'.lock');} } main().catch(()=>{console.error('Stopped. Preserve the original state and receipt files. Do not create a replacement authorization after an error.');process.exitCode=1;});