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

@spacepay/client-sdk

v1.0.26

Published

Lightweight SDK for SpacePay-like API - works in Node 18+ and modern browsers

Readme

SpacePay Client SDK

A lightweight, TypeScript-first SDK for integrating with SpacePay-like crypto payment gateways. Works in Node.js 18+ and modern browsers.

Features

  • 🚀 Lightweight - No heavy dependencies, minimal bundle size
  • 🔒 Type-safe - Full TypeScript support with comprehensive type definitions
  • 🌐 Universal - Works in Node.js 18+ and modern browsers
  • Modern - Uses native fetch API and modern JavaScript features
  • 🛡️ Robust - Built-in error handling, timeout management, and retry logic

This package focuses on external merchant APIs: secret-key payments (server-side) and payment-secret flows (browser-safe checkout client).

Installation

yarn add @spacepay/client-sdk

Backend (Node.js)

import { createBackendClient } from '@spacepay/client-sdk/backend'

const client = createBackendClient({
  apiBaseUrl: 'https://api.app.spacepay.solutions', // optional
  publicKey: 'your_public_key_here',
  secretKey: 'your_secret_key_here', // make sure to never expose this key on frontend
})

// Create a payment
const payment = await client.createPayment({
  amount: 5000, // 5000 cents = $50.00
  currency: 'USD',
  orderId: 'order_123',
})

console.log('Payment:', payment)
console.log('Payment URL:', payment.paymentUrl)
console.log('Payment Secret:', payment.secret)
console.log('Payment ID:', payment.paymentId)

Frontend (TypeScript / bundlers)

Hosted Checkout

For the most simple integration, redirect the user to paymentUrl returned from the createPayment request. After the payment completes, the user is redirected back to the success URL you set when creating the payment. For this flow, you do not need to load the frontend SDK at all.

Embedded Checkout

You can embed the SpacePay checkout UI into your own checkout page. We support 2 options, simple payment button, or full payment modal experience.

You can render a create order button and lazily create the payment on first click using fetchPaymentContext:

import { initPayment } from '@spacepay/client-sdk/frontend'

const checkoutButton = await initPayment({
  mode: 'embedded-button', // embedded-button, embedded-checkout, redirect
  fetchPaymentContext: async () => {
    // Called the first time the user clicks the \"Pay with crypto\" button
    const res = await fetch('/api/create-spacepay-order', { method: 'POST' })
    const { paymentId, paymentSecretKey } = await res.json()
    return { paymentId, paymentSecretKey }
  },
  onSuccess: (payload) => {
    // Called only in embedded-button and embedded-checkout modes
    console.log('Payment success', payload)
  },
})

checkoutButton.mount('#spacepay-checkout')

Alternatively, you can manage order lifecycle yourself and pass the payment details to the SDK:

import {
  initEmbeddedCheckoutButton,
  initEmbeddedCheckoutModal,
} from '@spacepay/client-sdk/frontend'

// Option 1 - Embedded button (inline iframe)
const checkoutButton = await initEmbeddedCheckoutButton({
  paymentId: 'payment_id_from_backend',
  paymentSecretKey: 'payment_secret_from_backend',
  onClose: (payload) => {
    console.log('Payment closed', payload)
  },
  onSuccess: (payload) => {
    console.log('Payment success', payload)
  },
  onError: (payload) => {
    console.log('Payment error', payload)
  },
})

checkoutButton.mount('#spacepay-checkout')
// Option 2 - Embedded full checkout in a modal
import {
  initEmbeddedCheckoutButton,
  initEmbeddedCheckoutModal,
} from '@spacepay/client-sdk/frontend'

const checkoutModal = await initEmbeddedCheckoutModal({
  paymentId: 'payment_id_from_backend',
  paymentSecretKey: 'payment_secret_from_backend',
  onClose: (payload) => {
    console.log('Payment closed', payload)
  },
  onSuccess: (payload) => {
    console.log('Payment success', payload)
  },
  onError: (payload) => {
    console.log('Payment error', payload)
  },
})

