@ramp-kit/server
v0.1.4
Published
Zero-dependency production backend for @ramp-kit/core: server-side API-key proxy with strict endpoint allowlist, plus Etherfuse/Manteca webhook signature verification (HMAC-SHA256, RFC 8785 canonicalization)
Downloads
65
Maintainers
Readme
@ramp-kit/server
Zero-dependency production backend for @ramp-kit/core. Two jobs:
- API-key proxy — your ramp provider key lives on this server, never in the browser. The frontend reaches only a strict allowlist of ramp endpoints; everything privileged is blocked.
- Webhook receiver — verifies provider signatures and turns deliveries into typed events.
Plain Node (node:http, node:crypto) — no framework, no dependencies.
Node ≥ 20.
Install
npm install @ramp-kit/serverStandalone server
import { createRampServer } from "@ramp-kit/server";
createRampServer({
proxy: {
apiKey: process.env.ETHERFUSE_API_KEY!,
environment: "production", // sandbox | production
// pathPrefix: "/etherfuse", // default
// allowSimulation: true, // sandbox-only; hard-blocked in production
},
webhooks: {
etherfuseSecret: process.env.ETHERFUSE_WEBHOOK_SECRET!,
onEvent: (type, entity) => {
// order_updated | swap_updated | customer_updated | kyc_updated | …
queue.push({ type, entity });
},
},
}).listen(8787);The frontend then targets the proxy instead of the provider:
new EtherfuseProvider({ apiKey: "", baseUrl: "https://api.myapp.com/etherfuse" });Or mount the handlers in an existing Node server: createRampProxy(config)
and createEtherfuseWebhookHandler(config) are plain
(req, res) => Promise<boolean> handlers.
Endpoint allowlist
Only what a ramp frontend legitimately needs is forwarded:
| Allowed | Blocked (403) |
| --- | --- |
| GET /ramp/me, /ramp/assets, /ramp/bank-accounts, /ramp/order/:id | Organization management |
| POST /ramp/quote, /ramp/order, /ramp/wallet | Partner statements, fees |
| POST /ramp/order/:id/cancel, /ramp/order/:id/regenerate_tx | Webhook management |
| POST /ramp/order/fiat_received (sandbox + opt-in only) | Everything else |
Webhook signature verification
- Etherfuse —
X-Signature: sha256={hex}: HMAC-SHA256 over the RFC 8785-canonicalized JSON body, keyed with the base64 secret returned once byPOST /ramp/webhook. Constant-time comparison; the handler acks2xximmediately (Etherfuse retries only 3× with 5s intervals) and dispatches the event afterwards. - Manteca —
verifyMantecaSignature(rawBody, header, secret)for their shared-secret HMAC (header name confirmed during Manteca onboarding).
canonicalize() (RFC 8785 subset) is exported for reuse.
Handle events idempotently
Deliveries can arrive out of order. Key your processing on resource id +
status, and drive logic from the payload's status field — not arrival
order.
Full documentation and demo apps live in the latam-ramp-kit repository. AI tooling (MCP server + agent skill) is available — see @ramp-kit/mcp.
MIT © Armando Cruz
