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

@smart-pay-chain/otp

v2.1.7

Published

Official TypeScript SDK for Smart Pay Chain OTP Verification Service - Now with phone authentication, JWT tokens, admin support, and brand management

Readme

@smart-pay-chain/otp

npm version npm downloads License: MIT TypeScript Node.js Version Build Status Coverage

Official TypeScript/JavaScript SDK for Smart Pay Chain OTP Verification Service

WebsiteDocumentationNPM PackageGitHub


Send and verify one-time passwords via SMS, WhatsApp, and Voice with ease.

What's New in v2.1

🆕 Phone Authentication - Complete passwordless auth with JWT tokens
🆕 Admin Role Support - RBAC with USER/ADMIN roles
🆕 Brand Management - Two-stage brand approval workflow
🆕 API Key Handling - Secure key generation and one-time secret reveal
🆕 Backend Integration - Full guide for sms-service integration

What's New in v2.0

🆕 Test Mode - Development-friendly testing with fixed OTP codes and test phone numbers
🆕 Status Endpoints - Check OTP status and get codes for testing
🆕 Auto-Configuration - SDK auto-configures from server settings
🆕 Mobile Examples - Complete React Native integration example
🆕 Idempotency - Automatic idempotency keys for retry safety
🆕 Enhanced Errors - Machine-readable error codes for better handling

See Migration Guide

Features

Multiple Channels - Send OTPs via SMS, WhatsApp, or Voice
🔒 Secure - Built-in encryption, timing-safe comparisons, and rate limiting
🎯 Type-Safe - Full TypeScript support with comprehensive type definitions
🔄 Retry Logic - Automatic retries for transient failures
📱 Mobile Ready - React Native example and mobile integration guide
🔐 Phone Authentication - Complete passwordless auth with JWT tokens
👥 Admin Support - Role-based access control (RBAC)
🏢 Brand Management - Two-stage approval workflow
🧪 Test Mode - Development testing with fixed codes
📦 Lightweight - Minimal dependencies
🧪 Well-Tested - Comprehensive test coverage
📚 Well-Documented - Extensive documentation and examples

Installation

npm install @smart-pay-chain/otp

or

yarn add @smart-pay-chain/otp

Quick Start

import { OtpClient, OtpChannel } from '@smart-pay-chain/otp';

// Initialize the client
const client = new OtpClient({
  apiKey: 'your-api-key-here',
  autoConfig: true, // v2.0: Auto-fetch server configuration
});

// Send an OTP
const result = await client.sendOtp({
  phoneNumber: '+995568000865',
  channel: OtpChannel.SMS,
});

console.log('OTP sent! Request ID:', result.requestId);

// v2.0: Check status
const status = await client.getStatus(result.requestId);
console.log('Current status:', status.status);

// Verify the OTP
const verification = await client.verifyOtp({
  requestId: result.requestId,
  code: '123456', // Code entered by user
});

if (verification.success) {
  console.log('Phone number verified! ✓');
}

Table of Contents

Test Mode

Test mode allows you to test OTP flows without sending real SMS messages. Perfect for development and automated testing!

// Check if server is in test mode
const testMode = await client.isTestMode();
if (testMode) {
  console.log('Test mode enabled - use test phone numbers');
}

// Use test phone numbers
import { TEST_PHONE_NUMBERS, TEST_OTP_CODE } from '@smart-pay-chain/otp';

const result = await client.sendOtp({
  phoneNumber: TEST_PHONE_NUMBERS.SUCCESS, // +15005550006
});

// In test mode, OTP code is always: 123456
const verification = await client.verifyOtp({
  requestId: result.requestId,
  code: TEST_OTP_CODE, // '123456'
});

Test Phone Numbers:

  • +15005550006 - Always succeeds
  • +15005550007 - SMS send fails
  • +15005550008 - Rate limit exceeded
  • +15005550009 - Insufficient balance
  • +15005550010 - Brand not authorized

