swapped-onramp
v0.1.0
Published
A lightweight, type-safe TypeScript SDK for integrating Swapped.com's crypto on-ramp widget into web applications
Maintainers
Readme
Swapped On-ramp SDK
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
anytypes - 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-onrampUsing npm
npm install swapped-onrampUsing yarn
yarn add swapped-onrampUsing pnpm
pnpm add swapped-onrampQuick 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 typehandler: 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 filesTest 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 testPerformance
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.
