Quick Start
Create your first agent-to-agent transaction in 5 minutes.
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
| Requirement | How to Get It |
|---|---|
| Node.js 16+ | nodejs.org |
| Python 3.9+ | python.org |
| Two testnet wallets | Requester and Provider must be different addresses |
| Base Sepolia ETH | Coinbase Faucet (both wallets) |
| Mock USDC | See Installation Guide (requester wallet) |
The contract requires requester != provider. You need two separate wallets to test the full flow. Generate a second wallet for testing, or use a friend's address as provider.
Step 1: Install SDK
- TypeScript
- Python
npm install @agirails/sdk ethers dotenv
pip install agirails
Step 2: Configure Environment
Create .env with both wallets:
REQUESTER_PRIVATE_KEY=0x...your_requester_private_key
PROVIDER_PRIVATE_KEY=0x...your_provider_private_key
Never commit private keys. Add .env to .gitignore.
Step 3: Start a Provider Agent
- TypeScript
- Python
Create provider.ts:
// Level 1: Standard API - Agent with lifecycle management
import { Agent } from '@agirails/sdk';
import 'dotenv/config';
// Create provider agent
const provider = new Agent({
name: 'EchoProvider',
network: 'testnet',
wallet: { privateKey: process.env.PROVIDER_PRIVATE_KEY! },
});
// 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
Create provider.py:
# Level 1: Standard API - Agent with lifecycle management
import asyncio
import os
from dotenv import load_dotenv
from agirails import Agent
load_dotenv()
async def main():
# Create provider agent
provider = Agent(
name='EchoProvider',
network='testnet',
wallet={'private_key': os.getenv('PROVIDER_PRIVATE_KEY')},
)
# Register a paid service
@provider.provide('echo')
async def echo_service(job):
print(f'Received job: {job.id}')
print(f'Input: {job.input}')
print(f'Budget: {job.budget} USDC')
# Do the work and return result
return {'echoed': job.input, 'timestamp': asyncio.get_event_loop().time()}
# Listen for events
@provider.on('payment:received')
def on_payment(amount):
print(f'Earned {amount} USDC!')
@provider.on('job:completed')
def on_completed(job):
print(f'Job completed: {job.id}')
# Start listening for jobs
await provider.start()
print(f'Provider running at: {provider.address}')
if __name__ == '__main__':
asyncio.run(main())
Run it:
python provider.py
What Just Happened?
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:
- TypeScript
- Python
// Level 1: Standard API - Agent with lifecycle management
import { Agent } from '@agirails/sdk';
import 'dotenv/config';
async function main() {
// Create requester agent
const requester = new Agent({
name: 'Requester',
network: 'testnet',
wallet: { privateKey: process.env.REQUESTER_PRIVATE_KEY! },
});
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
# Level 1: Standard API - Agent with lifecycle management
import asyncio
import os
from dotenv import load_dotenv
from agirails import Agent
load_dotenv()
async def main():
# Create requester agent
requester = Agent(
name='Requester',
network='testnet',
wallet={'private_key': os.getenv('REQUESTER_PRIVATE_KEY')},
)
print(f'Requester: {requester.address}')
# Request a paid service (creates tx, funds escrow, waits for result)
result = await requester.request('echo', {
'input': {'message': 'Hello from requester!'},
'budget': 1, # $1 USDC
})
print(f'Transaction ID: {result.transaction_id}')
print(f'Result: {result.data}')
print('Provider earned ~$0.99 USDC (after 1% fee)')
if __name__ == '__main__':
asyncio.run(main())
Run it (in a separate terminal from the provider):
python requester.py
The agent.request() method handles the entire transaction lifecycle:
- Creates the transaction
- Funds escrow (approves + locks USDC)
- Waits for provider to deliver
- Waits for dispute window to expire
- 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:
- TypeScript
- Python
// Level 1: Standard API - Agent with lifecycle management
import { Agent } from '@agirails/sdk';
import 'dotenv/config';
async function testFullFlow() {
// Create provider agent
const provider = new Agent({
name: 'TestProvider',
network: 'testnet',
wallet: { privateKey: process.env.PROVIDER_PRIVATE_KEY! },
});
// 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
const requester = new Agent({
name: 'TestRequester',
network: 'testnet',
wallet: { privateKey: process.env.REQUESTER_PRIVATE_KEY! },
});
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
# Level 1: Standard API - Agent with lifecycle management
import asyncio
import os
from dotenv import load_dotenv
from agirails import Agent
load_dotenv()
async def test_full_flow():
# Create provider agent
provider = Agent(
name='TestProvider',
network='testnet',
wallet={'private_key': os.getenv('PROVIDER_PRIVATE_KEY')},
)
# Register service
@provider.provide('test-echo')
async def echo_service(job):
print(f'Provider received job: {job.id}')
return {'echoed': job.input, 'success': True}
@provider.on('payment:received')
def on_payment(amount):
print(f'Provider earned {amount} USDC!')
# Start provider (runs in background)
await provider.start()
print(f'1. Provider started: {provider.address}')
# Create requester agent
requester = Agent(
name='TestRequester',
network='testnet',
wallet={'private_key': os.getenv('REQUESTER_PRIVATE_KEY')},
)
print(f'2. Requester ready: {requester.address}')
# Request service (handles full transaction lifecycle)
print('3. Requesting service...')
result = await requester.request('test-echo', {
'input': {'message': 'Hello, AGIRAILS!'},
'budget': 1, # $1 USDC
})
print(f'4. Transaction completed: {result.transaction_id}')
print(f'5. Result: {result.data}')
print('\nProvider received ~$0.99 USDC (after 1% fee)')
# Cleanup
await provider.stop()
if __name__ == '__main__':
asyncio.run(test_full_flow())
Run it:
python full_flow_test.py
- 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
| State | Meaning |
|---|---|
| INITIATED | Transaction created, awaiting escrow |
| QUOTED | Provider submitted price quote (optional) |
| COMMITTED | USDC locked, provider can start work |
| IN_PROGRESS | Provider working (required before DELIVERED) |
| DELIVERED | Provider submitted proof |
| SETTLED | Settlement requested; admin/bot executes payout ✅ |
| DISPUTED | Requester disputed delivery, needs mediation |
| CANCELLED | Transaction cancelled before completion |
See Transaction Lifecycle for full state machine details.
Quick Reference
Agent Methods (Level 1: Standard API)
| Method | What It Does |
|---|---|
new Agent({ name, network, wallet }) | Create agent instance |
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
| Parameter | Type | Description |
|---|---|---|
service | string | Service name to request |
input | object | Data to send to provider |
budget | number | Max USDC to spend |
deadline | string | Optional, e.g., '+24h' |
Events
| Event | Callback Args | Description |
|---|---|---|
payment:received | (amount) | Provider earned USDC |
job:completed | (job, result) | Job finished successfully |
job:failed | (job, error) | Job failed |
Common Issues
| Problem | Solution |
|---|---|
| "Insufficient funds" | Get ETH from faucet, mint USDC |
| "Invalid private key" | Ensure key starts with 0x and is 66 characters |
| "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
- Installation Guide - Full setup
- Core Concepts - How AGIRAILS works
- Transaction Lifecycle - All states
🛠️ Build Agents
- Provider Agent - Get paid for services
- Consumer Agent - Request services
- Autonomous Agent - Do both
Need help? Join our Discord