For Development/Testing Only:

// Get actual OTP code (WARNING: Never use in production!)
const status = await client.getStatusWithCode(result.requestId);
console.log('OTP Code:', status.otpCode); // For automated tests

Configuration

Client Options

const client = new OtpClient({
  apiKey: 'your-api-key-here',        // Required: Your API key
  baseUrl: 'https://custom.api.com',  // Optional: Custom base URL
  timeout: 30000,                      // Optional: Request timeout (ms)
  maxRetries: 3,                       // Optional: Max retry attempts
  autoConfig: true,                    // Optional: Auto-fetch server config
  platform: 'react-native',            // Optional: SDK platform
  language: 'typescript',              // Optional: SDK language
  headers: {                           // Optional: Custom headers
    'X-App-Version': '1.0.0',
  },
});

Usage

Sending OTP

Send an OTP to a phone number using your preferred channel:

const result = await client.sendOtp({
  phoneNumber: '+995568000865',    // Required: E.164 format
  channel: OtpChannel.SMS,          // Optional: SMS, WHATSAPP, or VOICE
  ttl: 300,                         // Optional: Time-to-live (60-600 seconds)
  length: 6,                        // Optional: Code length (4-8 digits)
  metadata: {                       // Optional: Custom metadata
    userId: 'user_12345',
    action: 'login',
  },
  idempotencyKey: 'unique-key',    // Optional: Prevent duplicate sends
});

console.log(result.requestId);     // Save this for verification
console.log(result.expiresAt);     // When the OTP expires
console.log(result.status);        // Current status

Verifying OTP

Verify the OTP code entered by the user:

const result = await client.verifyOtp({
  requestId: 'req_123456',         // From sendOtp response
  code: '123456',                   // User-entered code
  ipAddress: '192.168.1.1',        // Optional but recommended
  userAgent: 'Mozilla/5.0...',     // Optional
});

if (result.success) {
  console.log('Verified!', result.message);
  // Proceed with authentication
} else {
  console.log('Failed:', result.message);
  // Show error to user
}

Resending OTP

Resend the OTP if the user didn't receive it:

const result = await client.resendOtp({
  requestId: 'req_123456',
});

console.log('New request ID:', result.requestId);
console.log('Expires at:', result.expiresAt);

Checking Status

Check the current status of an OTP request:

const status = await client.getStatus('req_123456');

console.log('Status:', status.status); // 'PENDING' | 'SENT' | 'VERIFIED' | 'EXPIRED' | 'FAILED'
console.log('Attempts:', status.attempts);
console.log('Max attempts:', status.maxAttempts);
console.log('Is expired:', status.isExpired);
console.log('Expires at:', status.expiresAt);

SDK Configuration

Get server configuration (auto-cached for 1 hour):

const config = await client.getConfig();

console.log('OTP config:', config.otpConfig);
console.log('Rate limits:', config.rateLimits);
console.log('Test mode:', config.features.testMode);
console.log('Supported countries:', config.supportedCountries);

Mobile App Integration

The SDK is designed to run on your backend server, not directly in mobile apps. This keeps your API keys secure.

See our comprehensive Mobile Apps Guide for:

  • React Native integration (complete example)
  • Flutter/Dart integration
  • iOS native (Swift)
  • Android native (Kotlin)
  • Passwordless authentication with refresh tokens
  • Security best practices

Quick Example:

// Backend API
router.post('/auth/send-otp', async (req, res) => {
  const result = await otpClient.sendOtp({
    phoneNumber: req.body.phoneNumber,
  });
  res.json({ requestId: result.requestId });
});

// Mobile app calls your backend
fetch('https://yourapi.com/auth/send-otp', {
  method: 'POST',
  body: JSON.stringify({ phoneNumber: '+995568000865' }),
});

Error Handling

The SDK provides specific error classes for different scenarios:

