@siymo/otp-sdk-core
v1.0.0
Published
TypeScript SDK for the siymo-otp-service REST and WebSocket APIs
Maintainers
Readme
siymo-otp-sdk
TypeScript SDK for the REST and WebSocket contract exposed by siymo-otp-service.
Features
- Typed wrappers for OTP voice, SMS, inbound call, inbound SMS, verification, direct SMS, dongles, and health endpoints
- WebSocket subscription helper for
/ws/otp - Live attempt and lockout events during OTP verification
waitForConfirmation()helper for inbound OTP confirmation flowswaitForConfirmationLongPoll()helper for one-request HTTP long polling- Base URL can be passed directly or resolved from environment variables
Install
npm install siymo-otp-sdkConfiguration
The client resolves the service base URL in this order:
baseUrlpassed to the constructorSIYMO_OTP_BASE_URLOTP_BASE_URL
import { SiymoOtpClient } from 'siymo-otp-sdk';
const client = new SiymoOtpClient({
baseUrl: 'http://localhost:3000',
});Or with environment variables:
export SIYMO_OTP_BASE_URL=http://localhost:3000import { SiymoOtpClient } from 'siymo-otp-sdk';
const client = new SiymoOtpClient();Usage
Outbound OTP
import { SiymoOtpClient } from 'siymo-otp-sdk';
const client = new SiymoOtpClient();
const session = await client.initiateVoice({
phone: '+998901234567',
languages: ['uz', 'ru', 'en'],
repeat: true,
});
const verification = await client.verify({
sessionId: session.sessionId,
otp: '123456',
});Inbound OTP with WebSocket confirmation
import { SiymoOtpClient } from 'siymo-otp-sdk';
const client = new SiymoOtpClient({
baseUrl: 'http://localhost:3000',
});
const session = await client.initiateInboundSms({
phone: '+998990649000',
});
const confirmed = await client.waitForConfirmation(session.sessionId, {
timeoutMs: session.expiresIn * 1000,
onAttempt(event) {
console.log('Invalid attempt', event.data.attempts, 'tries left', event.data.triesLeft);
},
});
console.log(confirmed.data.verifiedAt);Inbound OTP with HTTP long polling
import { SiymoOtpClient } from 'siymo-otp-sdk';
const client = new SiymoOtpClient({
baseUrl: 'http://localhost:3000',
});
const session = await client.initiateInboundSms({
phone: '+998990649000',
expiration: 60,
});
const confirmed = await client.waitForConfirmationLongPoll(session.sessionId);
console.log(confirmed.status, confirmed.verifiedAt);Low-level WebSocket subscription
const subscription = client.subscribeToSession(session.sessionId, {
onSubscribed(event) {
console.log('Subscribed until', event.data.expiresAt);
},
onAttempt(event) {
console.log('Attempts used', event.data.attempts, 'tries left', event.data.triesLeft);
},
onLocked(event) {
console.log('Locked after', event.data.attempts, 'attempts');
},
onVerified(event) {
console.log('Verified', event.data.sessionId);
},
onExpired(event) {
console.log('Expired', event.data.sessionId);
},
});
// Later, if needed:
subscription.close();
await subscription.closed;Notes
- The SDK uses the service's existing WebSocket contract at
/ws/otp?sessionId=<uuid>. - The SDK also supports the long-poll endpoint at
GET /otp/wait?sessionId=<uuid>. - Inbound call and SMS initiation requests accept an optional
qrCode: trueflag. When requested, the response includesqrCodeImageas a data URL. - The WebSocket stream can emit
otp.subscribed,otp.attempt,otp.locked,otp.verified, andotp.expired. - In modern Node runtimes such as Node
22.x,WebSocketis available globally. If you need to override it, passwebSocketFactory. waitForConfirmation()keeps waiting throughotp.attemptevents, forwards WebSocket callbacks likeonAttempt, and rejects onotp.lockedorotp.expired.waitForConfirmationLongPoll()resolves on verification and rejects with the service error response if the session locks or expires.- Verification endpoints intentionally return
200 OKfor both success and logical verification failures. Inspect the typed response fields likeverified,message, andtriesLeft.