checkoutModal.mount()

Show payment details (optional)

Use the frontend checkout client for browser-safe usage (no secret key), and build your own UI. For they payment itself, redirect the user to paymentUrl (Hosted Checkout) or use Embedded Checkout option (below).

import {
  createCheckoutClient,
  initEmbeddedCheckoutButton,
  initEmbeddedCheckoutModal,
} from '@spacepay/client-sdk/frontend'

const paymentClient = createCheckoutClient({
  // Optional, defaults to https://api.app.spacepay.solutions
  apiBaseUrl: 'https://api.app.spacepay.solutions',
  publicKey: 'pk_...',
  paymentSecret: 'ps_...',
})

// Check payment status using payment client
const paymentStatus = await paymentClient.getPaymentStatus(paymentId)
console.log('Payment status:', paymentStatus.status)

// Get payment details using payment client
const paymentDetails = await paymentClient.getPaymentDetails(paymentId)
console.log('Payment details:', paymentDetails)
console.log('Deposit address:', paymentDetails.depositAddress?.address)

// Get active quotes for the payment using payment client
const quotes = await paymentClient.getActiveQuotes(paymentId)
console.log('Active quotes:', quotes)

CDN / Browser (global)

If you prefer a <script> tag, you can use the prebuilt browser bundle:

<script src="https://pub-e21c1fba794f48a6b4ec1facf5d68801.r2.dev/latest/spacepay-full.bundle.min.js"></script>
<script>
  ;(async function () {
    const checkout = await window.SpacePaySDK.initEmbeddedCheckoutButton({
      paymentId: 'payment_id_from_backend',
      paymentSecretKey: 'payment_secret_from_backend',
      onClose: (payload) => {
        console.log('Payment closed', payload)
      },
      onSuccess: (payload) => {
        console.log('Payment success', payload)
      },
      onError: (payload) => {
        console.log('Payment error', payload)
      },
    })

    checkout.mount('#spacepay-checkout')
  })()
</script>

The same bundle also exposes SpacePaySDK.createBackendClient and SpacePaySDK.createCheckoutClient for backend and frontend integration.

API Reference

Backend client options

type BackendClientOptions = {
  apiBaseUrl?: string // defaults to https://api.app.spacepay.solutions
  publicKey: string // Merchant public (access) key; sent as X-SpacePay-Access-Key
  secretKey: string // Sent as X-SpacePay-Secret-Key; never expose on the frontend
  timeoutMs?: number // default 30000
}

Checkout client options

type CheckoutClientOptions = {
  apiBaseUrl?: string
  publicKey: string
  paymentSecret: string // Sent as X-SpacePay-Payment-Secret
  timeoutMs?: number
}

Creating payments

interface CreatePaymentRequest {
  orderId: string
  currency: Currency // e.g. Currency.USD — only USD is supported by the API
  amount?: number // For default type `payment`: required by the API, minimum 250 cents. Ignored for type `deposit`.
  type?: 'payment' | 'deposit' // default `payment`
  redirectUrl?: string
  customMetadata?: string
}

const payment = await backendClient.createPayment({
  amount: 10000, // 10000 cents = $100.00 (must be ≥ 250 for type payment)
  currency: Currency.USD,
  orderId: 'order_456',
})

Optionally pass { idempotencyKey: '...' } as the second argument so retries of the same logical create reuse the same key and the server can deduplicate.

Listing payments

const page = await backendClient.listPayments({
  status: 'pending',
  limit: 50,
  offset: 0,
})
// page.data — PaymentDto[]; page.pagination — totals / hasMore, etc.

Getting payment details

Use getPaymentDetails to load the full payment record, including status.

const details = await backendClient.getPaymentDetails('payment_id_here')

Creating withdrawals

Send funds from the merchant balance to a recipient address. Minimum amountInCents is 100.

