@ramp-kit/core
v0.1.4
Published
Unified fiat on/off-ramp SDK for LATAM on Stellar: one provider interface over Etherfuse (PIX/SPEI, Stellar-native) and Manteca, with quote/order lifecycle normalization, multi-provider routing with live quote comparison, mock provider, and Stellar helper
Downloads
468
Maintainers
Readme
@ramp-kit/core
Unified fiat on/off-ramp SDK for Latin America on Stellar. One RampProvider
interface over real ramp backends — write your integration once, swap
providers with one line.
Built for the Stellar "Brazil Ramps and Regional Kits" initiative and proven end-to-end on Stellar Testnet: BRL entered via PIX and settled as USDC in a fresh Stellar wallet, sponsored account creation included.
Why
Every LATAM app that moves money between banks and blockchains hits the same wall: each ramp provider has its own API, auth scheme, KYC model, order states and price-expiry rules — and none covers the whole region. Integrating one takes weeks; integrating two doubles it. This SDK normalizes all of it behind a single interface.
Providers
| Provider | Fiat rails | Settlement networks | Notes |
| --- | --- | --- | --- |
| EtherfuseProvider | BRL (PIX), MXN (SPEI) | Stellar (native), Solana, Base, Polygon | Automatic trustlines, sponsored wallet onboarding via claimable balances, sandbox with full payment simulation |
| MantecaProvider | BRL (PIX), ARS, MXN, CLP, COP, PEN… | EVM chains, Tron | Price locks + multi-stage synthetics, mapped to the same lifecycle |
| MockProvider | BRL, MXN, ARS | Stellar | In-memory, realistic timing, optional auto-funding — for UI dev and tests |
Install
npm install @ramp-kit/coreQuickstart (Etherfuse sandbox, no real money)
import { EtherfuseProvider } from "@ramp-kit/core";
const provider = new EtherfuseProvider({
apiKey: process.env.ETHERFUSE_API_KEY!, // api_sand_… from sandbox.etherfuse.com
environment: "sandbox", // "production" flips base URL
});
// 1. Pick the fiat leg for orders
const accounts = await provider.listBankAccounts();
provider.setBankAccount(accounts.find((a) => a.compliant)!.bankAccountId);
// Wallet registration is automatic: createOrder self-heals "wallet not
// found" by registering (idempotent) and retrying. registerWallet() is
// still available to do it eagerly.
// 2. Discover assets — identifiers are environment-specific, never hardcode
const assets = await provider.listAssets("stellar", { currency: "brl" });
const usdc = assets.find((a) => a.symbol === "USDC")!;
// 3. Quote → order → deposit instructions
const quote = await provider.getQuote({
direction: "onramp",
fiatCurrency: "BRL",
assetIdentifier: usdc.identifier,
network: "stellar",
sourceAmount: "100",
customerId: orgId,
walletAddress,
});
const order = await provider.createOrder(quote);
console.log(order.depositInstructions); // { rail: "PIX", amount: "100", … }
// 4. Sandbox only: simulate the incoming PIX/SPEI transfer
await provider.simulateFiatReceived(order.id);
// 5. Track to settlement
const settled = await provider.getOrder(order.id); // status: "settled"Offramp (crypto → fiat)
Same lifecycle in reverse: the user signs a provider-built burn transaction instead of sending a fiat deposit.
const quote = await provider.getQuote({
direction: "offramp", fiatCurrency: "BRL",
assetIdentifier: usdc.identifier, network: "stellar",
sourceAmount: "5", customerId: org.id, walletAddress,
});
const order = await provider.createOrder(quote);
// order.unsignedTx appears asynchronously → status "awaiting_signature"
import { signAndSubmit, stellarConfigFor } from "@ramp-kit/core";
await signAndSubmit(order.unsignedTx!, walletSigner, stellarConfigFor("sandbox"));
// signAndSubmit raises RampError("tx_expired") when the ~1-2 min window
// passed — call provider.regenerateTx(order.id) and retry.Normalized order lifecycle
Every provider's states map to one lifecycle your UI can rely on:
created → awaiting_deposit → awaiting_signature? → processing → settled
↘ failed | cancelledQuotes always carry expiresAt (Etherfuse: 2 min; Manteca price locks:
asset-dependent) so UIs can refresh proactively — or use useQuote from
@ramp-kit/react which does it
automatically.
Multi-provider routing
import { RampRouter } from "@ramp-kit/core";
const router = new RampRouter()
.register(new EtherfuseProvider({ apiKey }))
.register(new MantecaProvider({ apiKey: mantecaKey }));
// Best provider for the corridor (Stellar-native preferred)
const provider = router.resolve({ country: "BR", fiatCurrency: "BRL" });
// Or fan out and compare live quotes across all eligible providers
const quotes = await router.compareQuotes(request, { fiatCurrency: "BRL" });Stellar helpers
Sponsored onramps deliver tokens as claimable balances when the wallet lacks a trustline (or doesn't exist yet). The helpers close that loop:
import {
getAccountState, // exists? trustline? XLM reserves?
getPendingBalances, // claimable balances waiting for the wallet
claimPendingBalances, // trustline(s) + claim in ONE tx, callback signing
signAndSubmit, // submit provider-built txs, detects tx_too_late
stellarConfigFor, // "sandbox" → Testnet, "production" → mainnet
} from "@ramp-kit/core";
await claimPendingBalances(walletAddress, async (xdr, passphrase) => {
// plug in Freighter, a hardware wallet, or any signer
return await freighter.signTransaction(xdr, { networkPassphrase: passphrase });
}, stellarConfigFor("sandbox"));Signing is always callback-based — secret keys never touch the SDK.
Error handling
All failures throw RampError with the provider name preserved and a typed
code: auth, quote_expired, tx_expired, kyc_required, unsupported,
network, provider_error.
Production
Provider API keys are server-side secrets: pair this SDK with @ramp-kit/server (allowlisted proxy + webhook signature verification). Full path-to-production checklist in the repository.
AI tooling
- @ramp-kit/mcp — MCP server
(listed in the official MCP Registry)
so AI agents can quote, create sandbox orders and inspect wallets:
claude mcp add ramp-kit -- npx -y @ramp-kit/mcp - Agent skill with integration knowledge and verified troubleshooting:
npx skills add https://github.com/armandocodecr/latam-ramp-kit/tree/main/skills/ramp-kit
Related packages
- @ramp-kit/react — embeddable
<RampWidget />+ hooks - @ramp-kit/server — production proxy + webhooks
- @ramp-kit/mcp — MCP server for AI agents
MIT © Armando Cruz · Repository & demo apps
