Skip to content

FurlPay/furlpay-node

Repository files navigation

Furlpay Node.js SDK

npm CI license

The official TypeScript/Node.js SDK for the Furlpay API: stablecoin payments, global banking, virtual cards, cross-chain swaps, fractional investing, and compliance tooling — behind one typed client.

  • Zero runtime dependencies. Uses the global fetch (Node 18+).
  • Full TypeScript types for every resource, request, and response.
  • Stripe-style webhook verification with replay protection.
  • Works against the hosted API or any self-hosted/sandbox deployment via baseUrl.

Requirements

  • Node.js 18 or later (for the built-in fetch). On older runtimes, pass a fetchImpl.

Installation

npm install @furlpay/furlpay-node

Quickstart

import { Furlpay } from "@furlpay/furlpay-node";

const furlpay = new Furlpay({ apiKey: process.env.FURLPAY_API_KEY! });

// Safe smart-account balances and active modules
const wallet = await furlpay.wallets.retrieve();

// Cheapest cross-chain stablecoin route
const { quote } = await furlpay.swaps.quote({
  fromToken: "USDT",
  toToken: "USDC",
  fromChain: "arbitrum",
  amountIn: 500,
});

// Fractional stock order
const order = await furlpay.investing.createOrder({
  symbol: "AAPL",
  side: "buy",
  notional: 100,
});

Client configuration

new Furlpay({
  apiKey: "sk_live_...",              // required
  baseUrl: "https://api.furlpay.app", // optional, defaults to the hosted API
  fetchImpl: fetch,                   // optional, custom fetch (proxies, polyfills, tests)
});
Option Type Default Description
apiKey string Secret API key (sk_...). Sent as a Bearer token.
baseUrl string https://api.furlpay.app API origin. Point at http://localhost:3000 for local sandbox.
fetchImpl typeof fetch globalThis.fetch Injectable fetch for proxies, retries, or tests.

API reference

furlpay.wallets

Method HTTP Description
retrieve() GET /api/wallets Safe smart account: stablecoin balances, active modules (PolicyGuard, Escrow, Paymaster, Safe4337Module).
transfer(params) POST /api/wallets/transfer Gas-sponsored stablecoin transfer. Requires destination, amount, token, chain, and an owner signature; the destination is AML-screened server-side and high-value transfers require step-up MFA.

furlpay.banking

Method HTTP Description
list() GET /api/banking Provisioned virtual accounts (IBAN, routing/account numbers, UPI).
provision(currency) POST /api/banking Provision a named virtual account: "USD" | "EUR" | "GBP" | "INR".

furlpay.cards

Method HTTP Description
list() GET /api/cards All virtual and physical cards with limits and channel controls.
updateSettings(params) POST /api/cards/settings Freeze/unfreeze, set limits.daily / limits.perPurchase, reorder funding priority.

furlpay.investing

Method HTTP Description
portfolio() GET /api/investing/portfolio Holdings marked to the latest quotes, dividends, and performance.
createOrder(params) POST /api/investing/order Fractional stock/ETF order. side: "buy" | "sell", notional in USD, type: "market" | "limit".

furlpay.swaps

Method HTTP Description
quote(params) POST /api/swaps Best cross-chain route for a stablecoin swap with slippage, gas, and ETA.

furlpay.compliance

Method HTTP Description
verifyIdentity(params) POST /api/compliance/kyc Run a KYC identity check.
travelRule(params) POST /api/compliance/travel-rule Produce a FATF Travel Rule payload for a VASP-to-VASP transfer.

Webhook verification

Furlpay.webhooks.constructEvent mirrors Stripe's API: HMAC-SHA256 over a timestamped payload, compared with crypto.timingSafeEqual, with a plus/minus 300 second tolerance to block replays.

import { Furlpay } from "@furlpay/furlpay-node";

app.post("/api/webhooks/furlpay", (req, res) => {
  let event;
  try {
    event = Furlpay.webhooks.constructEvent(
      req.body,                          // RAW string body — do not JSON.parse first
      req.headers["furlpay-signature"],  // "t=1719900000,v1=5257a869e7..."
      process.env.FURLPAY_ENDPOINT_SECRET!
    );
  } catch {
    return res.status(400).send("Invalid signature");
  }

  switch (event.type) {
    case "card.transaction.authorized":
      // ...
      break;
  }
  res.json({ received: true });
});

Use @furlpay/cli to forward signed sandbox events to localhost while you develop.

Error handling

Every non-2xx response throws a typed FurlpayError:

import { Furlpay, FurlpayError } from "@furlpay/furlpay-node";

try {
  await furlpay.wallets.transfer({ /* ... */ });
} catch (err) {
  if (err instanceof FurlpayError) {
    console.error(err.statusCode); // e.g. 403
    console.error(err.message);    // server error message
    console.error(err.raw);        // full response body (risk screens, step-up hints)
  }
}

A 401 with stepUpRequired: true in err.raw means the transfer needs an MFA code — retry with mfaCode.

Sandbox

Every Furlpay deployment runs in mock/sandbox mode by default. Point the client at your local app with a sandbox key:

new Furlpay({ apiKey: "sk_sandbox_demo", baseUrl: "http://localhost:3000" });

TypeScript

All request and response shapes are exported: Wallet, Balance, Card, Order, SwapQuote, FurlpayEvent, Stablecoin, Chain, and more. The package ships .d.ts declarations; no @types package is needed.

Related

Contributing and security

See CONTRIBUTING.md. Report vulnerabilities privately per SECURITY.md — do not open public issues for security reports.

License

MIT

About

Official Node.js/TypeScript SDK for the Furlpay API — stablecoin payments, cards, swaps, investing. Zero dependencies.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages