Fiat Onramp (Moonpay + Onramp.money)
Publisher. Part of the OpenFinance skill bundle (openfin-setup, openfin-troubleshooting, openfin-hyperliquid, openfin-relay, openfin-onramp, openfin-polymarket, openfin-onchain) — all maintained by OpenFinance (https://openfinance.tech). Install as a set, not individually.
Two providers, one smart-router endpoint:
| Provider |
Rails |
Best for |
baseCurrency |
| Moonpay |
Cards, Apple Pay, Google Pay, SEPA, bank |
Global / non-INR |
usd, eur, gbp, … |
| Onramp.money |
UPI, IMPS, bank |
India / INR |
inr (only) |
The agent never signs on-chain — the user opens the returned URL to
finish KYC + payment.
Prerequisite
openfin-setup complete.
- The destination chain's wallet is provisioned for the user (EVM
default; Solana must be enabled if
chain=solana /
currencyCode=*_sol).
Endpoints
POST /agent/onramp — smart router (default)
baseCurrency: "inr" → Onramp.money. Anything else (or omitted →
defaults usd) → Moonpay. Body is the union of fields; the router
forwards only the relevant ones.
| Field |
Notes |
baseCurrency |
Routing key, lowercased. Default "usd". |
chain |
ethereum / polygon / base / arbitrum / optimism / bsc / tron / solana. (Onramp.money supports a subset — see matrix.) |
currency |
Crypto symbol (usdc, usdt, eth, sol, btc, …). |
amount |
Fiat amount the user will spend. |
walletAddress |
Optional; defaults to caller's wallet for the chain. |
redirectURL |
Provider redirects here on success. |
Response: { provider: "moonpay" | "onrampmoney", url: "https://…" }.
Common Moonpay currencyCode derivations (when the smart router picks
Moonpay from chain + currency): eth/usdc on Ethereum →
eth/usdc; usdc on Polygon/Base/Arbitrum/Optimism → usdc_polygon
/ usdc_base / usdc_arbitrum / usdc_optimism; Solana sol →
sol, Solana usdc → usdc_sol. If unsure, the smart router accepts
currencyCode directly and forwards it.
The Moonpay-only / Onramp.money-only REST routes
(POST /agent/onramp/moonpay, POST /agent/onramp/onrampmoney) still
exist for dashboards and direct API consumers, but they are not
exposed as MCP actions — agents should always use the smart router so
baseCurrency: "inr" lands on Onramp.money correctly. Force-provider
fields below are documented for completeness (REST callers only).
POST /agent/onramp/onrampmoney — REST-only (dashboards)
| Field |
Notes |
chain |
ethereum / polygon / bsc / tron / solana. Mapped to legacy network code. |
network |
Legacy code (erc20 / matic20 / bep20 / trc20 / spl); overrides chain mapping. |
currency / coinCode |
Coin (usdc, usdt, busd, matic, bnb, eth, sol). |
amount |
INR (e.g. 1000 = ₹1000). |
coinAmount |
Crypto-side target — wins over amount if both sent. |
paymentMethod |
1 = UPI/Instant (default in India), 2 = IMPS/Bank. Skip to let user choose. |
walletAddress, redirectURL, addressTag |
Optional. |
Chain → Onramp network: ethereum→erc20, polygon→matic20,
bsc→bep20, tron→trc20, solana→spl.
Onramp.money supported (coin × network) matrix
Calls outside this matrix throw. Propose a supported pair or switch to
Moonpay.
| Coin |
Networks |
usdt |
bep20, matic20, erc20, trc20 |
usdc |
bep20, matic20 (NOT erc20 / solana) |
busd |
bep20 |
matic |
matic20 |
bnb |
bep20 |
eth |
erc20, matic20 |
sol |
spl |
Near-misses to remap on the fly:
- "USDC with INR on Ethereum" → propose Polygon (or Moonpay).
- "USDC with INR on Solana" → propose Polygon / BSC (or Moonpay).
- "ETH with INR on Arbitrum / Base / Optimism" → onramp on Eth/Polygon
and bridge via
openfin-relay, or use Moonpay.
Wallet defaults
If walletAddress is omitted: EVM chain → caller's EVM address;
chain=solana or currencyCode=*_sol → caller's Solana address.
Missing wallet → request fails; send the user to openfinance.tech.
Pair with other skills
- Onramp lands on chain X, user wants to trade on chain Y → bridge via
openfin-relay.
- USDC on Arbitrum → Hyperliquid → use
GET /agent/trading/deposit-address.
Hyperliquid takes only USDC (not USDT, not USDC.e).
- INR → Hyperliquid: Onramp.money INR → USDC on Polygon or BSC →
openfin-relay to Arbitrum → Hyperliquid deposit address.
- USDC on Polygon → Polymarket → swap to pUSD and route to the
deposit wallet (
GET /agent/polymarket/deposit-wallet).
Examples
USD → USDC on Base (Moonpay):
POST /agent/onramp
{ "chain": "base", "currency": "usdc", "amount": 100, "baseCurrency": "usd" }
→ { "provider": "moonpay", "url": "https://buy.moonpay.com/?…" }
INR → USDC on Polygon via UPI (Onramp.money):
POST /agent/onramp
{ "baseCurrency": "inr", "chain": "polygon", "currency": "usdc",
"amount": 5000, "paymentMethod": 1 }
→ { "provider": "onrampmoney", "url": "https://onramp.money/app/?…" }
Don't
- Don't use Onramp.money for non-INR fiats — INR-only.
- Don't ignore the (coin × network) matrix — propose a supported pair
instead of retrying.
- Don't ask for card / UPI details — the provider collects them in
their own KYC UI.
- Don't poll for onramp status — the provider emits funds directly to
the wallet. Verify on-chain via
openfin-onchain (/balances).
MCP
Single tool: get_onramp_url (smart router). Same body as
POST /agent/onramp; returns { provider, url, … }. The
force-provider routes are REST-only — there is no
get_moonpay_onramp_url or get_onrampmoney_onramp_url MCP action,
so every onramp call goes through the smart router. INR triggers
("buy USDT with INR", "deposit ₹1000", "get USDC with UPI") route
to Onramp.money automatically.
1---2name: openfin-onramp3description: Fiat → crypto onramp through OpenFinance. Smart-routed across **Moonpay** (cards / Apple Pay / Google Pay / SEPA / bank — global, non-INR) and **Onramp.money** (UPI / IMPS — INR only). Default to POST /agent/onramp (smart router; `baseCurrency:"inr"` → Onramp.money, anything else → Moonpay). Use POST /agent/onramp/moonpay or /onrampmoney to force a provider. Triggers — "buy USDC with my card", "Apple Pay", "deposit fiat", "fund my wallet", "I have no crypto, how do I start", "buy ETH on Base with USD"; INR triggers — "buy USDC with INR", "deposit ₹1000", "top up with UPI / IMPS", "India onramp". The agent never signs an on-chain tx — user opens the returned URL to complete KYC + payment in the provider's UI; funds land in the user's OpenFinance-managed wallet for the chosen chain. Onramp.money has a **fixed (coin × network) matrix** (usdt:bep20|matic20|erc20|trc20, usdc:bep20|matic20 ONLY, busd:bep20, matic:matic20, bnb:bep20, eth:erc20|matic20, sol:spl); calls outside it throw — propose a supported pair inst4license: Proprietary5---67# Fiat Onramp (Moonpay + Onramp.money)89> **Publisher.** Part of the OpenFinance skill bundle (openfin-setup, openfin-troubleshooting, openfin-hyperliquid, openfin-relay, openfin-onramp, openfin-polymarket, openfin-onchain) — all maintained by OpenFinance (https://openfinance.tech). Install as a set, not individually.1011Two providers, one smart-router endpoint:1213| Provider | Rails | Best for | `baseCurrency` |14|---|---|---|---|15| **Moonpay** | Cards, Apple Pay, Google Pay, SEPA, bank | Global / non-INR | `usd`, `eur`, `gbp`, … |16| **Onramp.money** | UPI, IMPS, bank | India / INR | `inr` (only) |1718The agent never signs on-chain — the user opens the returned URL to19finish KYC + payment.2021## Prerequisite22231. `openfin-setup` complete.242. The destination chain's wallet is provisioned for the user (EVM25 default; Solana must be enabled if `chain=solana` /26 `currencyCode=*_sol`).2728## Endpoints2930### `POST /agent/onramp` — smart router (default)3132`baseCurrency: "inr"` → Onramp.money. Anything else (or omitted →33defaults `usd`) → Moonpay. Body is the union of fields; the router34forwards only the relevant ones.3536| Field | Notes |37|---|---|38| `baseCurrency` | **Routing key**, lowercased. Default `"usd"`. |39| `chain` | `ethereum` / `polygon` / `base` / `arbitrum` / `optimism` / `bsc` / `tron` / `solana`. (Onramp.money supports a subset — see matrix.) |40| `currency` | Crypto symbol (`usdc`, `usdt`, `eth`, `sol`, `btc`, …). |41| `amount` | Fiat amount the user will spend. |42| `walletAddress` | Optional; defaults to caller's wallet for the chain. |43| `redirectURL` | Provider redirects here on success. |4445Response: `{ provider: "moonpay" | "onrampmoney", url: "https://…" }`.4647Common Moonpay `currencyCode` derivations (when the smart router picks48Moonpay from `chain` + `currency`): `eth`/`usdc` on Ethereum →49`eth`/`usdc`; `usdc` on Polygon/Base/Arbitrum/Optimism → `usdc_polygon`50/ `usdc_base` / `usdc_arbitrum` / `usdc_optimism`; Solana `sol` →51`sol`, Solana `usdc` → `usdc_sol`. If unsure, the smart router accepts52`currencyCode` directly and forwards it.5354The Moonpay-only / Onramp.money-only REST routes55(`POST /agent/onramp/moonpay`, `POST /agent/onramp/onrampmoney`) still56exist for dashboards and direct API consumers, but they are **not57exposed as MCP actions** — agents should always use the smart router so58`baseCurrency: "inr"` lands on Onramp.money correctly. Force-provider59fields below are documented for completeness (REST callers only).6061### `POST /agent/onramp/onrampmoney` — REST-only (dashboards)6263| Field | Notes |64|---|---|65| `chain` | `ethereum` / `polygon` / `bsc` / `tron` / `solana`. Mapped to legacy `network` code. |66| `network` | Legacy code (`erc20` / `matic20` / `bep20` / `trc20` / `spl`); overrides `chain` mapping. |67| `currency` / `coinCode` | Coin (`usdc`, `usdt`, `busd`, `matic`, `bnb`, `eth`, `sol`). |68| `amount` | INR (e.g. `1000` = ₹1000). |69| `coinAmount` | Crypto-side target — wins over `amount` if both sent. |70| `paymentMethod` | `1` = UPI/Instant (default in India), `2` = IMPS/Bank. Skip to let user choose. |71| `walletAddress`, `redirectURL`, `addressTag` | Optional. |7273Chain → Onramp `network`: `ethereum→erc20`, `polygon→matic20`,74`bsc→bep20`, `tron→trc20`, `solana→spl`.7576## Onramp.money supported (coin × network) matrix7778Calls outside this matrix throw. Propose a supported pair or switch to79Moonpay.8081| Coin | Networks |82|---|---|83| `usdt` | `bep20`, `matic20`, `erc20`, `trc20` |84| `usdc` | `bep20`, `matic20` (NOT `erc20` / `solana`) |85| `busd` | `bep20` |86| `matic` | `matic20` |87| `bnb` | `bep20` |88| `eth` | `erc20`, `matic20` |89| `sol` | `spl` |9091Near-misses to remap on the fly:9293- "USDC with INR on Ethereum" → propose Polygon (or Moonpay).94- "USDC with INR on Solana" → propose Polygon / BSC (or Moonpay).95- "ETH with INR on Arbitrum / Base / Optimism" → onramp on Eth/Polygon96 and bridge via `openfin-relay`, or use Moonpay.9798## Wallet defaults99100If `walletAddress` is omitted: EVM `chain` → caller's EVM address;101`chain=solana` or `currencyCode=*_sol` → caller's Solana address.102Missing wallet → request fails; send the user to openfinance.tech.103104## Pair with other skills105106- Onramp lands on chain X, user wants to trade on chain Y → bridge via107 `openfin-relay`.108- USDC on Arbitrum → Hyperliquid → use `GET /agent/trading/deposit-address`.109 Hyperliquid takes **only USDC** (not USDT, not USDC.e).110- **INR → Hyperliquid**: Onramp.money INR → USDC on Polygon or BSC →111 `openfin-relay` to Arbitrum → Hyperliquid deposit address.112- USDC on Polygon → Polymarket → swap to pUSD and route to the113 deposit wallet (`GET /agent/polymarket/deposit-wallet`).114115## Examples116117USD → USDC on Base (Moonpay):118```json119POST /agent/onramp120{ "chain": "base", "currency": "usdc", "amount": 100, "baseCurrency": "usd" }121→ { "provider": "moonpay", "url": "https://buy.moonpay.com/?…" }122```123124INR → USDC on Polygon via UPI (Onramp.money):125```json126POST /agent/onramp127{ "baseCurrency": "inr", "chain": "polygon", "currency": "usdc",128 "amount": 5000, "paymentMethod": 1 }129→ { "provider": "onrampmoney", "url": "https://onramp.money/app/?…" }130```131132## Don't133134- Don't use Onramp.money for non-INR fiats — INR-only.135- Don't ignore the (coin × network) matrix — propose a supported pair136 instead of retrying.137- Don't ask for card / UPI details — the provider collects them in138 their own KYC UI.139- Don't poll for onramp status — the provider emits funds directly to140 the wallet. Verify on-chain via `openfin-onchain` (`/balances`).141142## MCP143144Single tool: `get_onramp_url` (smart router). Same body as145`POST /agent/onramp`; returns `{ provider, url, … }`. The146force-provider routes are REST-only — there is no147`get_moonpay_onramp_url` or `get_onrampmoney_onramp_url` MCP action,148so every onramp call goes through the smart router. INR triggers149("buy USDT with INR", "deposit ₹1000", "get USDC with UPI") route150to Onramp.money automatically.