StableCard API

Fund virtual Visa cards with USDC via EIP-3009 transferWithAuthorization. Real on-chain USDC pull + Lithic card issuance with atomic guarantees. Supports Base, Polygon, Optimism, Arbitrum.

Base URL: https://stablecard.polsia.app
GET /api/config Get supported chains & treasury address

Returns the current mode (live or mock), supported chains, treasury address, and EIP-712 type definitions for client-side signing.

curl https://stablecard.polsia.app/api/config

// Response
{
  "success": true,
  "config": {
    "mode": "live",
    "supported_chains": [
      { "id": "base", "chain_id": 8453, "usdc_address": "0x833589..." },
      { "id": "polygon", "chain_id": 137, ... },
      { "id": "optimism", "chain_id": 10, ... },
      { "id": "arbitrum", "chain_id": 42161, ... }
    ],
    "treasury_address": "0xYourTreasury..."
  }
}
GET /api/signing-payload Get EIP-712 typed data for wallet signing

Query Params

ParamTypeDescription
amount number REQUIRED USDC amount to fund
wallet_address string REQUIRED Sender's wallet address
chain string optional Chain: base, polygon, optimism, arbitrum (default: base)

Returns a complete EIP-712 payload ready for eth_signTypedData_v4. Sign it, extract v/r/s, and send to POST /api/cards/fund.

curl "https://stablecard.polsia.app/api/signing-payload?amount=100&wallet_address=0x742d...&chain=base"

// Response includes pre-filled authorization_template
{
  "payload": { /* EIP-712 typed data */ },
  "authorization_template": {
    "from": "0x742d...",
    "to": "0xTreasury...",
    "value": "100000000",
    "nonce": "0xabc123..."
    // Add v, r, s after signing
  }
}
POST /api/cards/fund Fund a new virtual card with USDC (atomic)

Request Body

ParamTypeDescription
amount number REQUIRED USDC amount to fund (1-10,000)
wallet_address string REQUIRED EVM wallet address (0x...)
chain string optional Chain: base, polygon, optimism, arbitrum (default: "base")
label string optional Human-readable label for the card
authorization object live mode EIP-3009 signed authorization (from, to, value, validAfter, validBefore, nonce, v, r, s)

Atomic Flow (Live Mode)

When authorization is provided: verify EIP-3009 signature → check USDC balance → create Lithic card → submit on-chain tx. If card issuance fails, no on-chain tx. If on-chain tx fails, card is voided. Both succeed or neither executes.

Example (Live Mode)

// 1. Get signing payload
GET /api/signing-payload?amount=100&wallet_address=0x742d...

// 2. Sign with wallet (eth_signTypedData_v4)
// 3. Send to fund endpoint
curl -X POST https://stablecard.polsia.app/api/cards/fund \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 100,
    "wallet_address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
    "chain": "base",
    "authorization": {
      "from": "0x742d...",
      "to": "0xTreasury...",
      "value": "100000000",
      "validAfter": "0",
      "validBefore": "1742072400",
      "nonce": "0xabc...",
      "v": 28,
      "r": "0x...",
      "s": "0x..."
    }
  }'

// Response (201)
{
  "success": true,
  "mode": "live",
  "card": {
    "id": "sc_card_7x9k3m2p",
    "pan_masked": "**** **** **** 5678",
    "balance_usdc": 100,
    "status": "active"
  },
  "onchain": {
    "tx_hash": "0x8f2a...c41d",
    "block_number": 28456123,
    "chain": "Base",
    "chain_id": 8453
  }
}

Mock Mode (No authorization)

// Without authorization → mock mode (backward compatible)
curl -X POST https://stablecard.polsia.app/api/cards/fund \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 50,
    "wallet_address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
  }'
GET /api/cards/:id Get card details (optionally reveal PAN/CVV)

Query Params

ParamTypeDescription
reveal string optional Set to "true" to reveal full PAN and CVV

Example

// Reveal card details for agent
curl https://stablecard.polsia.app/api/cards/sc_card_7x9k3m2p?reveal=true

// Response
{
  "success": true,
  "card": {
    "id": "sc_card_7x9k3m2p",
    "pan": "4242 8888 1234 5678",
    "cvv": "492",
    "exp": "03/28",
    "balance_usdc": 50,
    "status": "active",
    ...
  },
  "transactions": [...]
}
GET /api/cards List all cards (optional filters)

Query Params

ParamTypeDescription
wallet_address string optional Filter by wallet address
status string optional Filter by status: active, frozen, closed

Example

curl https://stablecard.polsia.app/api/cards?status=active

// Response
{
  "success": true,
  "count": 3,
  "cards": [
    { "id": "sc_card_7x9k3m2p", "balance_usdc": 50, ... },
    ...
  ]
}
POST /api/cards/:id/spend Simulate a card spend (for testing)

Request Body

ParamTypeDescription
amount number REQUIRED Amount to spend (must not exceed balance)
description string optional Description of the purchase
POST /api/cards/:id/freeze Freeze an active card

Temporarily disables the card. No request body needed.

POST /api/cards/:id/unfreeze Unfreeze a frozen card

Reactivates a frozen card. No request body needed.

POST /api/cards/:id/close Close a card and refund remaining balance

Permanently closes the card. Any remaining USDC balance is automatically refunded to the original wallet. No request body needed.

MCP Server Config

Add this to your Claude Desktop / Cursor / MCP client config to let your AI agent create and read cards:

{
  "mcpServers": {
    "stablecard": {
      "url": "https://stablecard.polsia.app/mcp"
    }
  }
}

Once connected, your agent can use these tools:

ToolDescription
fund_cardCreate a new virtual card funded with USDC
get_cardGet card details including PAN/CVV for purchases
list_cardsList all cards with balances and statuses
freeze_cardFreeze a card to prevent spending
close_cardClose a card and refund remaining balance