Sign In

settlemesh-sdk

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

settlemesh-sdk

Add SettleMesh login, database and payments to any app — any framework, hosted anywhere.

npmnpm
Version
0.3.0
Version published
Weekly downloads
100
-2.91%
Maintainers
1
Weekly downloads
 
Created
Source

settlemesh-sdk

Add SettleMesh login, database and payments to any app — any framework, hosted anywhere (your own server, Vercel, Cloudflare, Render, a Raspberry Pi). You write the routes and decide where the "Sign in with SettleMesh" entry point lives; the SDK does the protocol work.

It is not tied to SettleMesh hosting. Drop it into an Express/Hono/Fastify/Next/SvelteKit/plain-Node app and call three small APIs.

npm install settlemesh-sdk

Runs anywhere with the Web Crypto API: Node 18+, Cloudflare Workers, Deno, Bun, the browser. Zero dependencies. Ships with TypeScript types, and transparently retries transient gateway errors (502/503/504) on idempotent reads — never on writes/charges.

Get credentials

npx settlemesh apps register \
  --name "My App" \
  --redirect-uri https://myapp.com/auth/callback \
  --with-database --with-payment

This prints (and never needs a SettleMesh-hosted deploy):

PillarYou receiveUse it for
LoginclientIdOAuth — auth.*
DatabaseprojectId, serverKeySQL — db.* (server-side only)
PaymentsmerchantKey, webhookSecretCheckout — payments.* (server-side only)

Create a client

import { createClient } from "settlemesh-sdk";

const settle = createClient({
  clientId: process.env.SETTLEMESH_CLIENT_ID,
  projectId: process.env.SETTLEMESH_PROJECT_ID,
  serverKey: process.env.SETTLEMESH_SERVER_KEY,
  merchantKey: process.env.SETTLEMESH_MERCHANT_KEY,
  webhookSecret: process.env.SETTLEMESH_WEBHOOK_SECRET,
  sessionSecret: process.env.SESSION_SECRET, // for durable login cookies
});

Pass only the credentials for the pillars you use.

Login — you choose where it lives

The SDK gives you a URL and the identity; you own the two routes. Example with plain Node, but the same two calls work in any framework:

// 1) Your "Sign in" route — wherever you want it
const { url, state, codeVerifier } = await settle.auth.createAuthorizationUrl({
  redirectUri: "https://myapp.com/auth/callback",
});
// stash { state, codeVerifier } in a short-lived signed/HttpOnly cookie, then redirect:
res.writeHead(302, { Location: url });

// 2) Your callback route — path is your choice, just match the redirectUri
const { user, idToken } = await settle.auth.handleCallback({
  code, redirectUri: "https://myapp.com/auth/callback", codeVerifier,
});
// user = { sub, email, name, ... }

Keep users signed in with your own durable cookie (decoupled from the 15‑minute OAuth token):

const sessionCookie = await settle.auth.createSession(user, { maxAgeSec: 60 * 60 * 24 * 7 });
// later, on any request:
const me = await settle.auth.readSession(cookieValue); // null if absent/expired/tampered

Helpers parseCookies(header) and serializeCookie(name, value, opts) are exported so you never hand-roll cookie strings.

Database

await settle.db.migrate("init", `
  create table if not exists notes (id integer primary key, user_id text, body text)
`);
await settle.db.query("insert into notes (user_id, body) values (?, ?)", [user.sub, "hi"]);
const { rows } = await settle.db.query("select * from notes where user_id = ?", [user.sub]);
const one = await settle.db.queryOne("select count(*) as n from notes");

Server-side only — never expose serverKey to the browser. Params are positional (? for SQLite/D1, $1 for Postgres/Neon).

Payments

// Start a checkout, redirect the user to `url`
const checkout = await settle.payments.createCheckout({
  amount: 50,                 // credits
  description: "Pro plan",
  externalId: order.id,
  returnUrl: "https://myapp.com/billing/return",
  cancelUrl: "https://myapp.com/billing",
  idempotencyKey: order.id,
});
res.writeHead(302, { Location: checkout.url });

Confirm completion either way:

// (a) On your return route — poll:
const c = await settle.payments.retrieveCheckout(checkoutId);
if (c.paid) { /* fulfil */ }

// (b) Via webhook (recommended) — verify the signature against the RAW body:
const event = await settle.payments.verifyWebhook({
  payload: rawBody,                                  // the raw string, do NOT re-serialize
  signature: req.headers["x-settlemesh-signature"],
});
if (event.event === "checkout.completed") { /* fulfil event.data.external_id */ }

Runtime — capabilities & storage, billed to the END USER

For a deployed app's backend: call official capabilities (LLM, search, scrape, video) and object storage with the app's runtime key (SETTLEMESH_APP_API_KEY, injected for you). By default these bill the developer who owns the key. To bill the logged-in user for their own usage instead, pass that user's token as payerextractPayerToken(req) pulls it off the incoming request in one line:

import { createClient, extractPayerToken } from "settlemesh-sdk";

const settle = createClient({}); // apiKey defaults to process.env.SETTLEMESH_APP_API_KEY

app.post("/ai/summarize", async (req, res) => {
  const payer = extractPayerToken(req); // the logged-in user's token (Bearer or __settle_session cookie)
  const out = await settle.runtime.invokeCapability("llm.generate",
    { prompt: req.body.text }, { payer }); // ← the USER pays for their own call, not you
  res.json(out);
});

No payer? The key owner (you) pays — never a surprise charge to the wrong account. Read your app's own non-secret config (storage / capability / database URLs, app id) at runtime instead of baking it in:

const cfg = await settle.runtime.config();   // { base_url, storage_api, capabilities_invoke, app_id, ... }

API surface

  • createClient(cfg){ auth, db, payments, runtime, baseUrl }
  • auth: createAuthorizationUrl, handleCallback, getUser, decodeIdToken, createSession, readSession
  • db: query, queryOne, migrate
  • payments: createCheckout, retrieveCheckout, verifyWebhook
  • runtime: invokeCapability(id, input, { payer }), storagePut/storageGet(key, { payer }), config() — plus extractPayerToken(req)

All errors are SettleMeshError with .status, .code, .details.

Self-hosting / different base URL

createClient({ baseUrl: "https://settlemesh.example.com", /* ... */ });

Defaults to https://www.settlemesh.io.

Keywords

settlemesh

FAQs

Package last updated on 09 Jun 2026

Related posts