docs · v0.4.0-rc.2 / sdk · @solupg/sdk@0.4.2 / tested · node 20 · deno 1.40 / last-updated · 2d ago
~/quickstart

Five minutes from npm install to a signed, settled Solana payment.

Three code snippets cover 90% of what most integrations need. The SDK is typed, tree-shakable, and works in Node, Deno, Bun, and the browser. Everything below runs against devnet by default — swap one env var to go to mainnet.

node ≥ 18 typescript 5.x bundler optional devnet live mainnet · pending audit
§01

Install the SDK

One dependency. No peer-deps. @solana/web3.js is bundled transitively — you can import it directly if needed.

$ npm install @solupg/sdk
added 1 package in 1.2s
§02

Your first payment

Get an API key from dashboard.solupg.dev — or run locally without one (see self-hosting). Sign transactions with a keypair you own; the SDK never touches your seed.

first-payment.ts
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { SolUPG, Keypair } from "@solupg/sdk"; const upg = new SolUPG({ apiKey: "sk_devnet_…", cluster: "devnet", payer: Keypair.fromSecretKey(SECRET), }); // Pay 0.5 SOL worth of USDC to a human-readable recipient const tx = await upg.pay({ to: "bob@example.id", amount: 25, settle: "USDC", }); console.log(`https://explorer.solana.com/tx/${tx.signature}`);
tip

In devnet, SolUPG auto-funds your payer with 2 SOL on first use. In mainnet you're responsible for keeping it topped up.

§03

Webhooks

Every payment lifecycle event (created · signed · confirmed · finalized · failed) fires a webhook. Signatures are HMAC-SHA256; verify before trusting.

webhook-handler.ts
copy
1
2
3
4
5
6
7
8
9
10
11
12
import { verifyWebhook } from "@solupg/sdk"; app.post("/webhooks/solupg", async (req, res) => { const event = verifyWebhook(req.body, req.headers["x-solupg-sig"], SECRET); if (event.type === "payment.finalized") { await fulfillOrder(event.data.reference); } res.sendStatus(200); });
§04

Patterns

Three canonical flows. Pick the one closest to your use case and fork.

copy
1
2
3
4
5
6
7
8
9
const tx = await upg.pay({ to: "alice@example.id", amount: 25, settle: "USDC", memo: "invoice #8821", }); // tx.signature → on-chain signature // tx.reference → idempotency key, safe to retry
§05

Self-host in one command

If you'd rather not depend on our hosted gateway, run the full stack on your own machine. Clone, compose, done.

$ git clone https://github.com/revengerrr/solupg
$ cd solupg
$ cp .env.example .env
$ docker compose up -d
✔ postgres healthy
✔ redis healthy
✔ api-gateway started on :8080
✔ router started on :8081
✔ directory started on :8082
✔ clearing started on :8083
✔ monitoring started on :8084
✓ solupg stack is up · http://localhost:8080

Required env

SOLANA_RPC_URLRPC endpoint (Helius, Triton, QuickNode)
POSTGRES_URLdefaults to compose service
REDIS_URLdefaults to compose service
UPG_SIGNER_KEYbase58 keypair for the gateway payer
WEBHOOK_SECRETHMAC secret for signed events

Optional env

JUPITER_URLoverride default quote endpoint
OTP_PROVIDERtwilio · mailgun · log
PROM_PUSHGATEWAYoptional metrics push
RATE_LIMIT_RPSdefault 50
LOG_LEVELtrace · debug · info · warn
§06

Scaling notes

The stack was load-tested to 1,000 TPS sustained on a single 8-core node. Past that, split along the natural service boundaries:

api-gateway

Stateless. Scale horizontally behind any load balancer. Use sticky sessions only if you rely on long-poll webhooks.

router

CPU-bound on signature verification. Pin to dedicated cores; each replica handles ~350 TPS.

directory

Redis-cached. Scales with RAM. 1M entries ≈ 180MB.

clearing

Single-writer by design. Use Postgres streaming replicas for read-heavy dashboards.

§07

Contribute

This is a small team. Good first issues are tagged good-first-issue and deliberately kept scoped. Large refactors should start with an RFC in /rfcs.

release

Releases cut every two weeks on Fridays. Changelog lives at /CHANGELOG.md. SDK versions follow the on-chain program IDL — a minor bump indicates a new IDL.

$ next steps

Still stuck?

Open a discussion on GitHub or reach out on X. Response times are typically under a day, because this team is small and nobody has a support-ticket queue.

Tweaks