interface CreateWithdrawalRequest {
  amountInCents: number // minimum 100
  chainId: number
  recipientAddress: string
  orderId?: string
  customMetadata?: string
  currency?: Currency // API defaults to USD
}

const withdrawal = await backendClient.createWithdrawal(
  {
    amountInCents: 10_000,
    chainId: 1,
    recipientAddress: '0x...',
    orderId: 'internal_ref_optional',
    currency: Currency.USD,
  },
  { idempotencyKey: 'optional-stable-key' }
)

For withdrawals, use the same optional { idempotencyKey: '...' } second argument when you need retry-safe creates.

Listing withdrawals

const withdrawalsPage = await backendClient.listWithdrawals({
  status: 'pending',
  limit: 50,
  offset: 0,
})
// withdrawalsPage.data — WithdrawalDto[]; withdrawalsPage.pagination — same shape as payments

Getting withdrawal details

const one = await backendClient.getWithdrawalDetails(withdrawal.id)

Payment status and refresh (checkout client)

Use the checkout client with the payment secret for getPaymentStatus and refreshPaymentStatus when polling or refreshing payment state from the browser.

const checkout = createCheckoutClient({
  publicKey: 'pk_...',
  paymentSecret: 'from_create_payment_response',
})
const status = await checkout.getPaymentStatus('payment_id_here')
// { id, status }

await checkout.refreshPaymentStatus('payment_id_here', {
  transactionHash: '0x...', // all optional
})

Quotes (checkout client)

// Default quote (no contract / chain — per API)
await checkout.createOrUpdateQuote(paymentId, {})

// Specific token
await checkout.createOrUpdateQuote(paymentId, {
  contractAddress: '0x...',
  chainId: 1,
})

Payment (incl. deposits) and withdrawal states:

Payment status (and PaymentStatusDto.status):

  • pending — created, awaiting funds
  • processing — transfer observed / confirming
  • completed — settled successfully
  • failed — failed or rejected
  • expired — expired before completion
  • cancelled — cancelled

Withdrawal status (on WithdrawalDto):

  • pending — created, awaiting processing
  • processing — in progress
  • completed — settled successfully
  • failed — failed or rejected
  • cancelled — cancelled

SDK Development

Prerequisites

  • Node.js 18+
  • npm or yarn

Setup

# Install dependencies
yarn install

# Build the project (includes format checking)
yarn build

# Development mode with watch
yarn dev

# Clean build artifacts
yarn clean

# Format code with Prettier
yarn format

# Check code formatting
yarn format:check

# Lint code with ESLint
yarn lint

# Fix linting issues automatically
yarn lint:fix

Project Structure

src/
├── index.ts              # Re-exports frontend + backend factories
├── frontend.ts           # Browser-safe entry (checkout client, embeds, utils)
├── backend.ts            # Node / server entry (secret key client)
├── client/               # HTTP clients
│   ├── base-client.ts
│   ├── backend-client.ts
│   ├── checkout-client.ts
│   ├── spacepay.ts
│   └── index.ts
├── embedded/             # Embedded checkout / wallet UI helpers
├── types/
│   ├── index.ts
│   ├── payment.ts
│   ├── config.ts
│   └── errors.ts
└── utils/
    ├── index.ts
    ├── formatting.ts
    ├── url.ts
    └── validation.ts

Code Quality

This project uses both Prettier and ESLint for code quality:

Prettier - Code formatting (.prettierrc):

ESLint - Code linting (eslint.config.js)

The build process automatically checks both formatting and linting, ensuring code quality standards are met.

Browser Support

This SDK works in modern browsers that support:

  • Fetch API
  • AbortController

For older browsers, you may need to include polyfills for these features.

Node.js Support

  • Node.js 18+: Full support with native fetch API
  • Node.js 16-17: Requires node-fetch polyfill
  • Node.js <16: Not supported

License

MIT License - see LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

Support

For support and questions:

  • Create an issue on GitHub
  • Check the examples directory
  • Review the API documentation