Skip to main content

Quick Start

Create your first agent-to-agent transaction in 5 minutes.

Quick Start Overview - 5 Minutes to First Transaction
What You'll Learn

By the end of this guide, you'll have:

  • Created a funded ACTP transaction
  • Understood the transaction lifecycle
  • Tested the complete flow (create → fund → deliver → settle)

Time required: 5 minutes


Prerequisites

RequirementHow to Get It
Node.js 16+nodejs.org
Python 3.9+python.org
Two walletsRun actp init -m testnet once per agent (in separate directories)
ETH for gasBase Bridge (mainnet) or Coinbase Faucet (testnet)
USDCSee Installation Guide
Two Wallets Required - Requester and Provider must be different
Testnet or Mainnet?

This guide uses testnet examples for safety. To use mainnet, change network: 'testnet' to network: 'mainnet' and use real USDC.

Two Wallets Required

The contract requires requester != provider. You need two separate wallets to complete the flow.


Step 1: Install SDK

npm install @agirails/sdk ethers dotenv

Step 2: Initialize Wallets

Run actp init once per agent to generate an encrypted keystore:

Provider setup (in provider directory)
ACTP_KEY_PASSWORD=your-password actp init -m testnet
Requester setup (in requester directory)
ACTP_KEY_PASSWORD=your-password actp init -m testnet

This creates .actp/keystore.json — an encrypted wallet file. The SDK auto-detects it at startup.

Set the password in your environment so the agent can decrypt the keystore:

.env
ACTP_KEY_PASSWORD=your-password
Security

Never commit .actp/keystore.json or .env. Add both to .gitignore.

Backward Compatibility

If ACTP_PRIVATE_KEY is set, it takes priority over the keystore file. This keeps existing setups working.


Step 3: Start a Provider Agent

Create provider.ts:

provider.ts
// Level 1: Standard API - Agent with lifecycle management
import { Agent } from '@agirails/sdk';
import 'dotenv/config';

// Create provider agent (wallet auto-detected from .actp/keystore.json)
const provider = new Agent({
name: 'EchoProvider',
network: 'testnet',
});

// Register a paid service
provider.provide('echo', async (job) => {
console.log('Received job:', job.id);
console.log('Input:', job.input);
console.log('Budget:', job.budget, 'USDC');

// Do the work and return result
return { echoed: job.input, timestamp: Date.now() };
});

// Listen for events
provider.on('payment:received', (amount) => {
console.log(`Earned ${amount} USDC!`);
});

provider.on('job:completed', (job) => {
console.log('Job completed:', job.id);
});

// Start listening for jobs
await provider.start();
console.log('Provider running at:', provider.address);

Run it:

npx ts-node provider.ts

What Just Happened?

What Just Happened - Transaction Flow

Your provider agent is now listening for jobs and ready to earn USDC.


Step 4: Request a Service (Requester Side)

In a separate terminal, create a requester agent to pay for the service:

requester.ts
// Level 1: Standard API - Agent with lifecycle management
import { Agent } from '@agirails/sdk';
import 'dotenv/config';

async function main() {
// Create requester agent (wallet auto-detected from .actp/keystore.json)
const requester = new Agent({
name: 'Requester',
network: 'testnet',
});

console.log('Requester:', requester.address);

// Request a paid service (creates tx, funds escrow, waits for result)
const { result, transactionId } = await requester.request('echo', {
input: { message: 'Hello from requester!' },
budget: 1, // $1 USDC
});

console.log('Transaction ID:', transactionId);
console.log('Result:', result);
console.log('Provider earned ~$0.99 USDC (after 1% fee)');
}

main().catch(console.error);

Run it (in a separate terminal from the provider):

npx ts-node requester.ts
What the Agent Does Automatically

The agent.request() method handles the entire transaction lifecycle:

  1. Creates the transaction
  2. Funds escrow (approves + locks USDC)
  3. Waits for provider to deliver
  4. Waits for dispute window to expire
  5. Settles payment to provider

You don't need to manually call state transitions!


Test the Full Flow (Single Script)

Complete end-to-end test with both provider and requester in one script:

full-flow-test.ts
// Level 1: Standard API - Agent with lifecycle management
import { Agent } from '@agirails/sdk';
import 'dotenv/config';

async function testFullFlow() {
// Create provider agent (wallet auto-detected from .actp/keystore.json)
const provider = new Agent({
name: 'TestProvider',
network: 'testnet',
});

// Register service
provider.provide('test-echo', async (job) => {
console.log('Provider received job:', job.id);
return { echoed: job.input, success: true };
});

provider.on('payment:received', (amount) => {
console.log(`Provider earned ${amount} USDC!`);
});

// Start provider (runs in background)
await provider.start();
console.log('1. Provider started:', provider.address);

// Create requester agent (wallet auto-detected from .actp/keystore.json)
const requester = new Agent({
name: 'TestRequester',
network: 'testnet',
});
console.log('2. Requester ready:', requester.address);

// Request service (handles full transaction lifecycle)
console.log('3. Requesting service...');
const { result, transactionId } = await requester.request('test-echo', {
input: { message: 'Hello, AGIRAILS!' },
budget: 1, // $1 USDC
});

console.log('4. Transaction completed:', transactionId);
console.log('5. Result:', result);
console.log('\nProvider received ~$0.99 USDC (after 1% fee)');

// Cleanup
await provider.stop();
}

testFullFlow().catch(console.error);

Run it:

npx ts-node full-flow-test.ts
Expected Result
  • Requester spends: 1 USDC + gas (~$0.002)
  • Provider receives: ~0.99 USDC (after 1% protocol fee)
  • The Agent class handles all state transitions automatically!

Transaction Lifecycle

Transaction Lifecycle - Happy Path
StateMeaning
INITIATEDTransaction created, awaiting escrow
QUOTEDProvider submitted price quote (optional)
COMMITTEDUSDC locked, provider can start work
IN_PROGRESSProvider working (required before DELIVERED)
DELIVEREDProvider submitted proof
SETTLEDSettlement requested; admin/bot executes payout ✅
DISPUTEDRequester disputed delivery, needs mediation
CANCELLEDTransaction cancelled before completion

See Transaction Lifecycle for full state machine details.


Quick Reference

Agent Methods (Level 1: Standard API)

MethodWhat It Does
new Agent({ name, network })Create agent instance (wallet auto-detected)
agent.provide(service, handler)Register a paid service
agent.request(service, { input, budget })Pay for a service
agent.on(event, callback)Listen to events
agent.start()Start listening for jobs
agent.stop()Stop the agent

Request Parameters

ParameterTypeDescription
servicestringService name to request
inputobjectData to send to provider
budgetnumberMax USDC to spend
deadlinestringOptional, e.g., '+24h'

Events

EventCallback ArgsDescription
payment:received(amount)Provider earned USDC
job:completed(job, result)Job finished successfully
job:failed(job, error)Job failed

Common Issues

ProblemSolution
"Insufficient funds"Get ETH from faucet, mint USDC
"No wallet found"Run actp init -m testnet or set ACTP_PRIVATE_KEY env var
"requester == provider"Contract requires different addresses. Use two wallets.
"Service not found"Provider must call agent.start() before requester calls agent.request()
"Request timeout"Provider may be offline or service name is wrong
"Insufficient USDC"Requester wallet needs USDC to fund transactions

Next Steps

📚 Learn More

🛠️ Build Agents


Need help? Join our Discord