Overview

Ankara Chain’s on-ramp/off-ramp support has two independent halves:
  1. A pluggable provider abstraction in the SDK (RampProvider interface + RampManager class) that orchestrates the off-chain side of a fiat↔token flow — quotes, KYC, and the actual payment/payout — against whichever provider you implement it for (Yellow Card, Flutterwave, Transak, etc.). The SDK ships only ManualRampProvider, a reference implementation for local development and testing.
  2. An optional on-chain settlement contract (RampSettlement) that gives the crypto side of a settlement a verifiable, auditable record. It’s entirely optional — RampManager works with just a provider if you don’t need on-chain proof of settlement.
This page covers both. See packages/sdk/src/core/RampManager.ts and packages/sdk/src/providers/ManualRampProvider.ts for the SDK source.

Why the on-chain half is optional

An on-ramp ends with the user holding tokens; an off-ramp starts with them holding tokens they want to cash out. Neither step strictly requires a smart contract — a backend can orchestrate the whole thing by calling the provider’s API and then minting/transferring tokens directly. What the on-chain half adds is a verifiable paper trail that a specific fiat settlement corresponds to a specific on-chain event, provable to a third party (an auditor, a dispute, a compliance review) without them having to trust your backend’s word for it. If you don’t need that, skip it — RampManager works fine with just a RampProvider.

RampSettlement

Deployed once per platform (or per market/currency, depending on your setup) via RampSettlementFactory. Handles the two directions very differently:

Off-ramp — real custody

A user converting tokens to fiat deposits them into the contract. Once the platform’s backend confirms (via the provider’s webhook) that the fiat payout succeeded, SETTLER_ROLE releases the custodied tokens to a configured treasury address. If the payout fails instead, MANAGER_ROLE can refund the original depositor.

On-ramp — attestation only, no custody

A user paying fiat to receive tokens does not deposit anything here. The actual mint is performed by the platform’s existing token contracts (MINTER_ROLE), which RampSettlement deliberately does not hold for arbitrary tokens — minting authority stays scoped to each token’s own factory-deployed contract, not a shared settlement contract. recordOnRampSettlement() just writes a verifiable, idempotent on-chain record tying a provider settlement reference to the recipient/token/amount that was minted, for audit purposes:

Status tracking

Every referenceId can only be used once per direction (ReferenceAlreadyUsed reverts on reuse) — it’s typically keccak256 of whatever session/reference ID your provider integration uses.

RampSettlementFactory

Deploys RampSettlement instances via ERC1967Proxy, following the same registration pattern as EscrowFactory — a single implementation slot, since there’s only one settlement contract type:
Deploy event:
Registry views: totalDeployedRampSettlements(), getDeployerRampSettlements(address). RampSettlement is registered as the 5th FactoryType (RAMP) in AnkaraFactoryRegistry, alongside ERC20, NFT, MULTI_TOKEN, and ESCROW.

SDK Integration

RampProvider — the off-chain half

Implement this interface against a real provider’s API for production. The SDK ships ManualRampProvider — a fully in-memory reference implementation for local development: quotes are computed from exchange rates you configure, and sessions only change status when you call markSettled()/markFailed() yourself, mirroring ManualOracle’s manually-driven design for the on-chain price-feed layer.
ManualRampProvider does no real payment processing and keeps session state only in memory for the lifetime of the process that created it — it’s for development and testing, not production traffic.

RampManager — the orchestrator

Pass an EVMAdapter and a deployed RampSettlement address to also enable the on-chain methods:
For an on-ramp, mint the recipient’s tokens through your existing TokenFactory/adapter calls once the provider confirms payment, then optionally record the attestation:
TokenFactory.deployRampSettlement() deploys a new settlement contract. See the CLI’s 8 ramp commands (starting with ankara deploy-ramp-settlement) for a fully interactive walkthrough, and the MCP server’s ramp tools for the same flow driven by an AI assistant.

Running the Ramp Tests Locally