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

swapped-onramp

v0.1.0

Published

A lightweight, type-safe TypeScript SDK for integrating Swapped.com's crypto on-ramp widget into web applications

Readme

Swapped On-ramp SDK

TypeScript Bun License Tests Zero Dependencies Bundle Size

A lightweight, type-safe TypeScript SDK for integrating Swapped.com's crypto on-ramp widget into web applications. Built with functional programming principles, Bun-native optimizations, and comprehensive type coverage.

Overview

The Swapped On-ramp SDK provides a robust, type-safe interface for embedding the Swapped.com on-ramp widget into your web applications. Designed with performance and developer experience in mind, it leverages modern TypeScript features and browser native APIs to deliver a seamless integration experience.

Key Design Principles:

  • Type Safety: Complete TypeScript coverage with zero tolerance for any types
  • Functional Architecture: Pure functions with immutable data structures
  • Performance First: Minimal allocations and efficient data handling
  • Zero Dependencies: Uses only browser built-in APIs
  • Developer Experience: Intuitive API design with comprehensive error handling

Features

  • Complete Type Coverage: Every widget event and configuration is fully typed
  • Functional Programming: Factory function pattern for widget creation
  • Type-Safe Events: Comprehensive event system with typed handlers
  • PostMessage Security: Origin validation for secure iframe communication
  • Comprehensive Error Handling: Typed error classes for all failure scenarios
  • Zero Runtime Dependencies: Uses only browser built-in capabilities
  • Immutable Data Structures: All types are readonly for safety

Installation

Using Bun (Recommended)

bun add swapped-onramp

Using npm

npm install swapped-onramp

Using yarn

yarn add swapped-onramp

Using pnpm

pnpm add swapped-onramp

Quick Start

import { createWidget } from 'swapped-onramp'

// Initialize the widget
const widget = createWidget({
  apiKey: 'your-api-key',
  container: '#widget-container',
  environment: 'sandbox',
})

// Listen for order events
widget.on('order:completed', (event) => {
  console.log('Order completed:', event.order)
  console.log('Order ID:', event.orderId)
})

widget.on('order:failed', (event) => {
  console.error('Order failed:', event.error)
})

// Mount the widget
widget.mount()

Configuration

The SDK accepts a configuration object with the following options:

import { createWidget, type SwappedWidgetConfig } from 'swapped-onramp'

const config: SwappedWidgetConfig = {
  apiKey: 'your-api-key-here',        // Required: Your Swapped API key
  container: '#widget-container',      // Required: Container selector or HTMLElement
  environment: 'sandbox',              // Optional: 'sandbox' | 'production' (default: 'production')
  widgetUrl: undefined,                // Optional: Custom widget URL (overrides environment)
  
  // Widget customization
  defaultCryptoCurrency: 'BTC',        // Optional: Default cryptocurrency
  defaultFiatCurrency: 'USD',          // Optional: Default fiat currency
  defaultAmount: '100',                // Optional: Default purchase amount
  theme: {                             // Optional: Theme configuration
    primaryColor: '#0066FF',
    borderRadius: '8px',
    mode: 'light',
  },
  paymentMethods: ['card', 'bank'],    // Optional: Filter payment methods
  
  // Legacy callbacks (deprecated, use event handlers instead)
  onReady: () => console.log('Widget ready'),
  onError: (error) => console.error('Error:', error),
}

Environment Variables

For production applications, it's recommended to use environment variables:

const widget = createWidget({
  apiKey: process.env.SWAPPED_API_KEY!,
  container: '#widget-container',
  environment: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox',
})

API Reference

Widget Factory

createWidget(config: SwappedWidgetConfig): SwappedWidget

Creates a new widget instance.

Parameters:

  • config: Widget configuration object

Returns: A new SwappedWidget instance

Throws: SwappedValidationError if configuration is invalid

Widget Methods

widget.mount(): void

Mounts the widget iframe to the container element.

Throws: SwappedInitializationError if mounting fails

widget.unmount(): void

Unmounts the widget iframe from the container (keeps event handlers).

widget.destroy(): void

Destroys the widget and cleans up all resources, including event handlers.

widget.on<T>(event: T, handler: WidgetEventHandler<T>): void

Registers an event handler for the specified event type.

Parameters:

  • event: Event type (e.g., 'order:completed')
  • handler: Event handler function

widget.off<T>(event: T, handler: WidgetEventHandler<T>): void

Unregisters an event handler for the specified event type.

Parameters:

  • event: Event type
  • handler: Event handler function to remove

widget.updateConfig(config: Partial<SwappedWidgetConfig>): void

Updates the widget configuration. If significant changes are made (API key, environment, widget URL), the widget will be remounted.

Parameters:

  • config: Partial configuration object

Widget Properties

widget.isMounted: boolean (readonly)

Returns true if the widget is currently mounted.

widget.config: Readonly<SwappedWidgetConfig> (readonly)

Returns the current widget configuration.

Event Types

The widget emits the following event types:

  • 'ready' - Widget is ready and loaded
  • 'order:created' - New order created
  • 'order:status_changed' - Order status changed
  • 'order:completed' - Order completed successfully
  • 'order:failed' - Order failed
  • 'order:cancelled' - Order was cancelled
  • 'error' - Widget error occurred

Event Examples

