Skip to main content

Intents

Intents are declarative transaction requests that abstract away low-level blockchain details. The system validates, builds, and executes intents through a multi-stage pipeline.

Intent Structure

Every transaction begins as an intent:
interface TransactionRequest {
  walletId: string;            // UUID of wallet to execute from
  agentId?: string;            // Optional agent UUID
  type: TransactionType;       // Intent type (see below)
  protocol: string;            // Protocol adapter name
  gasless?: boolean;           // Use gasless transaction path
  idempotencyKey?: string;     // Deduplication key (8-128 chars)
  intent: Record<string, unknown>; // Type-specific payload
}

Supported Transaction Types

Agentic Wallet supports 26 transaction types:

Native Transfers

transfer_sol

Transfer native SOL between accounts.
{
  "type": "transfer_sol",
  "protocol": "system-program",
  "intent": {
    "destination": "9B5XszUGdMaxCZ7...",
    "lamports": 1000000000
  }
}

transfer_spl

Transfer SPL tokens.
{
  "type": "transfer_spl",
  "protocol": "spl-token",
  "intent": {
    "destination": "9B5XszUGdMaxCZ7...",
    "mint": "EPjFWdd5AufqSSqeM2qN1...",
    "amount": "1000000"
  }
}

DeFi Operations

swap

Token swaps via DEX aggregators.
{
  "type": "swap",
  "protocol": "jupiter",
  "intent": {
    "inputMint": "So11111111111111...",
    "outputMint": "EPjFWdd5AufqSSqeM...",
    "amount": "1000000",
    "slippageBps": 50
  }
}

stake / unstake

Staking operations (Marinade, etc).
{
  "type": "stake",
  "protocol": "marinade",
  "intent": {
    "amount": "1000000000",
    "validator": "optional-validator-key"
  }
}

lend_supply / lend_borrow

Lending protocol operations.
{
  "type": "lend_supply",
  "protocol": "solend",
  "intent": {
    "mint": "EPjFWdd5AufqSSqeM...",
    "amount": "1000000",
    "marketAddress": "optional"
  }
}

Token Management

create_mint

Create a new SPL token mint.
{
  "type": "create_mint",
  "protocol": "spl-token",
  "intent": {
    "decimals": 9,
    "supply": "1000000000"
  }
}

mint_token

Mint tokens to an account.
{
  "type": "mint_token",
  "protocol": "spl-token",
  "intent": {
    "mint": "token-mint-address",
    "destination": "recipient-address",
    "amount": "1000000"
  }
}

Escrow Operations

create_escrow
intent
Create a new escrow with funds and conditions.
accept_escrow
intent
Accept an escrow as the counterparty.
release_escrow
intent
Release funds to the beneficiary.
refund_escrow
intent
Refund funds to the creator.
dispute_escrow
intent
Raise a dispute on an escrow.
resolve_dispute
intent
Resolve a disputed escrow.
create_milestone_escrow
intent
Create multi-milestone escrow.
release_milestone
intent
Release a specific milestone.

Read-Only Operations

query_balance

Query wallet balance (no signature).
{
  "type": "query_balance",
  "protocol": "system-program",
  "intent": {}
}

query_positions

Query DeFi positions (no signature).
{
  "type": "query_positions",
  "protocol": "system-program",
  "intent": {}
}
Read-only intents (query_*) skip signing and submission phases, confirming immediately after simulation.

Advanced Operations

x402_pay
intent
HTTP 402 payment protocol integration.
flash_loan_bundle
intent
Flash loan transaction bundle.
cpi_call
intent
Cross-Program Invocation.
custom_instruction_bundle
intent
Arbitrary instruction bundle.
treasury_allocate
intent
Treasury budget allocation.
treasury_rebalance
intent
Rebalance between agent budgets.
paper_trade
intent
Simulated trade for backtesting.

Intent Validation

Intents are validated through multiple layers:

1. Schema Validation

Zod schemas enforce type safety:
// packages/common/src/schemas/transaction.ts:14
export const transactionTypeSchema = z.enum([
  'transfer_sol',
  'transfer_spl',
  'swap',
  // ... all 26 types
]);

export const createTransactionRequestSchema = z.object({
  walletId: z.string().uuid(),
  agentId: z.string().uuid().optional(),
  type: transactionTypeSchema,
  protocol: z.string().min(1),
  gasless: z.boolean().default(false),
  idempotencyKey: z.string().min(8).max(128).optional(),
  intent: z.record(z.unknown()).optional(),
});

2. Protocol Compatibility

