Skip to main content

Protocols

Protocol adapters abstract blockchain interactions into a unified interface. They handle quote generation, transaction building, and protocol-specific logic.

Protocol Adapter Interface

interface ProtocolAdapter {
  readonly name: string;              // Protocol identifier
  readonly version: string;           // Adapter version (semver)
  readonly programIds: string[];      // On-chain program addresses
  readonly capabilities: string[];    // Supported operations
  
  // Swap operations
  getSwapQuote?(params: SwapQuoteParams): Promise<SwapQuote>;
  buildSwap?(params: SwapExecuteParams): Promise<BuildResult>;
  
  // Staking operations
  buildStake?(params: StakeParams): Promise<BuildResult>;
  buildUnstake?(params: StakeParams): Promise<BuildResult>;
  
  // Lending operations
  buildSupply?(params: LendingParams): Promise<BuildResult>;
  buildBorrow?(params: LendingParams): Promise<BuildResult>;
  
  // Generic intent builder
  buildIntent?(
    intentType: string,
    walletAddress: string,
    intent: Record<string, unknown>
  ): Promise<BuildResult>;
  
  // Intent migration
  migrateIntent?(
    input: MigrationInput
  ): Promise<Record<string, unknown>>;
  
  // Health check
  healthCheck?(): Promise<AdapterHealth>;
}

Supported Protocols

Agentic Wallet includes adapters for 9 protocols:

System Program

Native SOL transfers
  • transfer_sol
  • Program ID: 11111111111111111111111111111111

SPL Token

Token operations
  • transfer_spl
  • create_mint
  • mint_token
  • Program ID: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA

Jupiter

DEX aggregator
  • swap (quote + build)
  • Version: 1.0.0
  • API: https://lite-api.jup.ag/swap/v1

Marinade

Liquid staking
  • stake
  • unstake
  • Capabilities: stake, unstake

Solend

Lending protocol
  • lend_supply
  • lend_borrow
  • Fail-closed quotes

Metaplex

NFT operations
  • NFT minting
  • Metadata creation

Orca

DEX and liquidity
  • swap
  • Whirlpools support

Raydium

AMM and farms
  • swap
  • Pool interactions

Escrow

Custom escrow program
  • create_escrow
  • accept_escrow
  • release_escrow
  • refund_escrow
  • dispute_escrow
  • resolve_dispute
Solend, Orca, and Raydium adapters now fail closed instead of returning synthetic quotes. This prevents execution if external APIs are unavailable.

Protocol Registry

The AdapterRegistry manages protocol lifecycle:
// services/protocol-adapters/src/registry.ts
class AdapterRegistry {
  private readonly adapters = new Map<string, ProtocolAdapter>();
  
  register(adapter: ProtocolAdapter): void;
  get(name: string): ProtocolAdapter | null;
  list(): ProtocolAdapter[];
  
  registerMigration(protocol: string, migration: AdapterMigration): void;
  checkCompatibility(protocol: string, targetVersion: string): CompatibilityResult;
  migrateIntent(protocol: string, input: MigrationInput): Promise<MigratedIntent>;
}

Listing Protocols

npm run cli -- protocol list
Response:
{
  "data": [
    {
      "protocol": "jupiter",
      "version": "1.0.0",
      "capabilities": ["swap", "getQuote"],
      "programIds": [
        "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"
      ]
    },
    {
      "protocol": "marinade",
      "version": "1.0.0",
      "capabilities": ["stake", "unstake"],
      "programIds": [
        "MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD"
      ]
    }
  ]
}

Protocol Capabilities

Query specific protocol capabilities:
npm run cli -- protocol caps jupiter
Response:
{
  "data": {
    "protocol": "jupiter",
    "version": "1.0.0",
    "capabilities": ["swap", "getQuote"],
    "programIds": [
      "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"
    ]
  }
}

Quote/Build Flow

Protocol adapters follow a two-phase pattern:

1. Quote Phase (Read-Only)

