1+ import AcpClient , {
2+ AcpContractClientV2 ,
3+ AcpJobPhases ,
4+ AcpJob ,
5+ AcpMemo ,
6+ AcpAgentSort ,
7+ AcpGraduationStatus ,
8+ AcpOnlineStatus ,
9+ baseSepoliaAcpX402ConfigV2 ,
10+ AcpMemoState ,
11+ } from "../../../src/index" ;
12+ import {
13+ BUYER_AGENT_WALLET_ADDRESS ,
14+ BUYER_ENTITY_ID ,
15+ WHITELISTED_WALLET_PRIVATE_KEY ,
16+ } from "./env" ;
17+ import { arbitrumSepolia , baseSepolia , polygonAmoy } from "@account-kit/infra" ;
18+ import * as readline from "readline" ;
19+ import { SupportedChain } from "./jobTypes" ;
20+
21+ const SUPPORTED_CHAINS : Record <
22+ SupportedChain ,
23+ { chain : typeof baseSepolia | typeof arbitrumSepolia | typeof polygonAmoy }
24+ > = {
25+ "base-sepolia" : { chain : baseSepolia } ,
26+ "arbitrum-sepolia" : { chain : arbitrumSepolia } ,
27+ "polygon-amoy" : { chain : polygonAmoy } ,
28+ } ;
29+
30+ const config = {
31+ ...baseSepoliaAcpX402ConfigV2 ,
32+ chains : Object . entries ( SUPPORTED_CHAINS )
33+ . filter ( ( [ key ] ) => key !== "base-sepolia" )
34+ . map ( ( [ , { chain } ] ) => chain ) ,
35+ } ;
36+
37+ async function promptUser ( question : string ) : Promise < string > {
38+ const rl = readline . createInterface ( {
39+ input : process . stdin ,
40+ output : process . stdout ,
41+ } ) ;
42+
43+ return new Promise ( ( resolve ) => {
44+ rl . question ( question , ( answer ) => {
45+ rl . close ( ) ;
46+ resolve ( answer . trim ( ) ) ;
47+ } ) ;
48+ } ) ;
49+ }
50+
51+ async function buyer ( ) {
52+ console . log ( "=== Munchy the Swapmaster - Buyer ===\n" ) ;
53+ console . log ( "Supported chains:" ) ;
54+ console . log ( " 1. base-sepolia" ) ;
55+ console . log ( " 2. arbitrum-sepolia" ) ;
56+ console . log ( " 3. polygon-amoy\n" ) ;
57+
58+ const sourceChainInput = await promptUser (
59+ "Enter source chain (1-3 or name): " ,
60+ ) ;
61+ const targetChainInput = await promptUser (
62+ "Enter target chain (1-3 or name): " ,
63+ ) ;
64+ const amountInput = await promptUser ( "Enter amount to transfer: " ) ;
65+
66+ const chainMap : Record < string , SupportedChain > = {
67+ "1" : "base-sepolia" ,
68+ "2" : "arbitrum-sepolia" ,
69+ "3" : "polygon-amoy" ,
70+ "base-sepolia" : "base-sepolia" ,
71+ "arbitrum-sepolia" : "arbitrum-sepolia" ,
72+ "polygon-amoy" : "polygon-amoy" ,
73+ } ;
74+
75+ const sourceChain = chainMap [ sourceChainInput . toLowerCase ( ) ] ;
76+ const targetChain = chainMap [ targetChainInput . toLowerCase ( ) ] ;
77+ const amount = amountInput ;
78+
79+ if ( ! sourceChain || ! SUPPORTED_CHAINS [ sourceChain ] ) {
80+ console . error ( "Invalid source chain:" , sourceChainInput ) ;
81+ process . exit ( 1 ) ;
82+ }
83+
84+ if ( ! targetChain || ! SUPPORTED_CHAINS [ targetChain ] ) {
85+ console . error ( "Invalid target chain:" , targetChainInput ) ;
86+ process . exit ( 1 ) ;
87+ }
88+
89+ // if (isNaN(amount) || amount <= 0) {
90+ // console.error("Invalid amount:", amountInput);
91+ // process.exit(1);
92+ // }
93+
94+ console . log ( "\n=== Transfer Details ===" ) ;
95+ console . log ( "Source Chain:" , sourceChain ) ;
96+ console . log ( "Target Chain:" , targetChain ) ;
97+ console . log ( "Amount:" , amount ) ;
98+ console . log ( "Symbol: TEST\n" ) ;
99+
100+ const acpClient = new AcpClient ( {
101+ acpContractClient : await AcpContractClientV2 . build (
102+ WHITELISTED_WALLET_PRIVATE_KEY ,
103+ BUYER_ENTITY_ID ,
104+ BUYER_AGENT_WALLET_ADDRESS ,
105+ config ,
106+ ) ,
107+ onNewTask : async ( job : AcpJob , memoToSign ?: AcpMemo ) => {
108+ if (
109+ job . phase === AcpJobPhases . NEGOTIATION &&
110+ ( memoToSign ?. nextPhase === AcpJobPhases . TRANSACTION ||
111+ memoToSign ?. nextPhase === AcpJobPhases . COMPLETED )
112+ ) {
113+ console . log ( `Paying for job ${ job . id } ` ) ;
114+ await job . payAndAcceptRequirement ( ) ;
115+ console . log ( `Job ${ job . id } paid` ) ;
116+ } else if (
117+ job . phase === AcpJobPhases . TRANSACTION &&
118+ memoToSign ?. nextPhase === AcpJobPhases . REJECTED
119+ ) {
120+ console . log (
121+ `Signing job ${ job . id } rejection memo, rejection reason: ${ memoToSign ?. content } ` ,
122+ ) ;
123+ await memoToSign ?. sign ( true , "Accepts job rejection" ) ;
124+ console . log ( `Job ${ job . id } rejection memo signed` ) ;
125+ } else if ( job . phase === AcpJobPhases . COMPLETED ) {
126+ console . log (
127+ `Job ${ job . id } completed, received deliverable:` ,
128+ job . deliverable ,
129+ ) ;
130+ } else if ( job . phase === AcpJobPhases . REJECTED ) {
131+ console . log ( `Job ${ job . id } rejected by seller` ) ;
132+ } else if ( job . phase === AcpJobPhases . TRANSACTION ) {
133+ await memoToSign ?. sign ( true , "Accepts transaction memo" ) ;
134+ }
135+ } ,
136+ } ) ;
137+
138+ console . log ( "Browsing for Munchy the Swapmaster agents..." ) ;
139+ const relevantAgents = await acpClient . browseAgents ( "Munchy the Swapmaster" , {
140+ sortBy : [ AcpAgentSort . SUCCESSFUL_JOB_COUNT ] ,
141+ topK : 5 ,
142+ graduationStatus : AcpGraduationStatus . ALL ,
143+ onlineStatus : AcpOnlineStatus . ALL ,
144+ } ) ;
145+
146+ if ( ! relevantAgents || relevantAgents . length === 0 ) {
147+ console . error ( "No agents found for 'cross chain transfer'" ) ;
148+ process . exit ( 1 ) ;
149+ }
150+
151+ console . log ( `Found ${ relevantAgents . length } agents` ) ;
152+
153+ const chosenAgent = relevantAgents [ 0 ] ;
154+ console . log (
155+ `Chosen agent: ${ chosenAgent . name || "Unknown" } (ID: ${ chosenAgent . id } )` ,
156+ ) ;
157+
158+ if ( ! chosenAgent . jobOfferings || chosenAgent . jobOfferings . length === 0 ) {
159+ console . error ( "Agent has no job offerings" ) ;
160+ process . exit ( 1 ) ;
161+ }
162+
163+ const chosenJobOffering = chosenAgent . jobOfferings . find (
164+ ( offering ) => offering . name === "cross_chain_transfer" ,
165+ ) ;
166+
167+ if ( ! chosenJobOffering ) {
168+ console . error ( "Agent does not have 'cross_chain_transfer' offering" ) ;
169+ process . exit ( 1 ) ;
170+ }
171+
172+ console . log ( `Initiating job with offering: ${ chosenJobOffering . name } ` ) ;
173+
174+ const jobId = await chosenJobOffering . initiateJob (
175+ {
176+ symbol : "TEST" ,
177+ sourceChain,
178+ targetChain,
179+ amount,
180+ } ,
181+ undefined , // evaluator address
182+ new Date ( Date . now ( ) + 1000 * 60 * 15 ) , // 15 minute expiry
183+ ) ;
184+
185+ console . log ( `Job ${ jobId } initiated successfully` ) ;
186+ }
187+
188+ buyer ( ) . catch ( ( error ) => {
189+ console . error ( "Buyer error:" , error ) ;
190+ process . exit ( 1 ) ;
191+ } ) ;
0 commit comments