Skip to content
How it worksDevelopersDocsProtocol

Documentation

Core concepts

The five ideas that make up Railo - and how they fit together into one rail.

Railo has a small surface area on purpose. Five concepts cover everything: agents, wallets, policies, the gate that enforces them, and the receipts that prove settlement.

Agents

An agent is an autonomous actor that can hold and spend money under rules it cannot change. In Railo terms, an agent is the pairing of a wallet and a policy. You create one with a single SDK call and address it by its on-chain handle.

Agents can pay services (service://…) and other agents (agent://…). That second case - agent-to-agent - is what lets one agent hire another and settle the bill on the same rail.

Wallets

Each agent owns a wallet: an on-chain account that holds stablecoin and signs payments. Unlike a human bank account, the wallet's spending authority is bounded by code. The agent controls the wallet day to day, but the owner's policy sets the outer edges of what it can ever do.

The owner vs. the agent
The owner key can change policy and fund the wallet. The agent can spend - but only inside the policy. An agent can never raise its own limits.

Spending policies

A policy is the rule set attached to a wallet, written on-chain. It is the heart of Railo: the thing that turns "please don't overspend" into "cannot overspend."

policy.ts
const agent = await railo.createAgent({
  // The owner sets the policy; the contract enforces it.
  policy: {
    dailyLimit: "50.00",     // USDC, rolling 24h
    perCall: "0.05",         // hard ceiling per payment
    allow: [
      "service://api.search",
      "service://api.embed",
    ],
  },
});

console.log(agent.address); // 0xAgent…  (the agent's on-chain wallet)

Limits & per-call caps

Two numeric controls bound spend over time and per action:

  • dailyLimit - total spend allowed in a rolling 24-hour window. When it's exhausted, payments revert until the window rolls forward.
  • perCall - the maximum value of any single payment. A call above this ceiling never settles, regardless of remaining daily budget.

Allowlists

The allow list names exactly which services (and agents) a wallet may pay. A payment to anything not on the list is rejected at the gate. Allowlists keep an agent narrow: even a compromised or confused agent can only ever pay destinations the owner pre-approved.

denied.ts
// A call that violates policy never settles - it reverts at the gate.
try {
  await agent.pay({ to: "service://api.unknown", amount: "0.02" });
} catch (err) {
  // RailoPolicyError: service not in allowlist
  console.error(err.code); // "policy/service_not_allowed"
}

The policy gate

The policy gate is the smart contract that sits between an agent's intent and the movement of money. Every payment passes through it. The gate checks each rule - allowlist, per-call cap, daily limit, owner signature - and only opens if all of them pass. A failing payment doesn't get flagged; it never settles.

policy gateenforced on-chain
pay($0.02 service://api.search)
  • service in allowlistservice://api.search
  • amount ≤ per-call cap$0.02 ≤ $0.05
  • within daily limit$12.40 / $50.00
  • signed by owner policypol_2u9X…
All rules pass → open the gatesettle()

Settlement & receipts

When the gate opens, stablecoin settles to the recipient in a fraction of a second, and the agent receives a receipt. The receipt is signed and on-chain - it records the amount, the recipient, the transaction, and the policy that authorized it. That link back to policy is what makes spend auditable: every payment can be traced to the exact rule that allowed it.

receipt.json
{
  "id": "rcpt_8fK2c9Qd",
  "agent": "0xAgent7d2…",
  "to": "service://api.search",
  "amount": "0.02",
  "currency": "USDC",
  "network": "solana",
  "policyId": "pol_2u9X…",
  "settled": true,
  "tx": "0x9b1f…c20a",
  "signature": "0xsig…",
  "createdAt": "2025-01-01T00:00:00Z"
}