The protocol adapter registry validates that the protocol supports the intent type:
// services/protocol-adapters/src/registry.ts
const adapter = registry.get(protocol);
if (!adapter) {
  throw new Error(`Unknown protocol: ${protocol}`);
}

// Check if adapter supports the operation
if (type === 'swap' && !adapter.buildSwap) {
  throw new Error(`Protocol ${protocol} does not support swap`);
}

3. Policy Evaluation

Policies can block or require approval for intents:
const decision = await policyEngine.evaluate({
  walletId,
  type,
  protocol,
  destination,
  amountLamports,
  programIds,
  slippageBps,
});

if (decision.decision === 'deny') {
  return { status: 'failed', failedAt: 'policy', reasons: decision.reasons };
}

if (decision.decision === 'require_approval') {
  return { status: 'approval_gate', reasons: decision.reasons };
}

4. Agent Capability Check

If executed by an agent, the intent must be in the allowlist:
// services/agent-runtime/src/index.ts:170
if (!agent.allowedIntents.includes(request.type)) {
  return {
    status: 403,
    payload: { error: `Intent ${request.type} not permitted for this agent` }
  };
}

5. Budget Validation

Spend-capable intents check agent budgets:
const spendingTypes = new Set([
  'transfer_sol', 'transfer_spl', 'swap',
  'stake', 'unstake', 'lend_supply',
  // ...
]);

if (spendingTypes.has(request.type)) {
  const lamports = inferLamports(request.intent);
  const budgetResult = budgetStore.spend(agent.id, lamports);
  if (!budgetResult.ok) {
    return { status: 403, payload: { error: budgetResult.reason } };
  }
}

Legacy Adapter Behavior

The intent-runner CLI provides backward compatibility:
npm run intent-runner -- --intent '{...}'
Legacy transformations:
  1. Wallet ID lookup: fromWalletId (base58) → internal UUID
  2. Metadata preservation: chain, createdAt, reasoning stored in intent.legacy
  3. Type normalization:
    • transfertransfer_sol or transfer_spl (based on mint presence)
    • swapswap
    • create_mintcreate_mint
    • mint_tokenmint_token
Legacy adapter behavior is documented in SKILLS.md:60 for orchestrator compatibility.

Idempotency

Use idempotencyKey to prevent duplicate transactions:
{
  "walletId": "...",
  "type": "transfer_sol",
  "protocol": "system-program",
  "idempotencyKey": "user-payment-12345",
  "intent": {...}
}
Behavior:
  • First request: Creates new transaction
  • Duplicate key: Returns existing transaction record
  • Key scope: Per wallet
  • Key length: 8-128 characters

Gasless Transactions

Set gasless: true to route through sponsored RPC:
{
  "type": "swap",
  "protocol": "jupiter",
  "gasless": true,
  "intent": {...}
}
Requirements:
  1. Protocol must have gaslessEligible: true in risk config
  2. KORA_RPC_URL must be configured
  3. Transaction must meet size/complexity limits
Not all protocols support gasless transactions. Check protocol risk configuration before enabling.

Paper Trading

Set paperOnly: true in intent to simulate without execution:
{
  "type": "swap",
  "protocol": "jupiter",
  "intent": {
    "inputMint": "...",
    "outputMint": "...",
    "amount": "1000000",
    "paperOnly": true
  }
}
Paper trades:
  • Skip signing and submission
  • Record to strategy store
  • Useful for backtesting and validation
  • No budget deduction

Best Practices

  1. Use specific intent types (not custom_instruction_bundle) when possible
  2. Include all required fields for protocol adapter
  3. Set reasonable slippage for swaps (50-200 bps typical)
  4. Use idempotency keys for user-facing operations
  5. Validate amounts before submission
  1. Check status and failedAt in response
  2. Handle approval_gate status for manual approval flow
  3. Retry on PIPELINE_ERROR with exponential backoff
  4. Never retry on POLICY_VIOLATION or VALIDATION_ERROR
  5. Monitor errorCode for categorization
  1. Validate destinations before transfers
  2. Use address allowlists for high-value operations
  3. Set spending limits via policies
  4. Audit flash_loan and cpi_call intents carefully
  5. Restrict custom_instruction_bundle to trusted agents

Source Code Reference

Intent handling is implemented in:
  • packages/common/src/schemas/transaction.ts - Intent type definitions (packages/common/src/schemas/transaction.ts:14)
  • services/transaction-engine/src/pipeline/* - Execution pipeline
  • services/protocol-adapters/src/index.ts - Protocol routing (services/protocol-adapters/src/index.ts:1)
  • SKILLS.md - Canonical intent contract (SKILLS.md:312)