// Order completed
widget.on('order:completed', (event) => {
  console.log('Order ID:', event.orderId)
  console.log('Order:', event.order)
  console.log('Timestamp:', event.timestamp)
})

// Order status changed
widget.on('order:status_changed', (event) => {
  console.log(`Order ${event.orderId} changed from ${event.previousStatus} to ${event.status}`)
})

// Error handling
widget.on('error', (event) => {
  console.error('Widget error:', event.error)
  console.error('Error code:', event.code)
})

Error Handling

The SDK provides typed error classes for different error scenarios:

import {
  SwappedError,
  SwappedWidgetError,
  SwappedValidationError,
  SwappedPostMessageError,
  SwappedInitializationError,
} from 'swapped-onramp'

Error Handling Example

try {
  const widget = createWidget({
    apiKey: 'invalid-key',
    container: '#widget-container',
  })
  widget.mount()
} catch (error) {
  if (error instanceof SwappedValidationError) {
    console.error('Validation error:', error.message)
    console.error('Details:', error.details)
  } else if (error instanceof SwappedInitializationError) {
    console.error('Initialization failed:', error.message)
  } else if (error instanceof SwappedError) {
    console.error(`Error (${error.code}): ${error.message}`)
  }
}

TypeScript Support

The SDK is fully typed with comprehensive TypeScript definitions. All types are exported and can be imported for use in your application.

Type Imports

import type {
  // Core types
  SwappedWidgetConfig,
  SwappedWidget,
  Environment,
  ThemeConfig,
  
  // Event types
  WidgetEventType,
  WidgetEvent,
  WidgetEventHandler,
  OrderCreatedEvent,
  OrderStatusChangedEvent,
  OrderCompletedEvent,
  
  // Order types
  Order,
  OrderStatus,
  
  // Currency types
  CryptocurrencySymbol,
  FiatCurrencyCode,
} from 'swapped-onramp'

Examples

Basic Integration

import { createWidget } from 'swapped-onramp'

const widget = createWidget({
  apiKey: process.env.SWAPPED_API_KEY!,
  container: document.getElementById('widget-container')!,
  environment: 'sandbox',
})

widget.on('ready', () => {
  console.log('Widget is ready!')
})

widget.on('order:completed', (event) => {
  // Handle completed order
  console.log('Order completed:', event.orderId)
})

widget.mount()

React Integration

import { useEffect, useRef } from 'react'
import { createWidget, type SwappedWidget } from 'swapped-onramp'

function SwappedWidgetComponent({ apiKey }: { apiKey: string }) {
  const widgetRef = useRef<SwappedWidget | null>(null)
  const containerRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (!containerRef.current) return

    const widget = createWidget({
      apiKey,
      container: containerRef.current,
      environment: 'sandbox',
    })

    widget.on('order:completed', (event) => {
      console.log('Order completed:', event.orderId)
    })

    widget.mount()
    widgetRef.current = widget

    return () => {
      widget.destroy()
    }
  }, [apiKey])

  return <div ref={containerRef} style={{ width: '100%', height: '600px' }} />
}

Vue Integration

<template>
  <div ref="container" style="width: 100%; height: 600px"></div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { createWidget, type SwappedWidget } from 'swapped-onramp'

const container = ref<HTMLDivElement | null>(null)
let widget: SwappedWidget | null = null

onMounted(() => {
  if (!container.value) return

  widget = createWidget({
    apiKey: import.meta.env.VITE_SWAPPED_API_KEY,
    container: container.value,
    environment: 'sandbox',
  })

  widget.on('order:completed', (event) => {
    console.log('Order completed:', event.orderId)
  })

  widget.mount()
})

onUnmounted(() => {
  widget?.destroy()
})
</script>

Testing

The SDK includes comprehensive test coverage with 32 passing unit tests covering all core functionality.

Test Results

✅ 32 unit tests passing
✅ 0 unit tests failing
✅ 70 assertions
✅ 100% core functionality covered
✅ 5 test files

Test Coverage:

  • Error handling and factory functions (5 tests)
  • PostMessage utilities (7 tests)
  • Environment helpers (7 tests)
  • URL building and configuration (9 tests)
  • Validation utilities (4 tests)

Run tests with:

bun test

Performance

The SDK is designed with performance as a core consideration.

Bundle Size

The SDK is optimized for minimal bundle size:

  • Bundled Size: 7.6 KB (uncompressed)
  • Gzipped Size: 2.3 KB
  • Zero Runtime Dependencies: No external packages required
  • Tree-Shakeable: Only import what you need
  • Type Definitions: Included inline, no separate @types package needed

Performance Characteristics

  • Pure Functions: No unnecessary object creation or mutations
  • Immutable Types: All data structures are readonly, enabling safe sharing
  • Minimal Dependencies: Zero runtime dependencies, uses only browser built-ins
  • Type Safety: Compile-time checks eliminate runtime type errors

Browser Support

  • Modern browsers with iframe and postMessage support
  • ES2020+ features (async/await, optional chaining, etc.)
  • No polyfills required

Requirements

  • TypeScript: >= 5.0.0
  • Modern Browser: ES2020+ support

Documentation

For complete API documentation and integration guides, visit:

Swapped.com Documentation: https://docs.swapped.com/

License

MIT

See LICENSE file for details.