io.github.armandocodecr/ramp-kit
LATAM fiat ramps on Stellar for AI agents: live quotes, sandbox orders, PIX/SPEI simulation, docs
Open source Open in the app JSON README (API)
About
LATAM fiat ramps on Stellar for AI agents: live quotes, sandbox orders, PIX/SPEI simulation, docs
Details
- Kind
- MCP servers
- Topic
- Developer tools
- Publisher
- armandocodecr
- Origin
- official
- Category
- ferramentas
- Transport
- local
- Version
- 0.1.9
- Last push
- 2026-08-21T21:28:42Z
- Repository state
- ativo
- Language
- TypeScript
- License
- MIT
- Added
- 2026-08-29 03:02:26
- Updated
- 2026-08-29 03:02:26
- Origin id
io.github.armandocodecr/ramp-kit
README
# LATAM Ramp Kit
[](https://github.com/armandocodecr/latam-ramp-kit/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/@ramp-kit/core)
[](https://www.npmjs.com/package/@ramp-kit/react)
[](https://www.npmjs.com/package/@ramp-kit/server)
[](https://www.npmjs.com/package/@ramp-kit/mcp)
[](https://registry.modelcontextprotocol.io/?search=io.github.armandocodecr/ramp-kit)
[](./LICENSE)
Drop-in SDK + React components to add fiat on/off-ramps to any app in Latin
America, built for the Stellar **Brazil Ramps and Regional Kits** sub-lane.
## Install
```bash
npm install @ramp-kit/core @ramp-kit/react # SDK + React widget
npm install @ramp-kit/server # production backend (optional)
```
For AI agents:
```bash
claude mcp add ramp-kit -- npx -y @ramp-kit/mcp # MCP server
npx skills add https://github.com/armandocodecr/latam-ramp-kit/tree/main/skills/ramp-kit # agent skill
```
**BRL in *and* out, proven on Stellar Testnet (Etherfuse sandbox):**
- **In:** 100 BRL entered via PIX and settled as 19.0097 USDC in a fresh
Stellar wallet — account creation sponsored by the provider, tokens
delivered via claimable balance, claimed with one kit helper.
[Settlement tx on Stellar Expert.](https://stellar.expert/explorer/testnet/tx/95b4e01c139330fecfa9861d8a88735eec29433cdd5d6e7a67b2aaada98e00f4)
- **Out:** 5 USDC sold back to BRL — the provider pre-built the burn
transaction, the kit's `signAndSubmit` signed and submitted it
([burn tx](https://stellar.expert/explorer/testnet/tx/5bfc0470735be2a629870747e52edf429b3727d001f3721ee77a87f11f76cb6f)),
and the PIX payout processed provider-side. The widget ships the full
Sell flow with in-widget signing and automatic `tx_too_late` recovery.
One provider interface, two direct backends plus **any SEP-compliant Stellar
anchor** (and a mock for instant dev):
| Provider | Rails | Networks | Role in the kit |
| --- | --- | --- | --- |
| [Etherfuse](https://docs.etherfuse.com) | **BRL (PIX)** + MXN (SPEI) | **Stellar** (native), Solana, Base, Polygon | Stellar-native settlement: automatic trustlines, sponsored onboarding via claimable balances |
| [Manteca](https://docs.manteca.dev/cripto) | **In:** BRL (PIX), ARS, MXN, CLP · **Out:** those + COP, PEN, GTQ, CRC, BOB, PUSD, PHP | **Stellar**, EVM chains, Tron | Broadest LATAM payout coverage — 11 countries — behind the same interface. **Verified live**: BRL→PIX→USDC delivered on Stellar Testnet |
| `SepProvider` | any the anchor serves | **Stellar** | Fronts **any SEP-compliant anchor** (SEP-1/10/38/24): the end user authenticates with their own wallet, no partner key. One adapter, the whole anchor ecosystem |
| `MockProvider` | any | Stellar | Instant local dev + integration tests, realistic order lifecycle |
```tsx
import { EtherfuseProvider } from "@ramp-kit/core";
import { RampWidget } from "@ramp-kit/react";
const provider = new EtherfuseProvider({ apiKey });
provider.setBankAccount((await provider.listBankAccounts())[0].bankAccountId);
<RampWidget
provider={provider}
customerId={orgId}
fiatCurrency="BRL"
network="stellar"
assets={await provider.listAssets("stellar", { currency: "brl" })}
/>;
```
Swapping providers is one line (`new MantecaProvider({ apiKey })`,
`new MockProvider()`), or let the router pick per country and compare live
quotes:
```ts
const router = new RampRouter()
.register(new EtherfuseProvider({ apiKey }))
.register(new MantecaProvider({ apiKey: mantecaKey }));
// Routing is direction-aware: Manteca pays out across 11 countries but only
// takes deposits in 4, so the same corridor can resolve differently.
const provider = router.resolve({
country: "CO",
fiatCurrency: "COP",
direction: "offramp",
});
const quotes = await router.compareQuotes(request, { fiatCurrency: "BRL" });
```
## Packages
- **`@ramp-kit/core`** — framework-agnostic TypeScript SDK
- `RampProvider` interface: `listAssets` → `getQuote` → `createOrder` → `getOrder`
- Normalized order lifecycle: `created → awaiting_deposit → awaiting_signature → processing → settled | failed | cancelled`
- `EtherfuseProvider` (incl. `registerWallet`, `listBankAccounts`,
sandbox `simulateFiatReceived`), `MantecaProvider`, `MockProvider`
- `RampRouter`: provider selection per country/currency + live quote comparison
- Stellar helpers: `getAccountState` (trustline/reserve checks),
`getPendingBalances` / `claimPendingBalances` (sponsored-onramp claims),
`signAndSubmit` (handles `tx_too_late` → regenerate), `parseAssetIdentifier`
- **`@ramp-kit/react`** — `<RampWidget />` embeddable stepper flow (live quote
countdown, PIX/SPEI deposit instructions, status tracking), `useQuote`
(auto-refresh on expiry), `useOrder` (polls until terminal state)
- **`@ramp-kit/server`** — zero-dependency production backend: API-key proxy
with a strict endpoint allowlist, plus webhook receivers with HMAC-SHA256
signature verification (RFC 8785 canonicalization for Etherfuse)
- **`apps/demo`** — full BRL·PIX / MXN·SPEI onramp on Stellar Testnet:
built-in test wallet, live Horizon balance panel, one-click claim
- **`apps/second-app`** — the same widget dropped into a different app
(the sub-lane's "works in a second app" criterion)
## Why two providers
Manteca has the broadest LATAM fiat rails; Etherfuse is Stellar-native with
sponsored wallet onboarding. Both settle USDC on Stellar (Manteca added
Stellar support recently — verified live by this kit), which makes real
multi-anchor comparison possible on the same corridor:
`RampRouter.compareQuotes` fans one request out to both and returns live
rates sorted (verified: 100 BRL → 19.49 USDC Etherfuse vs 19.23 USDC Manteca).
They still expose completely different mental models (quote/order vs.
multi-stage synthetics + price locks) — the kit hides that behind one
interface, which is exactly the pain an app integrating ramps in the region
hits first.
| | Etherfuse | Manteca | Kit exposes |
| --- | --- | --- | --- |
| Pricing | quote (2 min expiry) | price lock (`expireAt`) | `RampQuote.expiresAt` + auto-refresh |
| Execution | order | ramp synthetic (stages) | `RampOrder.status` (one lifecycle) |
| Deposit info | CLABE / PIX charge on order | `details.depositAddress` | `DepositInstructions` |
| Stellar | trustlines, claimable balances, tx expiry | — | `stellar.ts` helpers |
## Running the demo (100% sandbox, no real money)
```bash
pnpm install
pnpm dev # demo on http://localhost:5173
```
**Zero-setup path:** pick "Mock provider" and walk the full flow immediately.
**Real sandbox path (Stellar Testnet):**
1. Create a sandbox account at <https://sandbox.etherfuse.com> — approve your
own KYB with the sandbox button.
2. In the dashboard, use **Add BRL Bank Account (PIX)** — it comes pre-filled
with test values and is compliant instantly. (MXN accounts registered via
API await async approval.)
3. Copy your `api_sand…` key into the demo and **connect Freighter** (your
own wallet signs everything — or generate a throwaway test wallet; the
provider registration happens automatically). Run an onramp: quote →
order → simulate the incoming PIX → watch it settle on Stellar Testnet →
claim the delivered claimable balance with one click. Then flip to
**Sell** to go the other way: USDC → BRL with in-wallet signing, both
transactions linked to Stellar Expert for public verification.
Manteca sandbox (`https://sandbox.manteca.dev/crypto/v2`) requires credentials
from the Manteca team; the adapter is implemented from their public docs and
ships with the same normalized lifecycle.
> **Note on API keys:** a provider key identifies your *business* (its KYB,
> fees and settlement accounts) — there is one per app, held server-side, and
> end users never see it. They are customers under it, identified by
> `customerId`. The demo asks you to paste a key only because whoever opens
> it is playing the role of the integrating developer.
## Shipping it to your own users
You get partner keys from Etherfuse and/or Manteca once. Your users just
click buy — they never see a key or an API.
```
browser (no key) → your backend (keys in env) → Etherfuse / Manteca
<RampWidget/> @ramp-kit/server
```
```ts
// your backend — the only place keys exist
createRampServer({
proxy: { apiKey: process.env.ETHERFUSE_API_KEY!, environment: "production" },
manteca: { apiKey: process.env.MANTECA_API_KEY!, environment: "production" },
}).listen(8787);
// your frontend — empty key, pointed at your backend
new EtherfuseProvider({ apiKey: "", baseUrl: "https://api.myapp.com/ramp/etherfuse" });
```
Runnable in [examples/backend-integration](examples/backend-integration) —
verified end to end against the real sandboxes with an empty client key:
quote → order → deposit → `settled`, while privileged endpoints (user
onboarding, company config, accounting) return `403` through the proxy.
The one piece that stays yours: onboarding each user with the provider
(KYC) to get their `customerId`. That's inherent to operating a ramp — from
quote onward the kit handles it.
**Why a backend at all?** Frontend env vars (`VITE_*`, `NEXT_PUBLIC_*`) are
embedded in the served JS bundle — any visitor can read them, so a partner
key there is exposed. The key must live in a backend env var behind
`@ramp-kit/server` (a ~10-line serverless function, not real
infrastructure). The exception is the SEP-anchor route: `SepProvider` needs
no partner key — the end user authenticates with their own wallet — so it
runs entirely in the frontend.
Full step-by-step for **testnet and mainnet** (env files, the single
`RAMP_ENV` flag, wallet networks, credential checklists):
[skills/ramp-kit/references/environments.md](skills/ramp-kit/references/environments.md).
The same guide ships inside the AI tooling — agents with the kit's skill or
the `@ramp-kit/mcp` server (`get_documentation` → `environments`) can walk
you through it.
## Deploy the demo (Vercel)
The demo ships ready to deploy — a serverless proxy at `api/[...path].ts`
(auto-detected by Vercel at the repo root):
1. [vercel.com/new](https://vercel.com/new) → import
`armandocodecr/latam-ramp-kit`.
2. **Root Directory:** `./` · **Framework Preset:** Other, with three
overrides in Build & Development Settings:
- Install Command: `pnpm install`
- Build Command: `pnpm -r build`
- Output Directory: `apps/demo/dist`
3. Deploy. **No environment variables are needed.**
What the deployed demo does:
- **Mock provider works for everyone**, with zero setup — the full widget
flow, buy and sell.
- **Live sandbox modes relay the visitor's own key**: the browser calls
`/api/<provider>/*`, the function forwards it to the provider with the
same endpoint allowlist `@ramp-kit/server` enforces. The deployment holds
no credentials and stores nothing.
- Upstreams are pinned to the providers' **sandbox** hosts, so a deployed
demo can never reach production money.
## Field notes (verified against the real sandbox)
- `GET /ramp/assets` requires `blockchain`, `currency` and `wallet` — the kit
fills sensible defaults.
- Bring-your-own wallets must be registered before their first order — the
SDK **self-heals** this: `createOrder` registers (idempotent) and retries
on "Wallet not found". `claimOwnership: true` under a KYB-approved org
marks wallets compliant with no per-wallet KYC.
- PIX onramp orders report `depositBankName: "PIX"` with an empty CLABE — the
kit maps this to a PIX `DepositInstructions` automatically.
- First-time wallets receive tokens as **claimable balances** (plus ~1.5 XLM
sponsored reserves); `claimPendingBalances` builds trustline + claim in one
transaction.
## AI tooling: MCP server + agent skill
The kit ships first-class AI support — both for **understanding** it and for
**operating** it. An AI agent has already driven the full flow through these
tools: quoted 50 BRL → USDC, created the sandbox order, simulated the PIX
payment and watched it settle on Stellar Testnet.
- **[@ramp-kit/mcp](packages/mcp)** — MCP server published on
[npm](https://www.npmjs.com/package/@ramp-kit/mcp) and listed in the
[official MCP Registry](https://registry.modelcontextprotocol.io/?search=io.github.armandocodecr/ramp-kit)
as `io.github.armandocodecr/ramp-kit`. Nine tools: built-in documentation
(`get_documentation` with 6 topics), provider discovery, live quotes,
multi-provider comparison, sandbox orders, deposit simulation
(sandbox-only by design) and Stellar wallet inspection. Works
credential-free with the mock provider.
```bash
claude mcp add ramp-kit -e ETHERFUSE_API_KEY=api_sand_… -- npx -y @ramp-kit/mcp
```
Or in any MCP client's `mcpServers` config:
```json
{ "ramp-kit": { "command": "npx", "args": ["-y", "@ramp-kit/mcp"] } }
```
- **[skills/ramp-kit](skills/ramp-kit)** — agent skill (Claude Code, Cursor,
and any agent supported by the [skills CLI](https://skills.sh)): teaches
the agent what the kit solves, the integration flow, sandbox setup,
verified troubleshooting and the production checklist.
```bash
npx skills add https://github.com/armandocodecr/latam-ramp-kit/tree/main/skills/ramp-kit
```
Together they cover both halves: the skill gives an agent the **knowledge**
to guide an integration; the MCP server gives it **hands** to actually
quote, order and verify against the sandbox. This pairs naturally with
Stellar's agentic-payments direction (x402/MPP): a ramp that AI agents can
understand and operate end-to-end.
## Path to production
The code is production-ready; what remains is provider onboarding. Ready today:
- **Environment switch** — `environment: "sandbox" | "production"` on every
provider flips base URLs; `stellarConfigFor("production")` returns mainnet
Horizon + network passphrase. No hardcoded issuers anywhere: assets are
always discovered via the provider, so mainnet identifiers flow through
automatically.
- **Server-side key handling** — `@ramp-kit/server` ships `createRampServer`:
the API key lives in your backend, the browser only reaches an allowlisted
ramp surface (quote/order/status), and the sandbox simulation endpoint is
hard-blocked in production.
- **Webhooks over polling** — `createEtherfuseWebhookHandler` verifies
`X-Signature` (HMAC-SHA256 over RFC 8785-canonicalized JSON, constant-time
compare), acks 2xx immediately, and dispatches typed events.
`verifyMantecaSignature` covers Manteca's shared-secret HMAC.
- **Real wallets** — signing is callback-based (`claimPendingBalances`,
`signAndSubmit`), so Freighter/hardware wallets plug in directly. The
demo's localStorage keypair is a sandbox convenience, not the pattern.
- **Sandbox-only code is fenced** — `simulateFiatReceived` throws in
production; deposits are detected from the real SPEI/PIX transfer.
External steps (with the provider, not in code):
1. **Etherfuse production KYB** — real legal-entity review (manual, allow
days/weeks), then an `api_prod_…` key. Register real bank accounts (real
CLABE/RFC) and confirm **BRL/PIX production availability** (live in
sandbox; listed as upcoming for production).
2. **End-user KYC** — production users complete the hosted identity flow
(documents + liveness); sandbox auto-approval does not apply.
3. **Manteca credentials** — commercial onboarding for a production
`md-api-key`, per-country permissions (BRL/PIX), and webhook secret;
confirm their signature header name during onboarding.
4. **Deploy `@ramp-kit/server`** behind HTTPS, register the webhook URL via
`POST /ramp/webhook`, and store the one-time secret.
5. **Persistence** — store quote/order idempotency UUIDs and webhook events
(dedupe by resource id + status) in your database.
## Repo layout
```
packages/core @ramp-kit/core — SDK, adapters, router, Stellar helpers
packages/react @ramp-kit/react — widget + hooks
packages/server @ramp-kit/server — production proxy + webhook verification
packages/mcp @ramp-kit/mcp — MCP server for AI agents (official MCP Registry)
api/ serverless ramp proxy for the deployed demo (Vercel)
skills/ramp-kit agent skill — integration knowledge for AI coding agents
examples/agent-checkout — third-party checkout using only the published npm artifacts
apps/demo primary demo (Etherfuse sandbox / mock, Stellar Testnet)
apps/second-app second integration of the same widget
docs/ provider research + Etherfuse OpenAPI spec
```