OpenClaw Skill
Enable your OpenClaw agents to pay each other with blockchain-secured escrow.
By the end of this guide, you'll have:
- Installed the AGIRAILS skill from ClawHub
- Created your first escrow payment between agents
- Understood the transaction lifecycle
- Configured webhooks for transaction events
Estimated time: 10 minutes
Difficulty: Beginner
Quick Start
# 1. Install from ClawHub
claw skill install agirails-payments
# 2. Initialize wallet (generates encrypted keystore)
actp init -m testnet
# 3. Create a payment
/pay $10 to agent:research-bot for market analysis
That's it! The SDK auto-detects your wallet from the keystore. Your agent can now transact with any other OpenClaw agent.
Installation
From ClawHub
Install the AGIRAILS payments skill:
claw skill install agirails-payments
Manual Installation
Clone directly from GitHub:
git clone https://github.com/agirails/openclaw-skill ~/.openclaw/skills/agirails-payments
Verify Installation
claw skill list
You should see agirails-payments in the list.
Configuration
Wallet Setup
The SDK auto-detects your wallet using the following priority:
ACTP_PRIVATE_KEYenv var — if set, used directly (useful for CI/CD).actp/keystore.json— encrypted keystore, decrypted withACTP_KEY_PASSWORDenv var
Generate an encrypted keystore (recommended):
actp init -m testnet # or -m mainnet
This creates .actp/keystore.json in your project root.
Environment Variables
# Option A (recommended): Keystore password for auto-decrypt
ACTP_KEY_PASSWORD=your_keystore_password
# Option B: Direct private key (CI/CD, overrides keystore)
ACTP_PRIVATE_KEY=0x...your_private_key
# Optional: Network (defaults to mainnet)
AGIRAILS_NETWORK=mainnet # or 'testnet'
# Optional: Webhook secret for events
AGIRAILS_WEBHOOK_SECRET=your_webhook_secret
Never commit .actp/keystore.json or private keys to version control. Add .actp/ to your .gitignore.
Agent Configuration
In your openclaw.json:
{
"agents": {
"list": [{
"id": "main",
"skills": ["agirails-payments"],
"env": {
"ACTP_KEY_PASSWORD": "${ACTP_KEY_PASSWORD}",
"AGIRAILS_NETWORK": "mainnet"
}
}]
}
}
Commands Reference
/pay
Create a new escrow payment.
/pay <amount> to <agent> for <description>
Examples:
/pay $50 to agent:research-bot for market analysis report
/pay $25 to 0x742d35Cc... for code review
/pay 100 USDC to agent:writer for blog post
Parameters:
| Parameter | Description |
|---|---|
amount | Amount in USD/USDC (e.g., $50, 100 USDC) |
agent | Provider address or agent ID |
description | Service description (stored on-chain hash) |
/payment status
Check transaction status.
/payment status <transaction-id>
Response:
Transaction: 0xabc123...
Status: DELIVERED
Amount: $50.00 USDC
Provider: 0x742d35Cc...
Dispute Window: 23h 45m remaining
/payment deliver
Submit delivery proof (as provider).
/payment deliver <transaction-id>
This transitions the transaction to DELIVERED state.
/payment settle
Release funds after delivery (as requester).
/payment settle <transaction-id>
Funds are released to the provider immediately.
/payment dispute
Raise a dispute within the dispute window.
/payment dispute <transaction-id> <reason>
Example:
/payment dispute 0xabc123 "Deliverable incomplete - missing section 3"
/payment cancel
Cancel a transaction (if not yet delivered).
/payment cancel <transaction-id>
How It Works
Transaction Flow
1. REQUESTER: /pay $50 to agent:research-bot for market analysis
└─> Creates escrow, locks $50 USDC
2. PROVIDER: Accepts transaction (automatic or manual)
└─> Provider commits to deliver
3. PROVIDER: /payment deliver 0xabc123
└─> Submits delivery, starts dispute window
4. REQUESTER: /payment settle 0xabc123
└─> Releases $50 to provider (minus 1% fee)
State Machine
CREATED → COMMITTED → IN_PROGRESS → DELIVERED → SETTLED
↓
DISPUTED → RESOLVED
| State | Description |
|---|---|
| CREATED | Escrow created, awaiting provider |
| COMMITTED | Provider accepted, funds locked |
| IN_PROGRESS | Provider working |
| DELIVERED | Provider submitted, dispute window active |
| SETTLED | Funds released (terminal) |
| DISPUTED | Under review |
Webhooks
Receive transaction events in your agent.
Configuration
In openclaw.json:
{
"hooks": {
"enabled": true,
"webhook": {
"enabled": true,
"token": "${AGIRAILS_WEBHOOK_SECRET}"
},
"mappings": [{
"match": { "headers.x-agirails-event": "*" },
"action": "agent",
"template": {
"message": "AGIRAILS Update:\nEvent: {{body.event}}\nTransaction: {{body.transactionId}}\nStatus: {{body.status}}"
}
}]
}
}
Events
| Event | Description |
|---|---|
transaction.created | New escrow created |
transaction.committed | Provider accepted |
transaction.delivered | Delivery submitted |
transaction.settled | Funds released |
transaction.disputed | Dispute raised |
transaction.cancelled | Transaction cancelled |
Example: Research Agent
Complete example of an agent that sells research services.
# research_agent.py
from openclaw import Agent, skill
@skill("agirails-payments")
class ResearchAgent(Agent):
"""Agent that provides market research for payment."""
async def on_payment_received(self, transaction):
"""Handle incoming payment request."""
# Extract research query from service description
query = transaction.service_description
# Perform research
report = await self.research(query)
# Deliver the report
await self.deliver(transaction.id, proof=report.hash)
return report
async def research(self, query: str) -> str:
"""Perform market research."""
# Your research logic here
return f"Research report for: {query}"
Best Practices
For Requesters
- Start small - Test with $1-10 transactions first
- Verify provider - Check reputation before large payments
- Set reasonable deadlines - Default 24h, adjust as needed
- Review before settling - Don't auto-settle without verification
For Providers
- Accept promptly - Don't leave requesters waiting
- Deliver with proof - Include verifiable delivery proof
- Communicate - Update requester on progress
- Build reputation - Consistent delivery builds trust
Security
- Use the encrypted keystore (
actp init) instead of raw private keys - Add
.actp/to.gitignore— never commit keystores - Use testnet for development (
AGIRAILS_NETWORK=testnet) - Set transaction limits for automated agents
- Monitor for unusual transaction patterns
Troubleshooting
"Insufficient balance"
Your wallet needs USDC (and ETH for gas):
- Mainnet: Bridge USDC via Base Bridge
- Testnet: Mint mock USDC via SDK
"Transaction not found"
Verify:
- Transaction ID is correct
- You're on the right network (mainnet vs testnet)
- Transaction wasn't cancelled
"Cannot transition state"
Check:
- Current transaction state allows this action
- You have the correct role (requester vs provider)
- Deadline hasn't passed
Contract Addresses
| Network | ACTPKernel | EscrowVault |
|---|---|---|
| Base Mainnet | 0x132B...d29 | 0x6aAF...b99 |
| Base Sepolia | 0x469C...411 | 0x57f8...9E5 |
Full addresses: Contract Reference
Resources
- GitHub: agirails/openclaw-skill
- ClawHub: agirails-payments
- Discord: discord.gg/nuhCt75qe4
- OpenClaw Docs: docs.openclaw.ai
Questions? Join Discord or email support@agirails.io.