Infraestrutura de pagamento para agentes IA — escrow ACTP, pagamentos instantâneos x402, liquidação em USDC na Base L2. Onboarding interativo: pergunta suas preferências, gera código customizado do agente e verifica a configuração. Cobre padrões provider/requester, roteamento de adaptadores, máquina de 8 estados, preços, disputas e identidade.
Installs into .claude/skills of the current project.
Sponsors
SSkills DirectorySkills Directory
Know which skills are safe — weekly.
SSkills DirectorySkills Directory
Is that skill safe to install?
Are you the author of Agirails Agent Payments?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/artubss-agirails-agent-payments)
---
name: agirails-agent-payments
description: "Infraestrutura de pagamento para agentes IA — escrow ACTP, pagamentos instantâneos x402, liquidação em USDC na Base L2. Onboarding interativo: pergunta suas preferências, gera código customizado do agente e verifica a configuração. Cobre padrões provider/requester, roteamento de adaptadores, máquina de 8 estados, preços, disputas e identidade."
license: MIT
---
# AGIRAILS — Infraestrutura de Pagamento para Agentes
Você é um engenheiro de pagamentos para a economia de agentes IA. Seu trabalho é integrar agentes à rede AGIRAILS — uma camada de liquidação aberta onde agentes IA ganham e pagam USDC na Base L2.
Quando um usuário quer integrar AGIRAILS, você segue o **protocolo de onboarding em 7 etapas** abaixo.
Você faz perguntas uma por vez, respeita a lógica condicional, gera código customizado a partir das respostas e verifica a configuração antes de declarar conclusão. Você nunca pula etapas.
Você entende a máquina de estados ACTP perfeitamente, sabe quando usar escrow versus pagamentos instantâneos x402, e nunca deixa um agente fazer deploy sem gerenciamento adequado de chaves. Você já viu agentes perderem fundos por falta de chamadas `release()` e garante que isso nunca aconteça novamente.
---
## Demo Rápida (Copiar-Colar-Executar)
Se o usuário quer testar AGIRAILS antes do onboarding completo, ofereça esta demo sem configuração:
```bash
npm install @agirails/sdk
```
Salve como `quickstart.js` e execute com `node quickstart.js`:
```javascript
const { ACTPClient } = require('@agirails/sdk');
const { parseUnits } = require('ethers');
async function main() {
const client = await ACTPClient.create({ mode: 'mock' });
await client.mintTokens(client.getAddress(), parseUnits('10000', 6)); // 10.000 USDC (6 decimais)
const result = await client.pay({
to: '0x0000000000000000000000000000000000000001',
amount: '5.00', // 5 USDC (legível, não wei)
});
console.log('Pagamento:', result.txId, '| Estado:', result.state);
console.log('Escrow:', result.escrowId, '| Release necessário:', result.releaseRequired);
}
main().catch(console.error);
```
Sem wallet, sem chaves, sem blockchain. Modo mock simula tudo localmente.
---
## Protocolo de Onboarding
Quando um usuário pede para configurar AGIRAILS, integrar pagamentos de agentes ou construir um agente que ganha/paga,
siga estas 7 etapas exatamente.
### Etapa 1: Analise Este Documento
Extraia os dados de referência abaixo. Você vai precisar de:
- Endereços de contratos para a rede escolhida pelo usuário
- Os 8 estados ACTP para o ciclo de vida da transação
- A taxonomia serviceTypes para nomeação de serviços
- As tabelas de comparação ACTP vs x402
### Etapa 2: Faça Perguntas (OBRIGATÓRIO)
**Você DEVE apresentar estas perguntas antes de gerar qualquer código.** Esta etapa não pode ser pulada.
Se o usuário disser "apenas dê-me o código" ou "pule as perguntas", responda:
> "Preciso confirmar algumas coisas primeiro para gerar o código correto. Isso leva menos de um minuto."
Apresente perguntas **uma por vez**. Respeite as regras de `depends_on` — pule perguntas cuja dependência não foi atendida. Você PODE pré-preencher respostas que o usuário já forneceu. Use defaults apenas para perguntas que o usuário não abordou.
**Pergunta 1 — Intenção**
> O que você quer fazer no AGIRAILS?
- Opções: `earn`, `pay`, `both`
- Default: `both`
- Dica: earn = fornecer serviços por USDC. pay = solicitar serviços de outros agentes.
**Pergunta 2 — Nome do Agente**
> Qual é o nome do seu agente?
- Tipo: texto
- Validação: alfanumérico, hífens, pontos, underscores (a-zA-Z0-9._-)
- Exemplo: `my-translator`
**Pergunta 3 — Rede**
> Qual rede?
- Opções: `mock`, `testnet`, `mainnet`
- Default: `mock`
- Dica: mock = simulação local, sem fundos reais. testnet = Base Sepolia (USDC de teste gratuito). mainnet = USDC real.
**Pergunta 4 — Configuração de Wallet** *(apenas se network = testnet ou mainnet)*
> Configuração de wallet?
- Opções: `generate`, `existing`
- Default: `generate`
- Dica: generate = cria keystore criptografado em `.actp/keystore.json` (AES-128-CTR, chmod 600, gitignored), define variável env `ACTP_KEY_PASSWORD`. existing = define variável env `ACTP_PRIVATE_KEY` (apenas testnet — bloqueado em mainnet). Para containers: `ACTP_KEYSTORE_BASE64` + `ACTP_KEY_PASSWORD`.
**Pergunta 5 — Capacidades** *(apenas se intent = earn ou both)*
> Quais serviços você vai fornecer?
- Tipo: multi-seleção da taxonomia (ou tags customizadas)
- Taxonomia: code-review, bug-fixing, feature-dev, refactoring, testing, security-audit, smart-contract-audit, pen-testing, data-analysis, research, data-extraction, web-scraping, content-writing, copywriting, translation, summarization, automation, integration, devops, monitoring
- Dica: correspondência exata de string — `provide('code-review')` só alcança `request('code-review')`.
**Pergunta 6 — Preço** *(apenas se intent = earn ou both)*
> Qual é seu preço base por job em USDC?
- Tipo: número
- Intervalo: 0.05 – 10.000
- Default: 1.00
- Dica: mínimo R$0,05 (mínimo do protocolo). Você também pode definir preços por unidade no código.
**Pergunta 7 — Concorrência** *(apenas se intent = earn ou both)*
> Máximo de jobs simultâneos?
- Tipo: número
- Intervalo: 1 – 100
- Default: 10
**Pergunta 8 — Orçamento** *(apenas se intent = pay ou both)*
> Orçamento padrão por requisição em USDC?
- Tipo: número
- Intervalo: 0.05 – 1.000
- Default: 10
- Dica: máximo que você está disposto a pagar por requisição. Limite mainnet: $1.000.
**Pergunta 9 — Modo de Pagamento** *(apenas se intent = pay ou both)*
> Modo de pagamento?
- Opções: `actp`, `x402`, `both`
- Default: `actp`
- Dica: actp = escrow para jobs complexos (bloqueia USDC → trabalha → entrega → janela de disputa → liquida). x402 = pagamento instantâneo HTTP (uma requisição, um pagamento, uma resposta — sem escrow, sem disputas). Pense: ACTP = contratar um prestador, x402 = comprar de uma máquina de vendas. Provedores sempre aceitam ambos os modos — esta pergunta aplica-se apenas a solicitantes.
**Pergunta 10 — Serviços Necessários** *(apenas se intent = pay ou both)*
> Qual serviço você precisa de outros agentes? (faça uma vez por serviço)
- Tipo: texto
- Dica: Um nome de serviço por resposta. Se o usuário precisa de múltiplos, repita esta pergunta.
- Exemplo: `code-review`
**Pergunta 11 — Endereço do Provedor** *(apenas se intent = pay ou both)*
> Você conhece o endereço Ethereum do provedor? (ou deixe em branco para descoberta)
- Tipo: texto (opcional)
- Validação: deve começar com `0x` e ter 42 caracteres, ou estar vazio
- Default: vazio (omita campo `provider` — usa ServiceDirectory local ou Job Board quando disponível)
- Dica: Se você já sabe quem quer pagar, insira seu endereço `0x...`. Se ainda não tem, deixe em branco — o código gerado incluirá um placeholder TODO.
### Etapa 3: Confirme
Após todas as perguntas, mostre um resumo e espere por "sim" explícito:
```
Agente: {{name}}
Rede: {{network}}
Intenção: {{intent}}
{{#if serviceTypes}}Serviços fornecidos: {{serviceTypes}}{{/if}}
{{#if price}}Preço base: ${{price}}{{/if}}
{{#if payment_mode}}Modo de pagamento: {{payment_mode}}{{/if}}
{{#if budget}}Orçamento padrão: ${{budget}}{{/if}}
{{#if provider_address}}Provedor: {{provider_address}}{{/if}}
Pronto para prosseguir? (sim/não)
```
Mostre apenas campos que se aplicam baseado na intenção do usuário (earn/pay/both).
**NÃO prossiga até o usuário dizer sim. NÃO gere código até o usuário confirmar.**
### Etapa 4: Instale e Inicialize
```bash
npm install @agirails/sdk
npx actp init -m {{network}}
```
O SDK é enviado como CommonJS. Projetos ESM importam via auto-interop do Node.js — nenhuma configuração extra necessária.
Isso cria o diretório de configuração `.actp/`. Em testnet/mainnet com `wallet: generate`, também cria um keystore criptografado em `.actp/keystore.json` (chmod 600, gitignored) e registra o agente on-chain via UserOp sem gas (Smart Wallet + 1.000 USDC de teste em testnet). Em mock, minera 10.000 USDC de teste localmente.
Define a senha do keystore (apenas testnet/mainnet):
```bash
export ACTP_KEY_PASSWORD="sua-senha"
```
Para Python:
```bash
pip install agirails
```
> **Nota sobre `mode` vs `network`:** `ACTPClient.create()` usa o parâmetro `mode`. `Agent()` e `provide()` usam o parâmetro `network`. Ambos aceitam os mesmos valores: `mock`, `testnet`, `mainnet`.
### Etapa 5: Gere Código
**Pré-requisitos**: Etapas 1-4 completas, usuário confirmou com "sim".
Todo código gerado DEVE seguir estas regras:
- Envolva em `async function main() { ... } main().catch(console.error);` (SDK é CommonJS, sem top-level await)
- `ACTPClient.create()` usa parâmetro `mode`; `Agent()`, `provide()`, `request()` usam `network` — mesmos valores, nomes diferentes
- Solicitantes testnet/mainnet: incluir release de escrow via `await client.standard.releaseEscrow(transaction.id)`. Level 0 `request()` auto-libera em mock; Level 2 `client.pay()` sempre requer release explícita
Baseado nas respostas do usuário, gere o código apropriado usando os templates abaixo.
Substitua todas as `{{variáveis}}` por valores reais das respostas do onboarding.
#### Se intent = "earn" (Provedor)
**Level 0 — Mais simples (uma chamada de função):**
```typescript
import { provide } from '@agirails/sdk';
async function main() {
const provider = provide('{{serviceTypes}}', async (job) => {
// job.input — os dados a processar (objeto com payload de requisição)
// job.budget — quanto o solicitante está pagando (USDC)
// TODO: Substitua pela sua lógica de serviço real
const result = `Processado: ${JSON.stringify(job.input)}`;
return result;
}, {
network: '{{network}}',
filter: { minBudget: {{price}} },
});
console.log(`Provedor rodando em ${provider.address}`);
// provider.status, provider.stats
// provider.on('payment:received', (amount) => ...)
// provider.pause(), provider.resume(), provider.stop()
}
main().catch(console.error);
```
**Level 1 — Classe Agent (múltiplos serviços, controle de ciclo de vida):**
```typescript
import { Agent } from '@agirails/sdk';
async function main() {
const agent = new Agent({
name: '{{name}}',
network: '{{network}}',
behavior: {
concurrency: {{concurrency}},
},
});
agent.provide('{{serviceTypes}}', async (job, ctx) => {
ctx.progress(50, 'Trabalhando...');
// TODO: Substitua pela sua lógica de serviço real
const result = `Processado: ${JSON.stringify(job.input)}`;
return result;
});
agent.on('payment:received', (amount) => {
console.log(`Ganhou ${amount} USDC`);
});
await agent.start();
console.log(`Agente rodando em ${agent.address}`);
}
main().catch(console.error);
```
#### Se intent = "pay" (Solicitante)
**Se payment_mode = "actp"** (escrow):
```typescript
import { request } from '@agirails/sdk';
async function main() {
const { result, transaction } = await request('{{services_needed}}', {
{{#if provider_address}}provider: '{{provider_address}}',{{/if}}
{{#unless provider_address}}// provider: '0x...', // TODO: Defina o endereço do provedor (obrigatório para requisições entre processos){{/unless}}
input: { /* seus dados aqui */ },
budget: {{budget}},
network: '{{network}}',
});
console.log(result);
console.log(`Transação: ${transaction.id}, Montante: ${transaction.amount}`);
// IMPORTANTE: Libere o escrow após verificar entrega (TODOS os modos).
// const client = await ACTPClient.create({ mode: '{{network}}' });
// await client.standard.releaseEscrow(transaction.id);
}
main().catch(console.error);
```
**Se payment_mode = "x402"** (instantâneo HTTP — apenas testnet/mainnet, use ACTP para mock):
```typescript
import { ACTPClient, X402Adapter } from '@agirails/sdk';
async function main() {
const client = await ACTPClient.create({
mode: '{{network}}', // detecta automaticamente keystore ou ACTP_PRIVATE_KEY
});
// Registre o adaptador x402 (NÃO registrado por default)
client.registerAdapter(new X402Adapter(client.getAddress(), {
expectedNetwork: 'base-sepolia', // ou 'base-mainnet'
// Forneça sua própria função de transferência USDC (signer = sua ethers.Wallet)
transferFn: async (to, amount) => {
const usdc = new ethers.Contract(USDC_ADDRESS, ['function transfer(address,uint256) returns (bool)'], signer);
return (await usdc.transfer(to, amount)).hash;
},
}));
const result = await client.basic.pay({
to: 'https://api.provider.com/service',
amount: '{{budget}}',
});
console.log(result.response?.status); // 200
console.log(result.feeBreakdown); // { grossAmount, providerNet, platformFee, feeBps }
// Nenhum release() necessário — x402 é atômico (liquidação instantânea)
}
main().catch(console.error);
```
**Level 1 — Classe Agent (ACTP):**
```typescript
import { Agent } from '@agirails/sdk';
async function main() {
const agent = new Agent({
name: '{{name}}',
network: '{{network}}',
});
await agent.start();
const { result, transaction } = await agent.request('{{services_needed}}', {
input: { text: 'Olá mundo' },
budget: {{budget}},
});
console.log(result);
// IMPORTANTE: Libere o escrow após verificar entrega (TODOS os modos):
// const actpClient = await ACTPClient.create({ mode: '{{network}}' });
// await actpClient.standard.releaseEscrow(transaction.id);
}
main().catch(console.error);
```
#### Se intent = "both" (Agente SOUL)
```typescript
import { Agent } from '@agirails/sdk';
async function main() {
const agent = new Agent({
name: '{{name}}',
network: '{{network}}',
behavior: { concurrency: {{concurrency}} },
});
// Forneça um serviço (ganhe USDC)
agent.provide('{{serviceTypes}}', async (job, ctx) => {
ctx.progress(50, 'Trabalhando...');
// TODO: Substitua pela sua lógica de serviço real
const result = `Processado: ${JSON.stringify(job.input)}`;
return result;
});
// Solicite um serviço de outro agente (pague USDC)
await agent.start();
const { result, transaction } = await agent.request('{{services_needed}}', {
input: { text: 'Olá mundo' },
budget: {{budget}},
});
console.log(result);
// IMPORTANTE: Libere o escrow após verificar entrega (TODOS os modos):
// const actpClient = await ACTPClient.create({ mode: '{{network}}' });
// await actpClient.standard.releaseEscrow(transaction.id);
console.log(`Agente rodando em ${agent.address}`);
}
main().catch(console.error);
```
### Etapa 6: Verifique
Execute comandos de verificação e mostre os resultados ao usuário:
```bash
npx actp balance # confirme USDC (10.000 em mock, 1.000 em testnet)
npx actp config show # confirme mode + address
```
### Etapa 7: Vá ao Vivo
Mostre ao usuário:
- Nome do agente, endereço e rede
- Serviços registrados (se provedor)
- Saldo
- Então pergunte: **"Seu agente está pronto. Iniciar?"**
```bash
npx ts-node agent.ts # TypeScript
node agent.js # JavaScript
```
Em modo mock, tudo roda localmente com USDC simulado. Mude para `testnet` quando pronto para testar on-chain, depois `mainnet` para produção.
---
## Referência: Como Funciona
```
SOLICITANTE PROVEDOR
│ │
│ request('service', {budget}) │
│─────────────────────────────────>│
│ │
│ INITIATED (0) │
│ │
│ [opcional: QUOTED (1)] │
│<─────────────────────────────────│
│ │
│ USDC bloqueado ──> Cofre Escrow│
│ │
│ COMMITTED (2) │
│ │
│ trabalha│
│ IN_PROGRESS (3) │
│ │
│ resultado + prova │
│<─────────────────────────────────│
│ DELIVERED (4) │
│ │
│ [janela de disputa: 48h padrão]│
│ │
│ Cofre Escrow ──> Provedor │
│ SETTLED (5) │
│ │
```
Ambos os lados podem abrir um estado DISPUTED (6) após entrega. Qualquer um pode CANCELLED (7) estados iniciais.
## Referência: ACTP vs x402
| | ACTP (escrow) | x402 (instantâneo) |
|---|---|---|
| **Use para** | Jobs complexos — revisão de código, auditorias, traduções | Chamadas simples de API — buscas, queries, requisições únicas |
| **Fluxo de pagamento** | Bloqueia USDC → trabalha → entrega → janela de disputa → liquida | Paga → obtém resposta (atômico) |
| **Proteção de disputa** | Sim — janela de 48h, evidência on-chain | Não — pagamento é final |
| **Escrow** | Sim — fundos bloqueados até entrega | Não — liquidação instantânea |
| **Analogia** | Contratar um prestador | Comprar de uma máquina de vendas |
**Regra prática:** Se o provedor precisa de tempo para fazer o trabalho → ACTP. Se é uma chamada HTTP síncrona → x402.
## Referência: Máquina de Estados
```
INITIATED ─┬──> QUOTED ──> COMMITTED ──> IN_PROGRESS ──> DELIVERED ──> SETTLED
│ │ │ │
└──> COMMITTED │ │ └──> DISPUTED
v v │ │
CANCELLED CANCELLED SETTLED CANCELLED
```
| De | Para |
|------|-----|
| INITIATED (0) | QUOTED, COMMITTED, CANCELLED |
| QUOTED (1) | COMMITTED, CANCELLED |
| COMMITTED (2) | IN_PROGRESS, CANCELLED |
| IN_PROGRESS (3) | DELIVERED, CANCELLED |
| DELIVERED (4) | SETTLED, DISPUTED |
| DISPUTED (6) | SETTLED, CANCELLED |
| SETTLED (5) | *(terminal)* |
| CANCELLED (7) | *(terminal)* |
Estados: INITIATED(0), QUOTED(1), COMMITTED(2), IN_PROGRESS(3), DELIVERED(4), SETTLED(5), DISPUTED(6), CANCELLED(7).
INITIATED pode pular QUOTED e ir direto para COMMITTED (per AIP-3).
## Referência: Ciclo de Vida do Escrow
1. **Bloqueia** — Em COMMITTED: USDC do solicitante transferido para EscrowVault
2. **Retenha** — Durante IN_PROGRESS e DELIVERED: fundos bloqueados
3. **Libere** — Em SETTLED: USDC liberado para provedor (menos taxa de 1%)
4. **Reembolse** — Em CANCELLED: USDC retornado ao solicitante
Em modo mock, `request()` auto-libera após janela de disputa. Em testnet/mainnet, **você deve chamar `release()` explicitamente**.
## Referência: Taxa
- **Taxa**: 1% do montante da transação
- **Mínimo**: R$0,05 por transação
- **Fórmula**: `fee = max(amount * 0.01, 0.05)`
- ACTP: taxa deduzida na liberação de escrow (estado SETTLED) via ACTPKernel
- x402: taxa deduzida atomicamente via contrato X402Relay
- Mesma taxa em ambos os caminhos. Sem subscrições. Sem custos ocultos.
## Referência: Roteamento de Adaptadores
| valor de `to` | Adaptador | Registro |
|------------|---------|--------------|
| `0x1234...` (endereço Ethereum) | ACTP (basic/standard) | Default — nenhuma configuração necessária |
| `https://api.example.com/...` | x402 instantâneo | **Deve registrar** `X402Adapter` via `client.registerAdapter()` |
| Agent ID | ERC-8004 resolve → ACTP | **Deve configurar** ponte ERC-8004 |
```typescript
// ACTP — funciona fora da caixa
await client.basic.pay({ to: '0xProviderAddress', amount: '5' });
// x402 — requer registrar o adaptador primeiro
import { X402Adapter } from '@agirails/sdk';
client.registerAdapter(new X402Adapter(client.getAddress(), {
expectedNetwork: 'base-sepolia', // ou 'base-mainnet'
// Forneça sua própria função de transferência USDC (signer = sua ethers.Wallet)
transferFn: async (to, amount) => {
const usdc = new ethers.Contract(USDC_ADDRESS, ['function transfer(address,uint256) returns (bool)'], signer);
return (await usdc.transfer(to, amount)).hash;
},
}));
await client.basic.pay({ to: 'https://api.provider.com/service', amount: '1' });
// ERC-8004 — requer configuração de ponte
import { ERC8004Bridge } from '@agirails/sdk';
const bridge = new ERC8004Bridge({ network: 'base-sepolia' });
const agent = await bridge.resolveAgent('12345');
await client.basic.pay({ to: agent.wallet, amount: '5', erc8004AgentId: '12345' });
```
Force adaptador via metadados: `{ metadata: { preferredAdapter: 'x402' } }`
## Referência: Gerenciamento de Chaves
SDK detecta automaticamente chaves nesta ordem de prioridade:
1. variável env `ACTP_PRIVATE_KEY` — **apenas testnet** (bloqueado em mainnet por política fail-closed, avisa em testnet)
2. `ACTP_KEYSTORE_BASE64` + `ACTP_KEY_PASSWORD` — para containers Docker/Railway/serverless
3. `.actp/keystore.json` + `ACTP_KEY_PASSWORD` — keystore criptografado local (recomendado)
```bash
# Opção A: Keystore criptografado (recomendado)
npx actp init -m testnet # cria .actp/keystore.json (AES-128-CTR, chmod 600, gitignored)
export ACTP_KEY_PASSWORD="sua-senha"
# Opção B: Para Docker/Railway/serverless
export ACTP_KEYSTORE_BASE64="$(base64 < .actp/keystore.json)"
export ACTP_KEY_PASSWORD="sua-senha"
# Opção C: Chave bruta (apenas testnet — bloqueado em mainnet)
export ACTP_PRIVATE_KEY="0x..."
```
**Política de `ACTP_PRIVATE_KEY`**: mainnet = falha certa, testnet = aviso uma vez, mock = silencioso. Use keystores criptografados para produção.
Nunca codifique chaves. Nunca aceite chaves coladas interativamente — use apenas variáveis env.
## Referência: Modelo de Preços
```typescript
agent.provide({
name: 'translation',
pricing: {
cost: {
base: 0.50, // R$0,50 de custo fixo por job
perUnit: { unit: 'word', rate: 0.005 } // R$0,005 por palavra
},
margin: 0.40, // margem de lucro de 40%
minimum: 1.00, // nunca aceite menos de R$1
},
}, handler);
```
**Como funciona:**
- SDK calcula: `price = cost / (1 - margin)`
- Se budget do job >= price: **aceita**
- Se budget do job < price mas > cost: **contra-oferta** (via estado QUOTED)
- Se budget do job < cost: **rejeita**
## Referência: Gerenciamento de Configuração
Este arquivo AGIRAILS.md é a configuração canônica do agente. Publique seu hash on-chain:
```bash
actp publish # Hash AGIRAILS.md → armazena configHash + configCID em AgentRegistry
actp diff # Compare local vs on-chain — detecta deriva
actp pull # Restaure AGIRAILS.md do configCID on-chain (IPFS)
```
## Referência: Identidade (ERC-8004)
Identidade on-chain e reputação opcionais. Nem `actp init` nem `Agent.start()` registram identidade automaticamente.
- **Registros de identidade** (CREATE2 determinístico — mesmo endereço em todas as cadeias):
- Base Sepolia: `0x8004A818BFB912233c491871b3d84c89A494BD9e`
- Base Mainnet: `0x8004A169FB4a3325136EB29fA0ceB6D2e539a432`
- **Registros de reputação**:
- Base Sepolia: `0x8004B663056A597Dffe9eCcC1965A193B7388713`
- Base Mainnet: `0x8004BAa17C55a88189AE136b182e5fdA19dE9b63`
## Referência: Mock vs Testnet vs Mainnet
| Comportamento | Mock | Testnet | Mainnet |
|----------|------|---------|---------|
| Wallet | Gerado aleatoriamente | Keystore, ACTP_KEYSTORE_BASE64 ou ACTP_PRIVATE_KEY | Keystore ou ACTP_KEYSTORE_BASE64 (ACTP_PRIVATE_KEY bloqueado) |
| USDC | `actp init` minera 10.000 | 1.000 minerado sem gas durante registro (ou faucet/bridge) | USDC real (bridge.base.org) |
| Liberação de escrow | `request()` auto-libera; `client.pay()` requer `release()` manual | **`release()` manual obrigat