Generate a quote without executing:
interface SwapQuoteParams {
  inputMint: string;
  outputMint: string;
  amount: string;
  slippageBps?: number;
  walletAddress: string;
}

interface SwapQuote {
  inputMint: string;
  outputMint: string;
  inputAmount: string;
  outputAmount: string;
  priceImpactPct: number;
  fee: string;
  route: unknown;
}
Example:
npm run cli -- protocol quote \
  --protocol jupiter \
  --input-mint So11111111111111111111111111111111111111112 \
  --output-mint EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v \
  --amount 1000000000 \
  --wallet 9B5XszUGdMaxCZ7uSQhPzdks5ZQSmWxrmzCSvtJ6Ns6g

2. Build Phase (Transaction Construction)

Convert quote into executable transaction:
interface BuildResult {
  mode: 'transaction' | 'instructions';
  transaction?: string;              // Base64 serialized transaction
  instructions?: SerializedInstruction[]; // Individual instructions
  programIds: string[];              // Programs invoked
  metadata?: Record<string, unknown>; // Protocol-specific data
}
Example flow:
// services/protocol-adapters/src/index.ts:88
if (type === 'swap' && adapter.getSwapQuote && adapter.buildSwap) {
  // Phase 1: Get quote
  const quote = await adapter.getSwapQuote({
    inputMint: intent['inputMint'],
    outputMint: intent['outputMint'],
    amount: intent['amount'],
    slippageBps: intent['slippageBps'] ?? 50,
    walletAddress,
  });
  
  // Phase 2: Build transaction
  return adapter.buildSwap({ walletAddress, quote });
}

Protocol-Specific Operations

Jupiter Swaps

npm run cli -- protocol swap \
  --protocol jupiter \
  --input-mint So11111111111111111111111111111111111111112 \
  --output-mint EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v \
  --amount 1000000000 \
  --wallet 9B5XszUGdMaxCZ7uSQhPzdks5ZQSmWxrmzCSvtJ6Ns6g \
  --slippage-bps 50

Marinade Staking

npm run cli -- protocol stake \
  --protocol marinade \
  --wallet 9B5XszUGdMaxCZ7uSQhPzdks5ZQSmWxrmzCSvtJ6Ns6g \
  --amount 1000000000

Solend Lending

npm run cli -- protocol lend-supply \
  --protocol solend \
  --wallet 9B5XszUGdMaxCZ7uSQhPzdks5ZQSmWxrmzCSvtJ6Ns6g \
  --mint EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v \
  --amount 1000000

Escrow Operations

npm run cli -- protocol escrow-create \
  --wallet 9B5XszUGdMaxCZ7uSQhPzdks5ZQSmWxrmzCSvtJ6Ns6g \
  --intent '{"amount":1000000000,"recipient":"..."}'
The escrow adapter requires a deployed escrow program. Set ESCROW_PROGRAM_ID in your environment. This repository does not ship a pre-deployed program artifact.

Protocol Health Checks

Adapters can implement health checks:
interface AdapterHealth {
  ok: boolean;
  details?: Record<string, unknown>;
}

Checking Health

curl http://localhost:3000/api/v1/protocols/health
Response:
{
  "data": {
    "ok": true,
    "checks": [
      {
        "protocol": "jupiter",
        "version": "1.0.0",
        "ok": true,
        "details": { "mode": "api", "endpoint": "https://lite-api.jup.ag" }
      },
      {
        "protocol": "marinade",
        "version": "1.0.0",
        "ok": true,
        "details": { "mode": "static" }
      }
    ]
  }
}

Protocol Versioning

Adapters use semantic versioning. Check compatibility:
curl -X POST http://localhost:3000/api/v1/protocols/jupiter/compatibility-check \
  -H "Content-Type: application/json" \
  -d '{"targetVersion":"2.0.0"}'
Response:
{
  "data": {
    "compatible": false,
    "currentVersion": "1.0.0",
    "reason": "Major version mismatch 1.0.0 -> 2.0.0"
  }
}
Compatibility rules:
  • Same major version: Compatible
  • Different major version: Incompatible (breaking changes)

