npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

suioutkit

v1.2.1

Published

Premium Universal Payment Gateway SDK for instant settlement on Sui

Readme

Browser SDK for SuiOutKit checkout: create sessions, open a ready-made payment modal, or build a custom UI with helpers.

Defaults to the hosted SuiOutKit API at https://api.suioutkit.xyz (mode: "live"). Switch with mode: "test" or mode: "local" for development. All routes under /v1/. The SDK does not perform settlement, treasury checks, or provider calls itself.

| Resource | Link | |----------|------| | Monorepo overview | /README.md | | Documentation | /docs/README.md | | Live demo | /demo/demo.html | | Backend & operator setup | /docs/developer-guide.md |

Table of contents

Install

npm install suioutkit
# or
yarn add suioutkit

Peer environment: Node 18+ to build; in the browser, any modern ESM-capable environment.

Quick start

React or bundler (recommended)

import { SuiOutKit } from "suioutkit";

const sdk = new SuiOutKit({
  merchantAddress: "0xYOUR_MERCHANT_SUI_ADDRESS",
  // mode optional - defaults to "live" (https://api.suioutkit.xyz, mainnet)
});

export function PayButton() {
  async function handlePay() {
    const session = await sdk.initCheckout({
      amount: 45000,
      currency: "NGN",
      metadata: { orderId: "ORDER-123" },
    });
    sdk.openModal(session, () => {
      console.log("Modal closed");
    });
  }

  return <button type="button" onClick={handlePay}>Pay now</button>;
}

One-line button binding

sdk.wrapButton("#pay-btn", {
  amount: 45000,
  currency: "NGN",
  metadata: { sku: "PRO-PLAN" },
});

Updates the button label (e.g. Pay ₦45,000) and opens the modal on click.

Vanilla HTML (serve SDK bundle)

For simple demos you can serve the built SDK bundle from any static host. Build the SDK with npm run build in sdk/ and serve sdk/dist/index.js from your server. See the Developer Guide for recommended local and production setups: /docs/developer-guide.md.

Configuration

new SuiOutKit(config)

| Option | Type | Required | Description | |--------|------|----------|-------------| | merchantAddress | string | Yes | Sui address that receives settlement | | mode | "local" \| "test" \| "live" | No | Default: "live". "local"http://localhost:5000 (testnet), "test"https://api.staging.suioutkit.xyz (testnet), "live"https://api.suioutkit.xyz (mainnet). | | backendUrl | string | No | Override API origin (no trailing slash). Takes precedence over mode. |

The SDK automatically sets window.SuiOutKitNetwork to the correct Sui network based on mode - no manual <script> tag needed.

API reference

initCheckout(options)

Creates a checkout session on the backend.

const session = await sdk.initCheckout({
  amount: 45000,       // integer in major units (e.g. 45000 NGN)
  currency: "NGN",     // e.g. "NGN"
  coinType?: "0x2::sui::SUI",  // optional: override settlement coin
  metadata?: { orderId: "ORDER-123" },
});

Returns CheckoutSession (includes at least):

| Field | Description | |-------|-------------| | token | Opaque session token for charge/crypto calls | | nonce | Public session id for status polling | | amount, currency | Checkout totals | | merchantAddress | Normalized Sui address | | coinType | Settlement coin type (from backend config) | | supportedCoins | Array of { symbol, type, decimals } for available settlement coins | | estimatedRate | FX preview (NGN → token) when applicable | | packageId, cryptoRegistryId, cryptoRegistryName | On-chain config for crypto paths |

Throws if the backend returns a non-OK response.


openModal(session, options?)

Opens the built-in checkout modal (bank transfer, OPay, Stripe, Sui wallet, outPay).

const modal = sdk.openModal(session, {
  onClose: () => console.log("closed"),
  onPaymentComplete: (result) => console.log(result.txDigest, result.walrusBlobId),
  redirectUrl: "/thank-you",
  autoCloseOnSuccess: true,
});

Returns SuiOutKitModal (internal handle). The modal loads styles from {backendUrl}/style.css automatically.

Options (SuiOutKitModalOptions):

| Option | Type | Description | |--------|------|-------------| | onClose | () => void | Called when the user dismisses the overlay | | onPaymentComplete | (result: PaymentResult) => void | Called after on-chain settlement with { nonce, txDigest, walrusBlobId } | | redirectUrl | string | Redirect browser here after successful payment | | autoCloseOnSuccess | boolean | Auto-close the modal after settlement instead of showing success panel |

Note: Theme, logo, and allowedMethods customization are not exposed on openModal today. Use custom UI or extend the modal in source if you need that.


wrapButton(selector, options)

Binds checkout to a DOM button.

| Argument | Type | Description | |----------|------|-------------| | selector | string | CSS selector (e.g. "#pay-btn") | | options.amount | number | Checkout amount | | options.currency | string | e.g. "NGN" | | options.coinType | string | Optional settlement coin type override | | options.metadata | object | Optional passthrough to initCheckout |