import {
  OtpError,
  AuthenticationError,
  ValidationError,
  RateLimitError,
  OtpExpiredError,
  InvalidOtpError,
} from '@smart-pay-chain/otp';

try {
  const result = await client.verifyOtp({ ... });
} catch (error) {
  if (error instanceof InvalidOtpError) {
    console.log('Wrong code. Please try again.');
  } else if (error instanceof OtpExpiredError) {
    console.log('OTP expired. Request a new one.');
  } else if (error instanceof RateLimitError) {
    console.log('Too many attempts. Please wait.');
  } else if (error instanceof OtpError) {
    // Generic OTP error
    console.log('Error:', error.message);
    console.log('Code:', error.code);
    console.log('Retryable:', error.retryable);
  }
}

Error Properties

All OTP errors include:

  • message: Human-readable error message
  • code: Error code (e.g., OTP_EXPIRED, INVALID_OTP_CODE)
  • statusCode: HTTP status code
  • retryable: Whether the request can be retried
  • details: Additional error details (optional)
  • requestId: Request ID for debugging (optional)

Idempotency

The SDK automatically generates unique idempotency keys for send/resend operations to prevent duplicate requests:

// Automatic idempotency (recommended)
const result = await client.sendOtp({
  phoneNumber: '+995568000865',
  // SDK auto-generates: X-Idempotency-Key: {timestamp}-{random}
});

// Manual idempotency key (for custom requirements)
const result = await client.sendOtp({
  phoneNumber: '+995568000865',
  idempotencyKey: 'my-unique-key-123',
});

Benefits:

  • Prevents duplicate OTPs on network retries
  • Safe for flaky mobile networks
  • Automatic for all send/resend operations

API Reference

OtpClient

constructor(config: OtpClientConfig)

Create a new OTP client instance.

sendOtp(options: SendOtpOptions): Promise<SendOtpResponse>

Send an OTP to a phone number.

Parameters:

  • phoneNumber (string, required): Phone number in E.164 format
  • channel (OtpChannel, optional): Delivery channel (default: SMS)
  • ttl (number, optional): Time-to-live in seconds (60-600, default: 300)
  • length (number, optional): OTP code length (4-8, default: 6)
  • metadata (object, optional): Custom metadata
  • idempotencyKey (string, optional): Idempotency key

Returns:

  • requestId (string): Unique request identifier
  • expiresAt (Date): Expiration timestamp
  • status (string): Current status

verifyOtp(options: VerifyOtpOptions): Promise<VerifyOtpResponse>

Verify an OTP code.

Parameters:

  • requestId (string, required): Request ID from sendOtp
  • code (string, required): OTP code to verify
  • ipAddress (string, optional): User's IP address
  • userAgent (string, optional): User's user agent

Returns:

  • success (boolean): Whether verification succeeded
  • message (string): Result message

resendOtp(options: ResendOtpOptions): Promise<SendOtpResponse>

Resend an OTP.

Parameters:

  • requestId (string, required): Original request ID

Returns: Same as sendOtp()

getStatus(requestId: string): Promise<OtpStatus>

Get OTP status (authenticated endpoint).

Parameters:

  • requestId (string, required): Request ID

Returns:

  • id (string): Request ID
  • phoneNumber (string): Phone number (masked)
  • channel (OtpChannel): Delivery channel
  • status (string): Current status
  • attempts (number): Verification attempts
  • maxAttempts (number): Maximum attempts allowed
  • expiresAt (Date): Expiration time
  • verifiedAt (Date | null): Verification time
  • createdAt (Date): Creation time
  • isExpired (boolean): Whether OTP is expired

getStatusWithCode(requestId: string): Promise<OtpStatusWithCode>

Get OTP status with code (public endpoint, for testing/development only).

WARNING: This returns the actual OTP code. Only use in test/development!

