TypeScript SDK for ERC-8001: Agent Coordination Framework
The first Ethereum standard for multi-party agent coordination.
npm install @erc8001/sdk viemimport { CoordinationClient, BoundedClient } from '@erc8001/sdk';
import { createPublicClient, createWalletClient, http } from 'viem';
import { baseSepolia } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
// Setup clients
const account = privateKeyToAccount('0x...');
const publicClient = createPublicClient({ chain: baseSepolia, transport: http() });
const walletClient = createWalletClient({
account,
chain: baseSepolia,
transport: http()
});
// Create coordination client
const coordination = new CoordinationClient({
contractAddress: '0x...', // Your deployed AgentCoordination contract
publicClient,
walletClient,
});
// Propose a coordination
const { intentHash, payload } = await coordination.propose({
agentId: account.address,
participants: ['0xAlice...', '0xBob...'],
coordinationType: 'TRADE_V1',
payload: {
version: '0x' + '01'.padStart(64, '0'),
coordinationType: '0x...',
coordinationData: '0x...',
conditionsHash: '0x' + '0'.repeat(64),
metadata: '0x',
},
});
console.log('Proposed:', intentHash);
// Accept as a participant
const { txHash } = await coordination.accept(intentHash);
console.log('Accepted:', txHash);
// Wait for all participants to accept
const status = await coordination.waitForReady(intentHash);
console.log('Ready for execution!');
// Execute
const { txHash: execTx } = await coordination.execute(intentHash, payload);
console.log('Executed:', execTx);Add spending limits and policy constraints to agent actions:
import { BoundedClient } from '@erc8001/sdk';
import { parseEther, encodeFunctionData } from 'viem';
const bounded = new BoundedClient({
contractAddress: '0x...', // Your deployed BoundedExecution contract
publicClient,
walletClient,
});
// Register a policy
const { policyId } = await bounded.registerPolicy({
agent: '0xAgent...',
actions: [
{ target: '0xVault...', selector: '0xa9059cbb' }, // transfer
{ target: '0xVault...', selector: '0x095ea7b3' }, // approve
],
spendingLimit: parseEther('10'),
maxCalls: 100,
durationSeconds: 86400, // 1 day
});
// Execute within bounds
const callData = encodeFunctionData({
abi: [...],
functionName: 'transfer',
args: [recipient, amount],
});
const { success } = await bounded.execute(policyId, {
target: '0xVault...',
callData,
value: parseEther('1'),
});propose → accept (all participants) → execute
- Propose: Initiator signs an EIP-712 intent with required participants
- Accept: Each participant signs an acceptance attestation
- Execute: Once all accept, anyone can trigger execution
Participants must be sorted ascending by address:
import { canonicalizeParticipants } from '@erc8001/sdk';
const sorted = canonicalizeParticipants(['0xBob...', '0xAlice...']);
// Returns ['0xAlice...', '0xBob...'] (sorted by uint160)import { CoordinationTypes, coordinationType } from '@erc8001/sdk';
// Built-in types
CoordinationTypes.TRADE // keccak256("ERC8001.TRADE_V1")
CoordinationTypes.SWAP // keccak256("ERC8001.SWAP_V1")
CoordinationTypes.PAYMENT // keccak256("ERC8001.PAYMENT_V1")
// Custom types
const myType = coordinationType('MY_CUSTOM_COORD_V1');import {
createDomain,
signIntent,
signAcceptance,
computeIntentStructHash,
} from '@erc8001/sdk';
// Create domain
const domain = createDomain(84532n, '0xContract...');
// Sign intent
const signature = await signIntent(walletClient, domain, intent);
// Compute intent hash (for acceptances)
const intentHash = computeIntentStructHash(intent);
// Sign acceptance
const attestation = await signAcceptance(walletClient, domain, {
intentHash,
participant: account.address,
nonce: 0n,
expiry: BigInt(Math.floor(Date.now() / 1000) + 3600),
conditionsHash: '0x' + '0'.repeat(64),
});| Method | Description |
|---|---|
propose(options) |
Propose a new coordination |
accept(intentHash) |
Accept a coordination |
execute(intentHash, payload) |
Execute a ready coordination |
cancel(intentHash, reason) |
Cancel a coordination |
getStatus(intentHash) |
Get coordination status |
getAgentNonce(agentId) |
Get agent's current nonce |
waitForReady(intentHash) |
Wait for all acceptances |
| Method | Description |
|---|---|
registerPolicy(options) |
Register a new policy |
execute(policyId, action) |
Execute within bounds |
revokePolicy(policyId) |
Revoke a policy |
getPolicy(policyId) |
Get policy details |
verifyBounds(...) |
Check if action is allowed |
| Function | Description |
|---|---|
canonicalizeParticipants(addresses) |
Sort addresses ascending |
createIntent(options, nonce) |
Build an AgentIntent |
createAttestation(options) |
Build an AcceptanceAttestation |
computeBoundsRoot(actions) |
Compute Merkle root for actions |
generateProof(actions, index) |
Generate Merkle proof |
| Contract | Address |
|---|---|
| AgentCoordination | 0x... |
| BoundedExecution | 0x... |
MIT
