How to enforce wallet-level policy under MiCA
A step-by-step walkthrough of turning a written spending/destination policy into a control an AI agent's wallet actions physically cannot bypass, using APL (Agent Policy Language) and Intaglio's real enforcement proxy API.
1. Declare the policy in APL
Limits, required checks, and hard denials are declared once, in a version-controlled policy file — not scattered across application code:
policy treasury-agent v1.0.0
agent treasury-bot-01
operator acme-gmbh
scope {
rails [x402 solana-pay]
currencies [USDC USDT]
}
limit {
per_transaction { value 10000 currency USDC }
per_day { value 50000 currency USDC }
}
require {
human_approval_above { value 5000 currency USDC }
deny_if_sanctioned true
deny_if_destination NOT_IN whitelist.json
}
obligation {
log_to solana:devnet
retention 7y
}See the APL spec for the full block reference (scope, limit, require, deny, obligation, approval).
2. Route the agent's actions through the enforcement proxy
Evaluate every action before it executes by calling the proxy directly:
curl -X POST http://localhost:3001/v1/actions \
-H "Authorization: Bearer <agent-secret>" \
-H "Content-Type: application/json" \
-d '{
"action": {
"rail": "x402",
"amount": { "value": 500, "currency": "USD" },
"timestamp": "2026-07-06T00:00:00Z"
}
}'Or evaluate-and-forward in one call, so the request only reaches the upstream target if the policy approves it:
curl -X POST http://localhost:3001/v1/x402/forward \
-H "Authorization: Bearer <agent-secret>" \
-H "Content-Type: application/json" \
-d '{
"action": { "rail": "x402", "amount": { "value": 50, "currency": "USD" } },
"x402_request": {
"target": "external-llm-service",
"prompt": "Execute the wire transfer."
}
}'3. Wrap it once with the TypeScript SDK
The real @intaglio/sdk client wraps the same endpoints so existing agent code doesn't need to hand-roll the HTTP calls:
import { IntaglioClient } from "@intaglio/sdk";
const client = new IntaglioClient({
baseUrl: process.env.INTA_PROXY_URL ?? "http://localhost:3001",
agentToken: process.env.INTA_AGENT_SECRET!,
});
const result = await client.enforce({
type: "payment",
amount: 500,
currency: "USDC",
destination: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
});
if (result.decision.outcome === "DENY") {
throw new Error(`Blocked by policy: ${result.decision.reason ?? "no reason given"}`);
}
if (result.decision.outcome === "REQUIRE_APPROVAL") {
await client.getApproval(result.approval_id!); // poll until resolved
}
// outcome === "APPROVE" -> proceed with the real transfer4. Every decision is auditable, whatever the outcome
Each evaluation returns a record with a SHA-256 self_hash and a prev_record_hash pointer, so the full decision history for an agent forms a tamper-evident chain that can be anchored to Solana and exported for a regulator or auditor.
Start enforcing policy today
MiCA CASP enforcement is active as of July 1, 2026.