Intent Migration

Migrate intents between adapter versions:
interface AdapterMigration {
  fromVersion: string;
  toVersion: string;
  migrate: (type: string, intent: Record<string, unknown>) => Record<string, unknown>;
}
Example migration:
// services/protocol-adapters/src/index.ts:65
registry.registerMigration('jupiter', {
  fromVersion: '0.9.0',
  toVersion: '1.0.0',
  migrate: (_type, intent) => ({
    ...intent,
    ...(intent['maxSlippageBps'] === undefined && intent['slippageBps'] !== undefined
      ? { maxSlippageBps: intent['slippageBps'] }
      : {}),
  }),
});

Migrating Intents

curl -X POST http://localhost:3000/api/v1/protocols/jupiter/migrate-intent \
  -H "Content-Type: application/json" \
  -d '{
    "fromVersion": "0.9.0",
    "toVersion": "1.0.0",
    "type": "swap",
    "intent": {
      "inputMint": "...",
      "outputMint": "...",
      "amount": "1000000",
      "slippageBps": 50
    }
  }'
Response:
{
  "data": {
    "intent": {
      "inputMint": "...",
      "outputMint": "...",
      "amount": "1000000",
      "slippageBps": 50,
      "maxSlippageBps": 50
    },
    "migrationApplied": true
  }
}

Generic Build Endpoint

Build transactions for any protocol/intent combination:
curl -X POST http://localhost:3000/api/v1/build \
  -H "Content-Type: application/json" \
  -d '{
    "protocol": "jupiter",
    "type": "swap",
    "walletAddress": "9B5XszUGdMaxCZ7uSQhPzdks5ZQSmWxrmzCSvtJ6Ns6g",
    "intent": {
      "inputMint": "So11111111111111111111111111111111111111112",
      "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "amount": "1000000000",
      "slippageBps": 50
    }
  }'

Configuration

# Jupiter API endpoint
JUPITER_API_URL=https://lite-api.jup.ag/swap/v1

# Escrow program
ESCROW_PROGRAM_ID=YourEscrowProgramIdHere

# Protocol service
PORT=3005

Best Practices

  1. Use jupiter for best swap prices (aggregates multiple DEXes)
  2. Use marinade for liquid staking (mSOL receipt tokens)
  3. Check protocol health before execution
  4. Implement fallback protocols for critical paths
  5. Monitor adapter version updates
  1. Always fetch fresh quotes (quotes expire quickly)
  2. Validate slippage before execution
  3. Check priceImpactPct for large trades
  4. Handle quote failures gracefully (fail-closed)
  5. Don’t cache quotes across requests
  1. DEX adapters may fail if external APIs are down
  2. Implement retries for transient failures
  3. Check AdapterHealth before submission
  4. Validate programIds match expected values
  5. Monitor adapter error rates
  1. Validate program IDs returned in BuildResult
  2. Use protocol allowlists in policies
  3. Set per-protocol risk rules
  4. Audit adapter code before production use
  5. Monitor for unexpected protocol behavior

Source Code Reference

Protocol adapter functionality is implemented in:
  • services/protocol-adapters/src/index.ts - Main service (services/protocol-adapters/src/index.ts:1)
  • services/protocol-adapters/src/registry.ts - Adapter registry (services/protocol-adapters/src/registry.ts:1)
  • services/protocol-adapters/src/adapters/adapter.interface.ts - Interface definitions (services/protocol-adapters/src/adapters/adapter.interface.ts:1)
  • services/protocol-adapters/src/adapters/jupiter.adapter.ts - Jupiter implementation (services/protocol-adapters/src/adapters/jupiter.adapter.ts:1)
  • services/protocol-adapters/src/adapters/escrow.adapter.ts - Escrow implementation (services/protocol-adapters/src/adapters/escrow.adapter.ts:1)

Build docs developers (and LLMs) love