openfin-onramp
Fiat Onramp (Moonpay)
The user can buy crypto with a card / bank / Apple Pay / Google Pay through Moonpay. The OpenFinance backend builds a prefilled Moonpay buy URL — the user opens it to complete KYC and payment. Funds land in the user's OpenFinance-managed wallet for the chosen chain.
The agent never signs an on-chain tx for this. Onramp lives entirely in Moonpay's flow.
Prerequisite
- User completed
openfin-setup(API key in place —open_…). - User's wallet is provisioned for the destination chain (EVM is
default; Solana wallet must be enabled if
chain=solana/currencyCode=*_sol).
Endpoint
POST /agent/onramp/moonpay
Builds a (HMAC-signed if backend has the secret) Moonpay simple URL with chain, currency, wallet address, and fiat amount baked in.
Body
| Field | Type | Notes |
|---|---|---|
chain |
string | One of ethereum / polygon / base / arbitrum / optimism / bsc / solana. Combined with currency to derive currencyCode. |
currency |
string | Crypto symbol (usdc, eth, sol, btc, …). Combined with chain. |
currencyCode |
string | Direct Moonpay code (e.g. usdc_polygon). Overrides chain + currency derivation. |
amount |
number | Fiat amount the user will spend |
baseCurrency |
string | ISO-4217 fiat code, lowercased. Defaults to usd. |
walletAddress |
string | Optional — defaults to the caller's wallet for the chain (EVM by default; Solana when chain=solana / currencyCode ends _sol) |
redirectURL, email, externalCustomerId, theme, colorCode |
string | Optional pass-through |
Response
{ "url": "https://buy.moonpay.com/?...&signature=..." }
The agent should hand the URL back to the user (or open it in the
client). Once Moonpay clears the buy, funds arrive at walletAddress
on the chosen chain. There's nothing else for the agent to do — no
status polling.
Wallet defaults
If walletAddress is omitted:
chainis EVM (ethereum,polygon,base,arbitrum,optimism,bsc) → uses the caller's EVM addresschain=solanaorcurrencyCodeends in_sol→ uses the caller's Solana address- If the required wallet isn't provisioned, the request fails fast — surface the error and send the user back to openfinance.tech to enable that chain.
Use GET /agent/wallets (see openfin-setup) if the agent wants to
display the receiving address before opening the URL.
Currency code rules of thumb
If the agent passes chain + currency, the backend derives
currencyCode. Common pairs Moonpay supports:
| chain | currency | derived currencyCode |
|---|---|---|
ethereum |
eth |
eth |
ethereum |
usdc |
usdc |
polygon |
usdc |
usdc_polygon |
base |
usdc |
usdc_base |
arbitrum |
usdc |
usdc_arbitrum |
optimism |
usdc |
usdc_optimism |
solana |
sol |
sol |
solana |
usdc |
usdc_sol |
If unsure, pass currencyCode directly with the exact Moonpay code.
Pair with other skills
- After onramp lands on chain X but the user wants to trade on chain
Y — use
openfin-relayto bridge. - After onramp lands as USDC on Arbitrum and user wants to trade on
Hyperliquid —
GET /agent/trading/deposit-address, send USDC there (no bridge needed). - After onramp lands as USDC on Polygon and user wants to trade on
Polymarket — confirm the token is USDC.e (not native USDC) before
trading; otherwise use
openfin-relayto swap on-Polygon.
Example
User: "Buy $100 of USDC on Base with my card."
POST /agent/onramp/moonpay
x-api-key: open_…
Content-Type: application/json
{
"chain": "base",
"currency": "usdc",
"amount": 100,
"baseCurrency": "usd"
}
Response:
{ "url": "https://buy.moonpay.com/?currencyCode=usdc_base&walletAddress=0x…&baseCurrencyAmount=100&baseCurrencyCode=usd&signature=…" }
Agent surfaces the URL: "Open this Moonpay link to complete the purchase: . USDC will land at your Base wallet (0x…) once cleared."
Don't
- Don't ask the user for credit-card details. Moonpay collects them in their own KYC-compliant UI; the OpenFinance backend never sees them.
- Don't treat the returned URL as authenticated to the user. It's prefilled but the actual KYC + payment happen on Moonpay.
- Don't poll the backend for onramp status. Moonpay handles the buy
and emits funds to the wallet directly. To verify funds arrived,
read on-chain via
openfin-onchain(/balances) or the chain's block explorer.
MCP note
get_moonpay_onramp_url — same body, returns { url }.
More from openfinance-tech/skills
openfin-relay
Cross-chain bridging, swapping, and "bridge+call" via Relay through the OpenFinance backend. Use whenever the user wants to move tokens between chains or execute a destination-chain transaction funded from another chain. Triggers: "bridge X from Y to Z", "move my USDC to Base / Arbitrum / Optimism / Polygon / Solana", "swap ETH for USDC on Base", "cross-chain swap", "bridge and call", "how do I get to Solana / back from Solana", "my USDC is stuck on Solana", EVM-to-EVM, EVM-to-Solana, Solana-to-EVM, Bitcoin bridge, gas topup on destination, native-token sentinel 0x0, relay quote/preview/execute flow, poll intent status. Covers POST /agent/relay/quote, POST /agent/relay/execute, GET /agent/relay/status. Includes the chainId cheatsheet (1/137/8453/10/42161/... and Solana 792703809 specifically), tradeType semantics (EXACT_INPUT / EXACT_OUTPUT / EXPECTED_OUTPUT), why topupGas is auto-disabled on Solana routes, and bridge+call payloads (txs array). Use together with openfin-setup (API key check) and openfin-troubleshooting (Blockhash not found, Custom:101, 412 setup-incomplete on Solana origin).
24openfin-polymarket
Complete Polymarket playbook covering research and trading on the world's largest prediction market. Use this for ANY Polymarket task. Deposit-wallet model (CRITICAL): Polymarket's CLOB rejects raw EOAs as makers, so each user has a deterministic per-EOA "deposit wallet" smart contract that holds pUSD, carries allowances, and is named as `funder`/`maker`/`signer` on signed orders (POLY_1271 / EIP-1271). pUSD sent directly to the EOA is stranded for trading until it reaches the deposit wallet. Always call `GET /agent/polymarket/deposit-wallet` to get the right address before quoting "where do I deposit", checking balance, or running position queries — and pass the deposit-wallet address (NOT the EOA) as `:address` for `/user/:address/*` lookups. Research triggers: finding events ("what's happening in politics", "show me election odds", "NBA finals odds", "BTC to 200k markets", "IPL / FIFA / UFC / F1 betting markets"), listing markets with filters, searching by keyword, reading orderbooks, mid prices, spreads, last trade prices, recent trades, open interest, volume, liquidity, and any user's positions/portfolio/PnL by address. Deposit triggers: "where do I deposit on Polymarket", "what's my Polymarket address", "send pUSD to Polymarket", "Polymarket deposit wallet", "is my deposit wallet deployed". Trading triggers: place a bet on YES or NO, buy/sell outcomes, limit orders (GTC/GTD), market orders (FOK/FAK), batch orders, cancel one/many/all orders, check and set on-chain pUSD and CTF approvals, neg-risk (multi-outcome) markets, tick size handling (0.01/0.001/0.0001), and builder-code attribution. Covers all routes under /agent/polymarket/* (events, markets, search, orderbook, price, prices, spread, last-trade-price, trades, market/:id/open-interest|volume|liquidity|trades, user/:address/positions|trades|portfolio|pnl, deposit-wallet, order, order/market, orders, order/:id, order/:id/scoring, approvals, builder/*). Use when the user mentions Polymarket, prediction markets, event betting, binary outcomes, probability markets, YES/NO tokens, conditional tokens, or politics/sports/crypto/culture odds. Prerequisite: openfin-setup for trading.
24openfin-setup
Auth check for the OpenFinance backend — confirms an API key is available before any other OpenFinance skill runs. Use FIRST whenever the user is about to call any /agent/* route (Polymarket, Hyperliquid, Relay), is hitting 401/412, or hasn't traded yet in this session. Triggers on "how do I get started", "API key is required", "Invalid API key", "401/412 from /agent/*", "set up OpenFinance", or any first call into a trading skill. Resolves the key from `OPENFINANCE_API_KEY` (or equivalent env / user-supplied value), confirms the format (`open_…`), verifies via GET /agent/wallets, and otherwise points the user to https://openfinance.tech to issue one.
23openfin-hyperliquid
>-
23openfin-troubleshooting
>-
23relay-bridging
Cross-chain bridging, swapping, and "bridge+call" via Relay through the OpenFinance backend. Use whenever the user wants to move tokens between chains or execute a destination-chain transaction funded from another chain. Triggers: "bridge X from Y to Z", "move my USDC to Base / Arbitrum / Optimism / Polygon / Solana", "swap ETH for USDC on Base", "cross-chain swap", "bridge and call", "how do I get to Solana / back from Solana", "my USDC is stuck on Solana", EVM-to-EVM, EVM-to-Solana, Solana-to-EVM, Bitcoin bridge, gas topup on destination, native-token sentinel 0x0, relay quote/preview/execute flow, poll intent status. Covers POST /agent/relay/quote, POST /agent/relay/execute, GET /agent/relay/status. Includes the chainId cheatsheet (1/137/8453/10/42161/... and Solana 792703809 specifically), tradeType semantics (EXACT_INPUT / EXACT_OUTPUT / EXPECTED_OUTPUT), why topupGas is auto-disabled on Solana routes, the Solana wallet delegation requirement for Solana-origin execute, and bridge+call payloads (txs array). Use together with openfinance-setup (Solana delegation) and openfinance-troubleshooting (Blockhash not found, Custom:101, 412 delegation).
6