Returns: Same as getStatus() plus:

  • otpCode (string): The actual OTP code
  • smsProvider (string | null): SMS provider used
  • smsMessageId (string | null): Provider message ID

getConfig(forceRefresh?: boolean): Promise<SdkConfiguration>

Get SDK configuration from server (cached for 1 hour).

Parameters:

  • forceRefresh (boolean, optional): Force refresh cached config

Returns: Server configuration including rate limits, features, test mode status, etc.

testConnection(): Promise<boolean>

Test connectivity to the OTP service.

Returns: true if connected, false otherwise

isTestMode(): Promise<boolean>

Check if server is in test mode.

Returns: true if test mode is enabled

Types

OtpChannel

enum OtpChannel {
  SMS = 'SMS',
  WHATSAPP = 'WHATSAPP',
  VOICE = 'VOICE',
}

ErrorCode

enum ErrorCode {
  AUTHENTICATION_FAILED = 'AUTHENTICATION_FAILED',
  INVALID_API_KEY = 'INVALID_API_KEY',
  INVALID_PHONE_NUMBER = 'INVALID_PHONE_NUMBER',
  OTP_EXPIRED = 'OTP_EXPIRED',
  OTP_MAX_ATTEMPTS = 'OTP_MAX_ATTEMPTS',
  INVALID_OTP_CODE = 'INVALID_OTP_CODE',
  OTP_NOT_FOUND = 'OTP_NOT_FOUND',
  RATE_LIMIT_EXCEEDED = 'RATE_LIMIT_EXCEEDED',
  // ... and more
}

See types.ts for complete type definitions.

Examples

The SDK includes comprehensive examples:

See the examples directory for more details.

Migration from v1 to v2

All v1.0 code continues to work in v2.0! No breaking changes.

New Features in v2.0:

// v2.0 additions (optional)
const client = new OtpClient({
  apiKey: 'your-key',
  autoConfig: true,  // NEW: Auto-fetch server config
});

// NEW: Check OTP status
const status = await client.getStatus(requestId);

// NEW: Get OTP code for testing
const testStatus = await client.getStatusWithCode(requestId);

// NEW: Check test mode
const testMode = await client.isTestMode();

// NEW: Test connectivity
const connected = await client.testConnection();

Automatic Improvements:

  • Idempotency keys auto-generated for all send/resend operations
  • SDK version tracking headers automatically included
  • Enhanced error codes for better error handling

Testing

Run the test suite:

npm test

Run tests in watch mode:

npm run test:watch

Generate coverage report:

npm test -- --coverage

Best Practices

  1. Security

    • Never expose your API key in frontend code
    • Use backend endpoints to proxy OTP requests
    • Implement rate limiting on your endpoints
    • Use HTTPS for all requests
  2. User Experience

    • Show clear error messages to users
    • Display OTP expiration time
    • Implement resend functionality
    • Limit verification attempts (3-5 max)
  3. Production

    • Use environment variables for API keys
    • Implement proper logging and monitoring
    • Handle all error cases gracefully
    • Use idempotency keys for critical flows

Requirements

  • Node.js >= 16.0.0
  • TypeScript >= 5.0.0 (if using TypeScript)

Support

Need help? We're here for you!

Contributing

Contributions are welcome! Please read our Contributing Guide for details.

License

MIT License - see the LICENSE file for details.

Changelog

See CHANGELOG.md for version history.


🏢 About Smart Pay Chain

Smart Pay Chain is a leading provider of blockchain-based payment solutions and verification services.

🌐 smartpaychain.com | 📧 [email protected]

Products & Services

  • 🔐 OTP Verification Service (SMS, WhatsApp, Voice)
  • 💳 Payment Processing Solutions
  • ⛓️ Blockchain Integration Services
  • 🔒 Secure Authentication Systems

Made with ❤️ by Smart Pay Chain

Follow us on Twitter Star on GitHub

© 2025 Smart Pay Chain. All rights reserved.