confirmCryptoPayment(nonce, txDigest, method?)

After the user pays via wallet/outPay in a custom flow, submit the transaction digest for backend verification and Walrus receipt handling.

const result = await sdk.confirmCryptoPayment(
  session.nonce,
  txDigest,
  "sui_wallet" // or "outpay"
);

if (result.status === "success") {
  console.log(result.txDigest, result.walrusBlobId);
}

The built-in modal calls this internally for crypto paths.


Helper exports

For custom UIs without the modal:

import {
  SuiOutKit,
  request,
  formatNgn,
  toTokenUnits,
  formatToken,
  createPolling,
} from "suioutkit";

| Export | Description | |--------|-------------| | request(url, options?) | fetch wrapper with timeout and JSON parsing | | formatNgn(amount) | Format NGN with locale / fallback | | toTokenUnits(baseUnits, decimals?) | Convert base units to float (default 9 decimals) | | formatToken(amount, decimals?, digits?) | Display-friendly token amount string | | createPolling(fn, intervalMs) | { start(), stop() } interval helper |

Example - poll settlement status:

import { createPolling, request } from "suioutkit";

const poll = createPolling(async () => {
  const status = await request(`${backendUrl}/v1/checkout/status/${nonce}`);
  if (status.status === "SETTLED") {
    poll.stop();
    console.log(status.txDigest, status.walrusBlobId);
  }
}, 3000);

poll.start();

Example - Server-Sent Events (React hook in repo, not published from package entry today):

The backend exposes GET /v1/payments/stream/:nonce. You can use EventSource directly or copy usePaymentStatus.ts into your app.

Payment methods

The modal orchestrates these charge methods against the backend:

| Method | Provider | Notes | |--------|----------|--------| | bank_transfer | Flutterwave | Virtual account details shown in modal | | opay | Flutterwave | Requires phoneNumber at charge time | | stripe | Stripe | Card element; NGN minimum enforced server-side | | sui_wallet | Sui + Payment Kit | Wallet connect via dApp Kit | | outpay | Payment Kit QR | outPay flow |

Fiat methods depend on backend env configuration (Flutterwave / Stripe keys). Crypto methods require registry IDs on the backend.

Custom UI (no modal)

  1. initCheckout → keep session.token and session.nonce.
  2. Optional: GET /v1/checkout/validate/:nonce for FX/settlement preview.
  3. POST /v1/checkout/charge with { token, method, phoneNumber? }.
  4. Poll GET /v1/checkout/status/:nonce or use SSE /v1/payments/stream/:nonce.
  5. For crypto: POST /v1/checkout/crypto/intent → wallet PTB → confirmCryptoPayment.

Charge and crypto endpoints are documented in Backend API.

Load from your backend

In production, either bundle the SDK with your app (npm install suioutkit) or serve the built sdk/dist statically from your web host. See the Developer Guide for recommended deployment patterns and backend integration: /docs/developer-guide.md.

Backend endpoints used by the SDK

All paths are relative to backendUrl.

| Method | Path | Used by | |--------|------|---------| | POST | /v1/checkout/session | initCheckout | | POST | /v1/checkout/charge | Modal (fiat) | | GET | /v1/checkout/status/:nonce | Modal polling | | GET | /v1/checkout/validate/:nonce | Modal pre-flight | | POST | /v1/checkout/crypto/intent | Modal (crypto) | | POST | /v1/checkout/crypto/confirm | Modal / confirmCryptoPayment | | GET | /v1/payments/stream/:nonce | Optional SSE (custom UI) |

Webhooks (/v1/checkout/webhook, /v1/checkout/stripe-webhook) are server-to-provider only.

Troubleshooting

| Symptom | Likely cause | |---------|----------------| | Failed to initialize checkout session | Backend down, CORS, or missing merchantAddress | | 409 Treasury insufficient | Operator vault underfunded for FX settlement amount | | Modal stuck on “waiting for settlement” | Webhook not reaching backend (Flutterwave hash, Stripe CLI, or ngrok) | | Stripe card errors on small NGN amounts | Backend enforces ~$0.50 USD equivalent minimum | | Crypto connect fails | Wrong mode or registry env on backend | | Styles missing | Backend not serving /style.css or wrong backendUrl |

See also Developer Guide - Troubleshooting.

Security

  • Only merchantAddress, mode, and backendUrl belong in browser code.
  • Never embed operator keys, Flutterwave secrets, or Stripe secret keys in the client.
  • Use HTTPS for the API endpoint in production (default when mode: "live").

Report vulnerabilities through your project’s private security channel (do not file public issues with key material).

License

GPL-3.0 - Copyright (c) 2026 The3rdWebLabs / @CYBWithFlourish