Official TypeScript SDK for Smart Pay Chain OTP Verification Service - Now with phone authentication, JWT tokens, admin support, and brand management
npm install @smart-pay-chain/otp






Official TypeScript/JavaScript SDK for Smart Pay Chain OTP Verification Service
Website โข Documentation โข NPM Package โข GitHub
---
Send and verify one-time passwords via SMS, WhatsApp, and Voice with ease.
๐ 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
๐ 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
โจ 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
``bash`
npm install @smart-pay-chain/otp
or
`bash`
yarn add @smart-pay-chain/otp
`typescript
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! โ');
}
`
- What's New in v2.0
- Installation
- Quick Start
- Test Mode
- Configuration
- Usage
- Sending OTP
- Verifying OTP
- Resending OTP
- Checking Status
- SDK Configuration
- Mobile App Integration
- Error Handling
- Idempotency
- API Reference
- Examples
- Migration from v1 to v2
- Testing
- Contributing
- License
Test mode allows you to test OTP flows without sending real SMS messages. Perfect for development and automated testing!
`typescript
// 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:
`typescript`
// 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
`typescript`
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',
},
});
Send an OTP to a phone number using your preferred channel:
`typescript
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
`
Verify the OTP code entered by the user:
`typescript
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
}
`
Resend the OTP if the user didn't receive it:
`typescript
const result = await client.resendOtp({
requestId: 'req_123456',
});
console.log('New request ID:', result.requestId);
console.log('Expires at:', result.expiresAt);
`
Check the current status of an OTP request:
`typescript
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);
`
Get server configuration (auto-cached for 1 hour):
`typescript
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);
`
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:
`typescript
// 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' }),
});
`
The SDK provides specific error classes for different scenarios:
`typescript
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);
}
}
`
All OTP errors include:
- message: Human-readable error messagecode
- : Error code (e.g., OTP_EXPIRED, INVALID_OTP_CODE)statusCode
- : HTTP status coderetryable
- : Whether the request can be retrieddetails
- : Additional error details (optional)requestId
- : Request ID for debugging (optional)
The SDK automatically generates unique idempotency keys for send/resend operations to prevent duplicate requests:
`typescript
// 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
#### constructor(config: OtpClientConfig)
Create a new OTP client instance.
#### sendOtp(options: SendOtpOptions): Promise
Send an OTP to a phone number.
Parameters:
- phoneNumber (string, required): Phone number in E.164 formatchannel
- (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 metadataidempotencyKey
- (string, optional): Idempotency key
Returns:
- requestId (string): Unique request identifierexpiresAt
- (Date): Expiration timestampstatus
- (string): Current status
#### verifyOtp(options: VerifyOtpOptions): Promise
Verify an OTP code.
Parameters:
- requestId (string, required): Request ID from sendOtpcode
- (string, required): OTP code to verifyipAddress
- (string, optional): User's IP addressuserAgent
- (string, optional): User's user agent
Returns:
- success (boolean): Whether verification succeededmessage
- (string): Result message
#### resendOtp(options: ResendOtpOptions): Promise
Resend an OTP.
Parameters:
- requestId (string, required): Original request ID
Returns:
Same as sendOtp()
#### getStatus(requestId: string): Promise
Get OTP status (authenticated endpoint).
Parameters:
- requestId (string, required): Request ID
Returns:
- id (string): Request IDphoneNumber
- (string): Phone number (masked)channel
- (OtpChannel): Delivery channelstatus
- (string): Current statusattempts
- (number): Verification attemptsmaxAttempts
- (number): Maximum attempts allowedexpiresAt
- (Date): Expiration timeverifiedAt
- (Date | null): Verification timecreatedAt
- (Date): Creation timeisExpired
- (boolean): Whether OTP is expired
#### getStatusWithCode(requestId: string): Promise
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 codesmsProvider
- (string | null): SMS provider usedsmsMessageId
- (string | null): Provider message ID
#### getConfig(forceRefresh?: boolean): Promise
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
Test connectivity to the OTP service.
Returns: true if connected, false otherwise
#### isTestMode(): Promise
Check if server is in test mode.
Returns: true if test mode is enabled
#### OtpChannel
`typescript`
enum OtpChannel {
SMS = 'SMS',
WHATSAPP = 'WHATSAPP',
VOICE = 'VOICE',
}
#### ErrorCode
`typescript`
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.
The SDK includes comprehensive examples:
- Basic Usage - Simple send and verify flow
- Advanced Usage - Error handling, metadata, retries
- Test Mode ๐ - Testing with fixed OTP codes
- Express Integration - Backend API with Express.js
- Phone Authentication ๐ - Complete passwordless auth with JWT
- React Integration - Frontend form with React
- React Native ๐ - Mobile app integration
- Mobile Apps Guide ๐ - Flutter, iOS, Android examples
- Backend Integration Guide ๐ - Full sms-service integration
See the examples directory for more details.
All v1.0 code continues to work in v2.0! No breaking changes.
New Features in v2.0:
`typescript
// 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
Run the test suite:
`bash`
npm test
Run tests in watch mode:
`bash`
npm run test:watch
Generate coverage report:
`bash``
npm test -- --coverage
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
- Node.js >= 16.0.0
- TypeScript >= 5.0.0 (if using TypeScript)
Need help? We're here for you!
- ๐ Website: smartpaychain.com
- ๐ Documentation: docs.smartpaychain.com
- ๐ Issues: GitHub Issues
- ๐ง Email: support@smartpaychain.com
- ๐ฌ Community: Join our Discord
Contributions are welcome! Please read our Contributing Guide for details.
MIT License - see the LICENSE file for details.
See CHANGELOG.md for version history.
---
Smart Pay Chain is a leading provider of blockchain-based payment solutions and verification services.
๐ smartpaychain.com | ๐ง contact@smartpaychain.com
Products & Services
- ๐ OTP Verification Service (SMS, WhatsApp, Voice)
- ๐ณ Payment Processing Solutions
- โ๏ธ Blockchain Integration Services
- ๐ Secure Authentication Systems
---
Made with โค๏ธ by Smart Pay Chain


ยฉ 2025 Smart Pay Chain. All rights reserved.