Suspends until the OTP is captured from the WhatsApp client, then resolves with the code.
Call this after startHandshake (and after your backend has sent the template). It resolves with the code delivered by the WhatsApp client, or rejects if the WhatsApp client reports an error (e.g. a signature-hash mismatch or a stale handshake).
No native timeout. This call waits indefinitely until a code arrives or the flow fails.
The Eitri-App owns the timeout: race awaitCode() against your own deadline and call
cancelAwaitCode to abandon a stuck wait.
One wait at a time. Only a single awaitCode() may be active concurrently. A second,
overlapping call rejects with awaitCode.alreadyInProgress rather than silently discarding
the first wait.
Platform availability: Android only. On iOS this method throws
eitri.whatsAppOtp.notSupportedOnIOS.
Example (with an Eitri-App-owned timeout):
const modules = await Eitri.modules()
const awaitCode = modules?.whatsAppOtp?.awaitCode
const cancelAwaitCode = modules?.whatsAppOtp?.cancelAwaitCode
if (!awaitCode || !cancelAwaitCode) return
const timeout = new Promise<never>((_, reject) =>
setTimeout(() => reject(new Error("otp.timeout")), 60_000)
)
try {
const code = await Promise.race([awaitCode(), timeout])
await myBackend.verifyOtp({ phone, code })
} catch (error) {
// On timeout (or any abandonment), cancel the native wait so it does not linger.
await cancelAwaitCode()
console.warn("WhatsApp OTP not received:", error)
}
The captured one-time password.
Cancels a pending awaitCode wait.
Use this to abandon the flow — for example when your own timeout fires, the user navigates
away, or the user chooses a different authentication method. The pending awaitCode() promise
rejects with a cancellation. It is a no-op when there is no active wait.
Platform availability: Android only. On iOS it is a no-op (there is no flow to cancel).
Example:
const modules = await Eitri.modules()
const cancelAwaitCode = modules?.whatsAppOtp?.cancelAwaitCode
if (!cancelAwaitCode) return
// User tapped "use SMS instead"
await cancelAwaitCode()
Verifies whether WhatsApp Zero-Tap is available on the current device.
Android: Returns true only when the feature is enabled for this brand
(whatsAppZeroTap: { active: true }) and a WhatsApp client (consumer or business) is
installed and advertises support for the OTP handshake.
iOS: Always returns false — WhatsApp Zero-Tap is not supported on iOS.
Always call this before startHandshake /
awaitCode, and fall back to a conventional OTP delivery
channel (e.g. SMS) when it returns false.
Example:
const modules = await Eitri.modules()
const isAvailable = modules?.whatsAppOtp?.isAvailable
if (!isAvailable) return
const available = await isAvailable()
if (!available) {
// WhatsApp Zero-Tap not available — fall back to SMS OTP, etc.
return
}
A boolean indicating whether WhatsApp Zero-Tap can be used on this device.
Emits the handshake to the WhatsApp client and opens Meta's required 10-minute window.
Meta only delivers the code if the app performed this handshake within the 10 minutes before the authentication template is sent. Call this first, then ask your backend to send the template, then call awaitCode.
Platform availability: Android only. On iOS this method throws
eitri.whatsAppOtp.notSupportedOnIOS. When the feature is disabled for the brand, it throws
an error as well. Always check isAvailable first.
Example:
const modules = await Eitri.modules()
const startHandshake = modules?.whatsAppOtp?.startHandshake
const awaitCode = modules?.whatsAppOtp?.awaitCode
if (!startHandshake || !awaitCode) return
// 1. Open the 10-minute window
const requestId = await startHandshake()
// 2. Ask YOUR backend to send the zero-tap authentication template to the user.
// The native layer never contacts a backend itself.
await myBackend.sendWhatsAppOtpTemplate({ phone, requestId })
// 3. Wait for the captured code
const code = await awaitCode()
await myBackend.verifyOtp({ phone, code })
The request_id (a UUID) correlated with the handshake. The same id is used by
the WhatsApp Cloud API authentication template and to validate the broadcast that delivers
the code.
Functions that allow an Eitri-App to authenticate a user with a WhatsApp Zero-Tap one-time password (OTP).
WhatsApp Zero-Tap delivers an OTP to the app without the user leaving it: after the app performs a handshake with the WhatsApp client, the WhatsApp client broadcasts the code straight to the app, where it is captured natively and returned via awaitCode.
Flow ownership: the Eitri-App drives the flow and talks to its own backend. The native layer only emits the handshake and captures the code — it makes no backend calls and does not send the authentication template. The expected sequence is:
Requirements: this feature must be enabled in the Eitri Shopping App native configuration by setting
whatsAppZeroTap: { active: true }in the brand's app configuration file. When disabled, isAvailable returnsfalseand the flow methods throw.Platform availability: Android only. On iOS, WhatsApp Zero-Tap is not supported — the WhatsApp client falls back to a copy-code button (and, on supported iOS versions, a keyboard autofill suggestion), both handled entirely by the OS and the WhatsApp client. The
whatsAppOtpnamespace is still registered on iOS so the detection contract is uniform: isAvailable returnsfalseand the flow methods throw. Always check isAvailable before starting the flow.