/** * GATE-01 action envelope helpers (§3.4). * * New gated native actions resolve once with a self-describing success or error * envelope. Legacy Bubble-era callbacks are untouched — this is additive only. */ /** Success envelope returned by NEW gated actions. * @example * const result: BdkActionSuccessEnvelope = { ok: true, action: "bdk.badge.get", count: 0 }; */ interface BdkActionSuccessEnvelope { /** Always `true` on success. */ ok: true; /** Action name without the leading `$` (e.g. `"bdk.permissions.status"`). * @example "bdk.permissions.status" */ action: string; /** Optional correlation id echoed from the request when the caller supplied one. * @example "req-1" */ requestId?: string; [key: string]: unknown; } /** Error envelope returned by NEW gated actions. * @example * const err: BdkActionErrorEnvelope = { * ok: false, * action: "bdk.permissions.status", * code: "common/feature_disabled", * message: "Feature not enabled in this build.", * recoverable: false * }; */ interface BdkActionErrorEnvelope { /** Always `false` on error. */ ok: false; /** Action name without the leading `$` (e.g. `"bdk.permissions.status"`). * @example "bdk.permissions.status" */ action: string; /** Machine-readable code (`/`). * @example "common/feature_disabled" */ code: string; /** Developer/AI-facing English message (never shown to end users by the shell). * @example "Feature not enabled in this build." */ message: string; /** Whether retrying or opening settings can succeed. * @example true */ recoverable: boolean; /** Optional structured details (e.g. `{ option: "requestId" }`). * @example { canOpenSettings: true } */ details?: Record; /** Optional correlation id echoed from the request when the caller supplied one. * @example "req-1" */ requestId?: string; } /** Success or error envelope for NEW gated actions (GATE-01 §3.4). * @example * function handle(payload: BdkActionEnvelope) { * if (isBdkError(payload)) console.error(payload.code); * } */ type BdkActionEnvelope = BdkActionSuccessEnvelope | BdkActionErrorEnvelope; /** * Type guard for a GATE-01 error envelope. * * Returns `true` only when `payload` looks like a structured action error * (`ok === false` with a string `code` and `action`). Never throws. * * @example * bdk.on("bdkEvent", (payload) => { * // envelope-aware helpers will use isBdkError on bdkCallback results * }); * if (isBdkError(result)) console.error(result.code, result.message); */ declare function isBdkError(payload: unknown): payload is BdkActionErrorEnvelope; /** * Type guard for a GATE-01 success envelope. * * @example * if (isBdkSuccess(result)) console.log(result.action); */ declare function isBdkSuccess(payload: unknown): payload is BdkActionSuccessEnvelope; type BdkErrorCode = "BDK_NOT_NATIVE" | "BDK_NATIVE_UNAVAILABLE" | "BDK_UNSUPPORTED_VERSION" | "BDK_UNSUPPORTED_PLATFORM" | "BDK_LISTENER_ERROR" | "BDK_PROVIDER_ERROR" | "BDK_VALIDATION_ERROR"; interface BdkErrorOptions { code: BdkErrorCode; message: string; cause?: unknown | undefined; details?: Record | undefined; } declare class BdkError extends Error { readonly code: BdkErrorCode; readonly details: Record | undefined; constructor(options: BdkErrorOptions); } declare class NotNativeError extends BdkError { constructor(message?: string, details?: Record); } declare class NativeUnavailableError extends BdkError { constructor(message?: string, details?: Record); } declare class UnsupportedVersionError extends BdkError { constructor(message: string, details?: Record); } declare class UnsupportedPlatformError extends BdkError { constructor(message: string, details?: Record); } declare class ListenerError extends BdkError { constructor(event: string, cause?: unknown); } declare class ProviderError extends BdkError { constructor(message: string, details?: Record, cause?: unknown); } declare class ValidationError extends BdkError { constructor(message: string, details?: Record); } declare function toErrorMessage(error: unknown): string; /** SDK-only timing controls shared by Phase 5 guarded actions. * @example * const timing: BdkPhase5TimingOptions = { capabilityTimeoutMs: 2000 }; */ interface BdkPhase5TimingOptions { /** Milliseconds to wait for capability discovery before treating support as unknown. * @example 2000 */ capabilityTimeoutMs?: number; } /** Notification authorization vocabulary returned by `bdk.notifications.status`. * @example * const status: BdkNotificationAuthorization = "authorized"; */ type BdkNotificationAuthorization = "authorized" | "denied" | "notDetermined" | "provisional" | "ephemeral"; /** Time-sensitive notification status. * @example * const status: BdkTimeSensitiveStatus = { supported: true, setting: "enabled" }; */ interface BdkTimeSensitiveStatus { supported: boolean; setting?: "enabled" | "disabled" | "notSupported"; channelId?: string; channelImportance?: "high" | "default" | "low" | "min" | "none"; channelEnabled?: boolean; } /** Critical-alert authorization details. * @example * const status: BdkCriticalNotificationStatus = { supported: true, authorization: "notDetermined", canRequest: true }; */ interface BdkCriticalNotificationStatus { supported: boolean; authorization?: "authorized" | "denied" | "notDetermined" | "notSupported"; canRequest?: boolean; } /** Successful notification-domain status response. * @example * const consume = (result: BdkNotificationsStatusSuccess) => console.log(result.timeSensitive.supported); */ interface BdkNotificationsStatusSuccess extends BdkActionSuccessEnvelope { action: "bdk.notifications.status"; authorization: BdkNotificationAuthorization; timeSensitive: BdkTimeSensitiveStatus; critical: BdkCriticalNotificationStatus; platform: "ios" | "android"; } /** Result returned by `bdk.notifications.status`. * @example * const result: BdkNotificationsStatusResult = await bdk.notifications.status(); */ type BdkNotificationsStatusResult = BdkNotificationsStatusSuccess | BdkActionErrorEnvelope; /** Successful critical-alert request response. * @example * const consume = (result: BdkRequestCriticalSuccess) => console.log(result.granted); */ interface BdkRequestCriticalSuccess extends BdkActionSuccessEnvelope { action: "bdk.notifications.requestCritical"; granted: true; critical: "authorized"; authorization: BdkNotificationAuthorization; } /** Result returned by `bdk.notifications.requestCritical`. * @example * const result: BdkRequestCriticalResult = await bdk.notifications.requestCritical(); */ type BdkRequestCriticalResult = BdkRequestCriticalSuccess | BdkActionErrorEnvelope; /** Android urgent-channel option for `bdk.notifications.openSettings`. * @example * await bdk.notifications.openSettings({ channel: "urgent" }); */ interface BdkNotificationsOpenSettingsOptions extends BdkPhase5TimingOptions { channel?: "urgent"; } /** Successful notification-settings open response. * @example * const consume = (result: BdkNotificationsOpenSettingsSuccess) => console.log(result.opened); */ interface BdkNotificationsOpenSettingsSuccess extends BdkActionSuccessEnvelope { action: "bdk.notifications.openSettings"; opened: true; } /** Result returned by `bdk.notifications.openSettings`. * @example * const result: BdkNotificationsOpenSettingsResult = await bdk.notifications.openSettings(); */ type BdkNotificationsOpenSettingsResult = BdkNotificationsOpenSettingsSuccess | BdkActionErrorEnvelope; /** One retained background data notification. * @example * const message: BdkPushDataMessage = { id: "push-1", receivedAt: 1786230000000, appState: "background", data: {}, delivered: false }; */ interface BdkPushDataMessage { id: string; receivedAt: number; appState: "foreground" | "background" | "cold"; data: Record; delivered?: boolean; } /** Successful `bdk.push.getDataMessages` response. * @example * const consume = (result: BdkPushDataMessagesSuccess) => console.log(result.count); */ interface BdkPushDataMessagesSuccess extends BdkActionSuccessEnvelope { action: "bdk.push.getDataMessages"; count: number; messages: BdkPushDataMessage[]; } /** Result returned by `bdk.push.getDataMessages`. * @example * const result: BdkPushDataMessagesResult = await bdk.push.getDataMessages(); */ type BdkPushDataMessagesResult = BdkPushDataMessagesSuccess | BdkActionErrorEnvelope; /** Live background data-notification event. * @example * bdk.on("push.dataReceived", (event: BdkPushDataReceivedEvent) => console.log(event.data)); */ interface BdkPushDataReceivedEvent extends Omit { event: "push.dataReceived"; ts: number; } /** One retained notification click returned by `bdk.push.getPendingClicks`. * @example * const click: BdkPushClickRecord = { id: "push-1", actionId: null, additionalData: null, appState: "cold", clickedAt: 1786230000000, delivered: false }; */ interface BdkPushClickRecord { id: string; actionId: string | null; title?: string; body?: string; additionalData: Record | null; appState: "foreground" | "background" | "cold"; clickedAt: number; delivered: boolean; } /** One live OneSignal notification click, including action-button taps. * @example * bdk.on("push.clicked", (event: BdkPushClickEvent) => console.log(event.id, event.actionId)); */ interface BdkPushClickEvent extends Omit { event: "push.clicked"; ts: number; } /** Successful `bdk.push.getPendingClicks` drain response. * @example * const consume = (result: BdkPushPendingClicksSuccess) => console.log(result.count, result.clicks); */ interface BdkPushPendingClicksSuccess extends BdkActionSuccessEnvelope { action: "bdk.push.getPendingClicks"; count: number; clicks: BdkPushClickRecord[]; } /** Result returned by `bdk.push.getPendingClicks`. * @example * const result: BdkPushPendingClicksResult = await bdk.push.getPendingClicks(); */ type BdkPushPendingClicksResult = BdkPushPendingClicksSuccess | BdkActionErrorEnvelope; /** Upload state for an inbound shared file. * @example * const upload: BdkInboundShareUpload = { status: "uploaded", httpStatus: 200 }; */ interface BdkInboundShareUpload { status: "pending" | "uploading" | "uploaded" | "failed" | "rejected" | "skipped"; httpStatus?: number; response?: unknown; error?: { code: string; message: string; details?: Record; } | null; } /** Text item received from another app. * @example * const item: BdkInboundShareTextItem = { kind: "text", text: "Hello" }; */ interface BdkInboundShareTextItem { kind: "text"; text: string; } /** URL item received from another app. * @example * const item: BdkInboundShareUrlItem = { kind: "url", url: "https://example.com" }; */ interface BdkInboundShareUrlItem { kind: "url"; url: string; } /** Uploaded or pending file item received from another app. * @example * const item: BdkInboundShareFileItem = { kind: "image", name: "photo.jpg", mime: "image/jpeg", sizeBytes: 10, upload: { status: "pending" } }; */ interface BdkInboundShareFileItem { kind: "image" | "video" | "file"; name: string; mime: string; sizeBytes: number; upload: BdkInboundShareUpload; } /** One inbound item. Kept distinct from the frozen outbound `BdkShareItem` API. * @example * const item: BdkInboundShareItem = { kind: "text", text: "Hello" }; */ type BdkInboundShareItem = BdkInboundShareTextItem | BdkInboundShareUrlItem | BdkInboundShareFileItem; /** A native inbound-share record. * @example * const share: BdkInboundShare = { shareId: "shr_1", receivedAt: "2026-08-09T00:00:00Z", source: "ios-extension", status: "complete", items: [] }; */ interface BdkInboundShare { shareId: string; receivedAt: string; source: "ios-extension" | "android-intent"; status: "pending" | "complete" | "partial" | "failed"; items: BdkInboundShareItem[]; } /** Successful pending-share replay. * @example * const consume = (result: BdkInboundSharesSuccess) => console.log(result.shares); */ interface BdkInboundSharesSuccess extends BdkActionSuccessEnvelope { action: "bdk.share.getPending"; shares: BdkInboundShare[]; } /** Result returned by `bdk.share.getPending`. * @example * const result: BdkInboundSharesResult = await bdk.share.getPending(); */ type BdkInboundSharesResult = BdkInboundSharesSuccess | BdkActionErrorEnvelope; /** Options for retrying failed inbound uploads. * @example * await bdk.share.retryUpload({ shareId: "shr_1" }); */ interface BdkInboundShareRetryOptions extends BdkPhase5TimingOptions { shareId: string; } /** Successful inbound upload retry acknowledgement. * @example * const consume = (result: BdkInboundShareRetrySuccess) => console.log(result.retrying); */ interface BdkInboundShareRetrySuccess extends BdkActionSuccessEnvelope { action: "bdk.share.retryUpload"; shareId: string; retrying: number; } /** Result returned by `bdk.share.retryUpload`. * @example * const result: BdkInboundShareRetryResult = await bdk.share.retryUpload({ shareId: "shr_1" }); */ type BdkInboundShareRetryResult = BdkInboundShareRetrySuccess | BdkActionErrorEnvelope; /** Inbound share receipt or settlement event. * @example * bdk.on("share.received", (event: BdkInboundShareReceivedEvent) => console.log(event.share.shareId)); */ interface BdkInboundShareReceivedEvent { event: "share.received"; ts: number; share: BdkInboundShare; } /** Foreground upload progress for an inbound shared file. * @example * bdk.on("share.uploadProgress", (event: BdkInboundShareUploadProgressEvent) => console.log(event.progress)); */ interface BdkInboundShareUploadProgressEvent { event: "share.uploadProgress"; ts: number; shareId: string; itemIndex: number; bytesSent: number; totalBytes: number; progress: number; } /** Canonical read-only health type id. * @example * const type: HealthTypeId = "steps"; */ type HealthTypeId = "steps" | "distance" | "activeCalories" | "heartRate" | "restingHeartRate" | "weight" | "height" | "bloodOxygen" | "sleep" | "workouts"; /** BDK-prefixed alias for `HealthTypeId`. * @example * const type: BdkHealthTypeId = "sleep"; */ type BdkHealthTypeId = HealthTypeId; /** Per-type authorization entry returned by health status/request. * @example * const entry: BdkHealthAuthorizationEntry = { status: "unknown", requested: false }; */ interface BdkHealthAuthorizationEntry { status: "granted" | "notGranted" | "unknown"; requested: boolean; } /** SDK timing and correlation controls shared by health actions. * @example * const options: BdkHealthActionOptions = { requestId: "health-1", timeoutMs: 60000 }; */ interface BdkHealthActionOptions extends BdkPhase5TimingOptions { requestId?: string; timeoutMs?: number; } /** Options for requesting health read access. * @example * await bdk.health.request({ types: ["steps", "sleep"] }); */ interface BdkHealthRequestOptions extends BdkHealthActionOptions { types?: HealthTypeId[]; } /** Options for a raw health read. * @example * await bdk.health.read({ type: "steps", startDate: "2026-08-01", limit: 100 }); */ interface BdkHealthReadOptions extends BdkHealthActionOptions { type: HealthTypeId; startDate?: string; endDate?: string; limit?: number; ascending?: boolean; } /** Options for aggregate health statistics. * @example * await bdk.health.aggregate({ type: "steps", interval: "day" }); */ interface BdkHealthAggregateOptions extends BdkHealthActionOptions { type: HealthTypeId; startDate?: string; endDate?: string; interval?: "total" | "hour" | "day" | "month"; } /** Successful health availability and authorization response. * @example * const consume = (result: BdkHealthStatusSuccess) => console.log(result.types.steps?.status); */ interface BdkHealthStatusSuccess extends BdkActionSuccessEnvelope { action: "bdk.health.status"; available: boolean; platform: "ios" | "android"; types: Partial>; reason?: "device_unsupported" | "provider_missing" | "provider_update_required"; } /** Result returned by `bdk.health.status`. * @example * const result: BdkHealthStatusResult = await bdk.health.status(); */ type BdkHealthStatusResult = BdkHealthStatusSuccess | BdkActionErrorEnvelope | NativeCommandResult; /** Successful health permission request response. * @example * const consume = (result: BdkHealthRequestSuccess) => console.log(result.requested); */ interface BdkHealthRequestSuccess extends BdkActionSuccessEnvelope { action: "bdk.health.request"; requested: HealthTypeId[]; types: Partial>; } /** Result returned by `bdk.health.request`. * @example * const result: BdkHealthRequestResult = await bdk.health.request(); */ type BdkHealthRequestResult = BdkHealthRequestSuccess | BdkActionErrorEnvelope | NativeCommandResult; /** Quantity sample returned by `bdk.health.read`. * @example * const sample: BdkHealthQuantitySample = { value: 212, startDate: "2026-08-09T00:00:00Z", endDate: "2026-08-09T00:05:00Z", source: "iPhone" }; */ interface BdkHealthQuantitySample { value: number; startDate: string; endDate: string; source: string; } /** Normalized sleep stage. * @example * const stage: BdkHealthSleepStage = { stage: "deep", startDate: "2026-08-09T00:00:00Z", endDate: "2026-08-09T01:00:00Z" }; */ interface BdkHealthSleepStage { stage: "awake" | "light" | "deep" | "rem" | "inBed" | "unknown"; startDate: string; endDate: string; } /** Normalized sleep session. * @example * const session: BdkHealthSleepSample = { startDate: "2026-08-08T22:00:00Z", endDate: "2026-08-09T06:00:00Z", durationSeconds: 28800, source: "Watch", stages: [] }; */ interface BdkHealthSleepSample { startDate: string; endDate: string; durationSeconds: number; source: string; stages: BdkHealthSleepStage[]; } /** Normalized workout session. * @example * const workout: BdkHealthWorkoutSample = { activity: "running", nativeActivity: "running", startDate: "2026-08-09T07:00:00Z", endDate: "2026-08-09T08:00:00Z", durationSeconds: 3600, source: "Watch" }; */ interface BdkHealthWorkoutSample { activity: "running" | "walking" | "cycling" | "swimming" | "hiking" | "yoga" | "strengthTraining" | "hiit" | "pilates" | "rowing" | "elliptical" | "stairClimbing" | "dance" | "other"; nativeActivity: string; startDate: string; endDate: string; durationSeconds: number; source: string; } /** Successful raw health read response. * @example * const consume = (result: BdkHealthReadSuccess) => console.log(result.samples.length); */ interface BdkHealthReadSuccess extends BdkActionSuccessEnvelope { action: "bdk.health.read"; type: HealthTypeId; kind: "quantity" | "session"; unit?: "count" | "m" | "kcal" | "bpm" | "kg" | "cm" | "%"; startDate?: string; endDate?: string; count: number; truncated: boolean; samples: Array; } /** Result returned by `bdk.health.read`. * @example * const result: BdkHealthReadResult = await bdk.health.read({ type: "steps" }); */ type BdkHealthReadResult = BdkHealthReadSuccess | BdkActionErrorEnvelope | NativeCommandResult; /** Cumulative aggregate bucket. * @example * const bucket: BdkHealthSumBucket = { startDate: "2026-08-09T00:00:00+05:30", endDate: "2026-08-10T00:00:00+05:30", sum: 8123 }; */ interface BdkHealthSumBucket { startDate: string; endDate: string; sum: number; } /** Discrete aggregate bucket. * @example * const bucket: BdkHealthDiscreteBucket = { startDate: "2026-08-09T00:00:00+05:30", endDate: "2026-08-10T00:00:00+05:30", avg: 70, min: 60, max: 90 }; */ interface BdkHealthDiscreteBucket { startDate: string; endDate: string; avg: number; min: number; max: number; } /** Successful health aggregate response. * @example * const consume = (result: BdkHealthAggregateSuccess) => console.log(result.buckets); */ interface BdkHealthAggregateSuccess extends BdkActionSuccessEnvelope { action: "bdk.health.aggregate"; type: Exclude; unit: "count" | "m" | "kcal" | "bpm" | "kg" | "cm" | "%"; stat: "sum" | "avg"; interval: "total" | "hour" | "day" | "month"; buckets: Array; } /** Result returned by `bdk.health.aggregate`. * @example * const result: BdkHealthAggregateResult = await bdk.health.aggregate({ type: "steps" }); */ type BdkHealthAggregateResult = BdkHealthAggregateSuccess | BdkActionErrorEnvelope | NativeCommandResult; /** Text NDEF record returned by NFC reads. * @example * const record: BdkNfcTextRecord = { type: "text", text: "Widget", language: "en" }; */ interface BdkNfcTextRecord { type: "text"; text: string; language: string; } /** URI NDEF record returned by NFC reads. * @example * const record: BdkNfcUriRecord = { type: "uri", uri: "https://example.com" }; */ interface BdkNfcUriRecord { type: "uri"; uri: string; } /** External-type NDEF record returned by NFC reads. * @example * const record: BdkNfcExternalRecord = { type: "external", externalType: "com.example:serial", payloadBase64: "U04=", text: "SM" }; */ interface BdkNfcExternalRecord { type: "external"; externalType: string; payloadBase64: string; text: string | null; } /** Unknown NDEF record preserved as base64. * @example * const record: BdkNfcUnknownRecord = { type: "unknown", payloadBase64: "AAE=" }; */ interface BdkNfcUnknownRecord { type: "unknown"; payloadBase64: string; } /** Normalized NDEF record returned by NFC reads. * @example * const record: BdkNfcRecord = { type: "uri", uri: "https://example.com" }; */ type BdkNfcRecord = BdkNfcTextRecord | BdkNfcUriRecord | BdkNfcExternalRecord | BdkNfcUnknownRecord; /** NDEF record accepted by NFC writes. * @example * const record: BdkNfcWritableRecord = { type: "text", text: "Asset A-1", language: "en" }; */ type BdkNfcWritableRecord = BdkNfcTextRecord | BdkNfcUriRecord | Omit; /** Normalized NFC tag payload. * @example * const tag: BdkNfcTag = { id: null, ndef: { writable: true, capacityBytes: 144, records: [] } }; */ interface BdkNfcTag { id: string | null; ndef: { writable?: boolean; capacityBytes?: number; records: BdkNfcRecord[]; }; } /** NFC read options. * @example * await bdk.nfc.read({ message: "Scan product tag", timeoutMs: 30000 }); */ interface BdkNfcReadOptions extends BdkPhase5TimingOptions { message?: string; timeoutMs?: number; } /** NFC write options. * @example * await bdk.nfc.write({ records: [{ type: "uri", uri: "https://example.com" }] }); */ interface BdkNfcWriteOptions extends BdkNfcReadOptions { records: BdkNfcWritableRecord[]; } /** Successful NFC read response. * @example * const consume = (result: BdkNfcReadSuccess) => console.log(result.tag.ndef.records); */ interface BdkNfcReadSuccess extends BdkActionSuccessEnvelope { action: "bdk.nfc.read"; tag: BdkNfcTag; } /** Result returned by `bdk.nfc.read`. * @example * const result: BdkNfcReadResult = await bdk.nfc.read(); */ type BdkNfcReadResult = BdkNfcReadSuccess | BdkActionErrorEnvelope; /** Successful NFC write response. * @example * const consume = (result: BdkNfcWriteSuccess) => console.log(result.bytesWritten); */ interface BdkNfcWriteSuccess extends BdkActionSuccessEnvelope { action: "bdk.nfc.write"; tag: Pick; bytesWritten: number; } /** Result returned by `bdk.nfc.write`. * @example * const result: BdkNfcWriteResult = await bdk.nfc.write({ records: [{ type: "text", text: "Hello", language: "en" }] }); */ type BdkNfcWriteResult = BdkNfcWriteSuccess | BdkActionErrorEnvelope; /** Successful NFC cancellation response. * @example * const consume = (result: BdkNfcCancelSuccess) => console.log(result.cancelled); */ interface BdkNfcCancelSuccess extends BdkActionSuccessEnvelope { action: "bdk.nfc.cancel"; cancelled: boolean; } /** Result returned by `bdk.nfc.cancel`. * @example * const result: BdkNfcCancelResult = await bdk.nfc.cancel(); */ type BdkNfcCancelResult = BdkNfcCancelSuccess | BdkActionErrorEnvelope; /** Successful NFC launch-tag response. * @example * const consume = (result: BdkNfcLaunchTagSuccess) => { if (result.launched) console.log(result.url); }; */ type BdkNfcLaunchTagSuccess = BdkActionSuccessEnvelope & ({ action: "bdk.nfc.getLaunchTag"; launched: false; } | { action: "bdk.nfc.getLaunchTag"; launched: true; url: string; tag: BdkNfcTag; }); /** Result returned by `bdk.nfc.getLaunchTag`. * @example * const result: BdkNfcLaunchTagResult = await bdk.nfc.getLaunchTag(); */ type BdkNfcLaunchTagResult = BdkNfcLaunchTagSuccess | BdkActionErrorEnvelope; /** Successful NFC settings-open response (Android). iOS returns an error envelope. * @example * const consume = (result: BdkNfcOpenSettingsSuccess) => console.log(result.opened); */ interface BdkNfcOpenSettingsSuccess extends BdkActionSuccessEnvelope { action: "bdk.nfc.openSettings"; opened: boolean; } /** Result returned by `bdk.nfc.openSettings`. * @example * const result: BdkNfcOpenSettingsResult = await bdk.nfc.openSettings(); */ type BdkNfcOpenSettingsResult = BdkNfcOpenSettingsSuccess | BdkActionErrorEnvelope; /** NFC launch event emitted after the user opens a tag URL. * @example * bdk.on("nfc.launchTag", (event: BdkNfcLaunchTagEvent) => console.log(event.url)); */ interface BdkNfcLaunchTagEvent { event: "nfc.launchTag"; ts: number; url: string; tag: BdkNfcTag; } /** Registered NFC error codes. * @example * const code: BdkNfcErrorCode = "nfc/tag_lost"; */ type BdkNfcErrorCode = "common/feature_disabled" | "common/invalid_options" | "common/cancelled" | "common/timeout" | "common/internal" | "common/unsupported_os_version" | "common/unsupported_platform" | "nfc/unavailable" | "nfc/busy" | "nfc/system_busy" | "nfc/tag_unsupported" | "nfc/tag_lost" | "nfc/tag_read_only" | "nfc/tag_capacity" | "nfc/write_failed"; /** Notification capability config. * @example * const config: BdkNotificationsCapabilityConfig = { channelId: "bdk_urgent" }; */ interface BdkNotificationsCapabilityConfig { channelId?: string; } /** Background push-data capability config. * @example * const config: BdkPushDataCapabilityConfig = { queueSize: 20 }; */ interface BdkPushDataCapabilityConfig { queueSize: number; } /** Notification-click capability config. * @example * const config: BdkPushClickCapabilityConfig = { queueSize: 20 }; */ interface BdkPushClickCapabilityConfig { queueSize: number; } /** Inbound-share capability config. * @example * const config: BdkInboundShareCapabilityConfig = { types: ["text", "url"], maxSizeMb: 50, uploadConfigured: false }; */ interface BdkInboundShareCapabilityConfig { types: Array<"text" | "url" | "image" | "video" | "file">; maxSizeMb: number; uploadConfigured: boolean; } /** Health-read capability config. * @example * const config: BdkHealthCapabilityConfig = { types: ["steps", "sleep"] }; */ interface BdkHealthCapabilityConfig { types: HealthTypeId[]; } /** NFC capability config. * @example * const config: BdkNfcCapabilityConfig = { write: true, launch: false, tagId: false, maxRecords: 8 }; */ interface BdkNfcCapabilityConfig { write: boolean; launch: boolean; tagId: boolean; maxRecords: number; } /** Normalized platform name reported by BDK Native. * @example * const platform: BdkPlatform = "ios"; */ type BdkPlatform = "ios" | "android" | "web" | "unknown"; /** Loading-screen removal mode. * @example * const bdk = createBdkNative({ removeLoading: "automatic" }); */ type RemoveLoadingMode = "automatic" | "manual"; /** Runtime environment reported by `bdk.environment()`. * @example * const env: BdkEnvironment = bdk.environment(); */ type BdkEnvironment = "native" | "web" | "unknown"; /** Page-fit mode for the native web view. * @example * const bdk = createBdkNative({ pageFit: "normal" }); */ type PageFitMode = "normal" | "cover"; /** Browser SDK configuration. * @example * const bdk = createBdkNative({ removeLoading: "automatic" }); */ interface BdkNativeConfig { /** Controls whether the SDK removes the native loading screen automatically. * @example "automatic" */ removeLoading?: RemoveLoadingMode; /** Controls native web-view page fitting. * @example "normal" */ pageFit?: PageFitMode; /** Treat an undetectable environment as the open web. * * Set `true` only when every installed build of your app can mark its * environment at startup; `bdk.environment()` then reports `"web"` instead * of `"unknown"` in a plain browser, and `bdk.ready()` resolves `null` * immediately instead of waiting out its timeout. * @example * const bdk = createBdkNative({ assumeWebWithoutSeed: true }); */ assumeWebWithoutSeed?: boolean; /** Receives SDK errors. * @example * const bdk = createBdkNative({ onError: (error) => console.error(error.code) }); */ onError?: (error: BdkError) => void; } /** Command acknowledgement returned by BDK Native helpers. * @example * const result = await bdk.ui.showAlert({ title: "Hi" }); */ interface NativeCommandResult { /** Native command name. * @example "showAlert" */ command: string; /** Whether the command entered the SDK dispatch flow. * @example true */ queued: boolean; /** Whether the command was handed to the native runtime. * @example true */ triggered: boolean; /** Whether the command was skipped. * @example false */ skipped: boolean; /** Whether the command is waiting for native availability. * @example true */ pending?: boolean; /** Optional acknowledgement reason. * @example "waiting_for_agent" */ reason?: string; } /** Device and app information reported by BDK Native. * @example * bdk.on("deviceInfo", (info) => console.log(info.deviceOS, info.bdkRelease)); */ interface BdkDeviceInfo { /** OneSignal player id, when available. * @example "player-id" */ playerId: string | null; /** Push token, when available. * @example "push-token" */ pushToken: string | null; /** Device width. * @example 390 */ deviceWidth: string | number | null; /** Device height. * @example 844 */ deviceHeight: string | number | null; /** Device OS. * @example "iOS" */ deviceOS: string | null; /** Device OS version. * @example "17.0" */ deviceOSVersion: string | null; /** Device language. * @example "en" */ deviceLanguage: string | null; /** Camera permission status. * @example "granted" */ cameraPermissionStatus: string | null; /** Contacts permission status. * @example "granted" */ contactsPermissionStatus: string | null; /** Audio recording permission status. * @example "granted" */ audiorecordPermissionStatus: string | null; /** External storage permission status. * @example "granted" */ externalstoragePermissionStatus: string | null; /** Location permission status. * @example "granted" */ locationPermissionStatus: string | null; /** App version name. * @example "1.0" */ versionName: string | null; /** App version code. * @example "1" */ versionCode: string | number | null; /** Device model. * @example "iPhone" */ deviceModel: string | null; /** BDK Native runtime release. * @example "2.1" */ bdkRelease: string | number | null; /** Whether native biometrics are available. * @example true */ biometricsAvailable: boolean; /** Whether Smart Login is available. * @example true */ smartLoginAvailable: boolean; /** iOS app tracking permission status. * @example "authorized" */ appTrackingPermissionStatus?: string; /** iOS IDFA, when available. * @example "00000000-0000-0000-0000-000000000000" */ idfa?: string; /** Native view type, when supplied. * @example "primary" */ viewType?: string; } /** One feature entry in the BDK Native capability handshake (GATE-01 §3.6). * @example * const feature: BdkCapabilityFeature = { enabled: true, available: false }; */ interface BdkCapabilityFeature> { /** Whether the feature is compiled in and switched on for this customer. * @example true */ enabled: boolean; /** Runtime availability (device/OS/services); omitted when not applicable. * @example false */ available?: boolean; /** Optional safe-to-expose effective settings (never secrets). * @example { types: ["image", "url"] } */ config?: Config; /** Optional machine-readable capability state details. * @example { reason: "no_types" } */ details?: Record; } /** Safe configuration exposed for URI-scheme deep links. * @example * const config: BdkDeepLinkCapabilityConfig = { schemes: ["com.example.app"] }; */ interface BdkDeepLinkCapabilityConfig { /** Registered schemes in preferred order (bundle-id scheme first). * @example ["com.example.app", "example"] */ schemes?: string[]; } /** Safe configuration exposed for the reworked media bridge. * @example * const config: BdkMediaCapabilityConfig = { fileUrl: true, takePhoto: true }; */ interface BdkMediaCapabilityConfig { /** Whether system photo selection is available. * @example true */ pickPhotos?: boolean; /** Whether `result: "fileUrl"` is verified and available on this platform. * @example true */ fileUrl?: boolean; /** Whether a camera can service `bdk.media.takePhoto`. * @example true */ takePhoto?: boolean; /** Maximum selection limit supported by the native contract. * @example 30 */ maxLimit?: number; /** Android camera-facing selection is a best-effort hint. * @example "bestEffort" */ cameraFacingHint?: "bestEffort"; } /** Safe configuration exposed for outbound file sharing. * @example * const config: BdkShareFilesCapabilityConfig = { maxSizeMb: 100, maxTotalMb: 300 }; */ interface BdkShareFilesCapabilityConfig { /** Maximum combined items and expanded URLs. * @example 10 */ maxItems?: number; /** Per-file size cap in megabytes. * @example 100 */ maxSizeMb?: number; /** Aggregate per-call size cap in megabytes. * @example 300 */ maxTotalMb?: number; /** Platform's success timing vocabulary. * @example "presented" */ outcome?: "completed" | "presented"; } /** Effective webview OAuth mode and provider presets. * @example * const config: BdkAuthOAuthCapabilityConfig = { mode: "auto", providers: ["google"] }; */ interface BdkAuthOAuthCapabilityConfig { /** Effective OAuth mode. * @example "explicit" */ mode: "off" | "explicit" | "auto"; /** Presets eligible for automatic interception. * @example ["google"] */ providers?: Array<"google" | "facebook" | "line" | "kakao">; } /** Safe configuration exposed for native modal navigation. * @example * const config: BdkNavigationModalCapabilityConfig = { styles: ["sheet", "fullscreen"], detents: ["large", "medium"] }; */ interface BdkNavigationModalCapabilityConfig { /** Presentation styles this build can use. * @example ["sheet", "fullscreen"] */ styles: Array<"sheet" | "fullscreen">; /** Sheet detents this build can use. * @example ["large", "medium"] */ detents: Array<"large" | "medium">; } /** Capability handshake payload reported by `$bdk.getCapabilities` (GATE-01). * * Absent feature keys mean the feature is not in this binary — treat as * `enabled: false` (§3.6 rule 1). `gating.schema` marks GATE-01+ builds. * * @example * bdk.on("capabilities", (capabilities) => console.log(capabilities.gating?.schema)); */ interface BdkCapabilities { /** Capability schema version. * @example 1 */ api: number; /** Platform that produced the payload. * @example "ios" */ platform: string; /** App version details, when supplied. * @example { versionName: "1.0", versionCode: "1" } */ app?: { /** App version name. * @example "1.0" */ versionName?: string; /** App version code. * @example "1" */ versionCode?: string | number; }; /** Feature map keyed by canonical feature id. * @example { "geo.background": { enabled: false }, billing: { enabled: true, available: true } } */ features: Record & { "deeplink.scheme"?: BdkCapabilityFeature; media?: BdkCapabilityFeature; "share.files"?: BdkCapabilityFeature; "auth.oauth"?: BdkCapabilityFeature; "notifications.timesensitive"?: BdkCapabilityFeature; "notifications.critical"?: BdkCapabilityFeature; "push.data"?: BdkCapabilityFeature; "push.click"?: BdkCapabilityFeature; "share.inbound"?: BdkCapabilityFeature; "health.read"?: BdkCapabilityFeature; nfc?: BdkCapabilityFeature; iap?: BdkCapabilityFeature; "navigation.modal"?: BdkCapabilityFeature; }; /** GATE-01 meta block. Absent on older binaries without the gating framework. * @example { schema: 1 } */ gating?: { /** Gating schema version. * @example 1 */ schema: number; }; } /** Multiplexed native→web event payload delivered via `window.bdkEvent` (GATE-01 §3.5). * @example * bdk.on("bdkEvent", (payload) => console.log(payload.event, payload.ts)); */ interface BdkEventPayload { /** Event name (`.`). * @example "permissions.changed" */ event: string; /** Epoch milliseconds when native emitted the event. * @example 1754640000000 */ ts?: number; [key: string]: unknown; } /** Canonical permission types reported by `bdk.permissions.status` (F10). * @example * const type: BdkPermissionType = "camera"; */ type BdkPermissionType = "push" | "location" | "camera" | "photos" | "microphone" | "contacts" | "tracking"; /** Wire-frozen authorization statuses for the permissions bridge (F10). * @example * const status: BdkPermissionStatus = "granted"; */ type BdkPermissionStatus = "granted" | "denied" | "notDetermined" | "limited" | "provisional" | "restricted" | "unsupported"; /** Per-permission entry in a status map or `permissions.changed` payload. * @example * const entry: BdkPermissionEntry = { status: "granted", canPrompt: false }; */ interface BdkPermissionEntry { /** Canonical authorization status. * @example "granted" */ status: BdkPermissionStatus; /** Whether a system prompt would appear if the app requested now (advisory only). * @example true */ canPrompt: boolean; /** Optional detail (location precision/scope; push timeout degradation). * @example { precision: "precise", scope: "whenInUse" } */ detail?: { /** Location accuracy class when granted. * @example "precise" */ precision?: "precise" | "approximate"; /** Location scope when granted. * @example "whenInUse" */ scope?: "whenInUse" | "always"; /** True when a subsystem hang forced a degraded answer (e.g. push timeout). * @example true */ degraded?: boolean; }; } /** Options for `bdk.permissions.status`. * @example * await bdk.permissions.status({ types: ["camera", "notifications"] }); */ interface PermissionsStatusOptions { /** Subset of types to report. Legacy aliases (`notifications`, `record audio`, …) are mapped natively. * @example ["camera", "push"] */ types?: Array; /** Optional correlation id echoed on the envelope (GATE-01 §3.4). * @example "req-1" */ requestId?: string; /** SDK-only: ms to wait for the `bdkCallback` envelope. Defaults to `8000`. * @example 5000 */ timeoutMs?: number; /** SDK-only: ms for the capability probe before deciding the feature is absent. Defaults to `1500`. * @example 2000 */ capabilityTimeoutMs?: number; } /** Options for `bdk.permissions.openSettings`. * @example * await bdk.permissions.openSettings({ section: "notifications" }); */ interface PermissionsOpenSettingsOptions { /** Which settings surface to open. Defaults to `"app"`. * @example "notifications" */ section?: "app" | "notifications"; /** Optional correlation id echoed on the envelope (GATE-01 §3.4). * @example "req-1" */ requestId?: string; /** SDK-only: ms to wait for the `bdkCallback` envelope. Defaults to `8000`. * @example 5000 */ timeoutMs?: number; /** SDK-only: ms for the capability probe before deciding the feature is absent. Defaults to `1500`. * @example 2000 */ capabilityTimeoutMs?: number; } /** Success envelope from `bdk.permissions.status` (F10 §3.2). * @example * const result = await bdk.permissions.status(); * if (!isBdkError(result)) console.log(result.permissions.camera?.status); */ interface PermissionStatusSuccess extends BdkActionSuccessEnvelopeBase { action: "bdk.permissions.status"; /** Platform that produced the map (F10 §3.2 — required on success). * @example "ios" */ platform: "ios" | "android"; /** Full or filtered permission map (canonical type keys). * @example { camera: { status: "granted", canPrompt: false } } */ permissions: Record; /** Request-side alias → canonical type map when aliases were used. * @example { notifications: "push" } */ aliasesApplied?: Record; /** Soft warnings (e.g. `push_status_timeout`); absent when empty. * @example ["push_status_timeout"] */ warnings?: string[]; } /** Result of `bdk.permissions.status` — success map or error envelope. */ type PermissionStatusResult = PermissionStatusSuccess | BdkActionErrorEnvelope; /** Success envelope from `bdk.permissions.openSettings` (F10 §3.3). * @example * const result = await bdk.permissions.openSettings({ section: "notifications" }); */ interface PermissionsOpenSettingsSuccess extends BdkActionSuccessEnvelopeBase { action: "bdk.permissions.openSettings"; /** Section that actually opened (`"app"` when iOS fell back from notifications). * @example "app" */ section: "app" | "notifications"; /** Present when the OS fell back (e.g. iOS 15.0–15.3 notifications → app settings). * @example { fallback: true } */ details?: { fallback?: boolean; }; } /** Result of `bdk.permissions.openSettings` — success or error envelope. */ type PermissionsOpenSettingsResult = PermissionsOpenSettingsSuccess | BdkActionErrorEnvelope; /** `permissions.changed` payload on the `bdkEvent` channel (F10 §3.4). * @example * bdk.on("permissions.changed", (payload) => { * console.log(payload.changed, payload.permissions); * }); */ interface PermissionsChangedEvent extends BdkEventPayload { event: "permissions.changed"; /** Type names whose status or detail changed. * @example ["camera", "location"] */ changed: string[]; /** Prior `{status, detail?}` per changed type. * @example { camera: { status: "notDetermined" } } */ previous: Record; /** Full current permission map. * @example { camera: { status: "granted", canPrompt: false } } */ permissions: Record; } /** SDK-only timing options for push and ATT permission-control helpers. * These fields are never forwarded to native actions. * @example * const options: PermissionControlOptions = { timeoutMs: 10000, capabilityTimeoutMs: 2000 }; */ interface PermissionControlOptions { /** Milliseconds to wait for the native result envelope. Defaults to 8,000 for * push/status helpers and 95,000 for `bdk.att.request()` so native's 90-second * ATT watchdog resolves first. * @example 10000 */ timeoutMs?: number; /** Milliseconds to wait for the capability handshake. * @example 2000 */ capabilityTimeoutMs?: number; } /** Push authorization values returned by F06. * @example * const status: PushPermissionStatus = "provisional"; */ type PushPermissionStatus = "granted" | "denied" | "notDetermined" | "provisional"; /** Success envelope from `bdk.push.status()` or `bdk.push.request()`. * @example * const result = await bdk.push.status(); * if (!isBdkError(result)) console.log(result.status, result.mode); */ interface PushPermissionSuccess extends BdkActionSuccessEnvelopeBase { action: "bdk.push.status" | "bdk.push.request"; /** Canonical notification authorization status. * @example "notDetermined" */ status: PushPermissionStatus; /** True for `granted` and `provisional`. * @example false */ granted: boolean; /** Whether calling `request()` can still ask the user. * @example true */ canPrompt: boolean; /** Whether the app can open notification settings. * @example true */ canOpenSettings: boolean; /** Effective launch-prompt mode. * @example "manual" */ mode: "automatic" | "manual"; /** Optional F10 status detail. * @example { degraded: true } */ detail?: Record; /** Optional non-fatal status warnings. * @example ["push_status_timeout"] */ warnings?: string[]; } /** Result from `bdk.push.status()` or `bdk.push.request()`. * @example * const result: PushPermissionResult = await bdk.push.request(); */ type PushPermissionResult = PushPermissionSuccess | BdkActionErrorEnvelope; /** Success envelope from `bdk.push.openSettings()`. * @example * const result = await bdk.push.openSettings(); * if (!isBdkError(result)) console.log(result.opened); */ interface PushOpenSettingsSuccess extends BdkActionSuccessEnvelopeBase { action: "bdk.push.openSettings"; /** Always true after the OS accepts the settings-open request. * @example true */ opened: true; /** Optional platform fallback details. * @example { fallback: true } */ details?: Record; } /** Result from `bdk.push.openSettings()`. * @example * const result: PushOpenSettingsResult = await bdk.push.openSettings(); */ type PushOpenSettingsResult = PushOpenSettingsSuccess | BdkActionErrorEnvelope; /** Canonical App Tracking Transparency authorization status. * @example * const status: AttStatus = "notDetermined"; */ type AttStatus = "granted" | "denied" | "restricted" | "notDetermined"; /** Success envelope from `bdk.att.status()`. * @example * const result = await bdk.att.status(); * if (!isBdkError(result)) console.log(result.canPrompt); */ interface AttStatusSuccess extends BdkActionSuccessEnvelopeBase { action: "bdk.att.status"; /** Current ATT authorization state. * @example "notDetermined" */ status: AttStatus; /** Whether ATT is not determined and this configured surface may request it. * @example true */ canPrompt: boolean; /** Advertising identifier only when authorized and non-zero. * @example "1A2B3C4D-1111-2222-3333-444455556666" */ idfa: string | null; } /** Result from `bdk.att.status()`. * @example * const result: AttStatusResult = await bdk.att.status(); */ type AttStatusResult = AttStatusSuccess | BdkActionErrorEnvelope; /** Success envelope from `bdk.att.request()`. * @example * const result = await bdk.att.request(); * if (!isBdkError(result)) console.log(result.status, result.prompted); */ interface AttRequestSuccess extends BdkActionSuccessEnvelopeBase { action: "bdk.att.request"; /** ATT state after the request completes. * @example "denied" */ status: AttStatus; /** Whether status was `notDetermined` and a request was issued. The system dialog may * still not appear when the device-wide tracking-request setting is off. * @example true */ prompted: boolean; /** Advertising identifier only when authorized and non-zero. * @example null */ idfa: string | null; } /** Result from `bdk.att.request()`. * @example * const result: AttRequestResult = await bdk.att.request(); */ type AttRequestResult = AttRequestSuccess | BdkActionErrorEnvelope; /** `att.changed` payload emitted after a real ATT status transition. * @example * bdk.on("att.changed", (payload) => console.log(payload.status, payload.idfa)); */ interface AttChangedEvent extends BdkEventPayload { event: "att.changed"; /** New ATT authorization state. * @example "granted" */ status: AttStatus; /** Advertising identifier only when newly authorized and non-zero. * @example null */ idfa: string | null; } /** Query values accepted by `bdk.deeplink.buildLink`. * @example * const query: BdkDeepLinkQuery = { tab: "details", page: 2 }; */ type BdkDeepLinkQuery = Record; /** Build an open-page URI-scheme link. * @example * const options: BdkDeepLinkBuildUrlOptions = { url: "https://example.com/orders/1" }; */ interface BdkDeepLinkBuildUrlOptions { /** Same-origin HTTP(S) page that the native shell should open. * @example "https://example.com/orders/1" */ url: string; path?: never; query?: never; } /** Build a route-inside-the-page URI-scheme link. * @example * const options: BdkDeepLinkBuildPathOptions = { path: "orders/1", query: { tab: "details" } }; */ interface BdkDeepLinkBuildPathOptions { url?: never; /** Route path, without the app scheme. * @example "orders/1" */ path: string; /** Optional route query values. * @example { tab: "details" } */ query?: BdkDeepLinkQuery; } /** Input accepted by `bdk.deeplink.buildLink`. * @example * const options: BdkDeepLinkBuildOptions = { path: "orders/1" }; */ type BdkDeepLinkBuildOptions = BdkDeepLinkBuildUrlOptions | BdkDeepLinkBuildPathOptions; /** Common fields on a received app-scheme link. * @example * bdk.deeplink.onReceived((link) => console.log(link.rawUrl, link.coldStart)); */ interface BdkDeepLinkRecordBase { /** Original scheme URI exactly as native received it. * @example "com.example.app://orders/1" */ rawUrl: string; /** Scheme links are the only source in F18. * @example "scheme" */ source: "scheme"; /** Whether the app was launched by this link. * @example true */ coldStart: boolean; /** Stable delivery identifier used for replay/event deduplication. * @example "4D8A2CE8-88BD-4D44-9DFD-0F27C89FEC01" */ id: string; /** Epoch milliseconds when native accepted the link. * @example 1786127400000 */ ts: number; } /** URL-form scheme link already applied by the native shell. * @example * bdk.deeplink.onReceived((link) => { if (link.form === "url") console.log(link.targetUrl); }); */ interface BdkDeepLinkUrlRecord extends BdkDeepLinkRecordBase { form: "url"; /** Same-origin page native navigated to. * @example "https://example.com/orders/1" */ targetUrl: string; } /** Path-form scheme link for page-owned routing. * @example * bdk.deeplink.onReceived((link) => { if (link.form === "path") routeTo(link.path, link.query); }); */ interface BdkDeepLinkPathRecord extends BdkDeepLinkRecordBase { form: "path"; /** Decoded route path. * @example "orders/1" */ path: string; /** Decoded query values. * @example { tab: "details" } */ query: Record; } /** One received app-scheme link. * @example * const handle = (link: BdkDeepLinkRecord) => console.log(link.id); */ type BdkDeepLinkRecord = BdkDeepLinkUrlRecord | BdkDeepLinkPathRecord; /** Success response when no scheme link is available. * @example * const empty: BdkDeepLinkEmptySuccess = { ok: true, action: "bdk.deeplink.get", received: false }; */ interface BdkDeepLinkEmptySuccess extends BdkActionSuccessEnvelope { action: "bdk.deeplink.get"; received: false; } /** Successful `bdk.deeplink.get` replay. * @example * const consume = (result: BdkDeepLinkReceivedSuccess) => console.log(result.id, result.consumed); */ type BdkDeepLinkReceivedSuccess = BdkActionSuccessEnvelope & BdkDeepLinkRecord & { action: "bdk.deeplink.get"; received: true; /** Whether a previous `bdk.deeplink.get` call already consumed the replay. * @example false */ consumed: boolean; }; /** Result returned by `bdk.deeplink.get`. * @example * const result: BdkDeepLinkGetResult = await bdk.deeplink.get(); */ type BdkDeepLinkGetResult = BdkDeepLinkEmptySuccess | BdkDeepLinkReceivedSuccess | BdkActionErrorEnvelope; /** Warm/cold scheme delivery event. * @example * bdk.on("deeplink.received", (event) => console.log(event.id, event.form)); */ type BdkDeepLinkReceivedEvent = BdkDeepLinkRecord & { event: "deeplink.received"; }; /** Photo result representation requested from native. * @example * const result: BdkMediaResultMode = "fileUrl"; */ type BdkMediaResultMode = "base64" | "fileUrl"; /** Options for the permissionless system photo picker. * @example * const options: BdkMediaPickPhotosOptions = { limit: 5, maxDimensionPx: 2048 }; */ interface BdkMediaPickPhotosOptions { /** Maximum photos to select; native validates 1 through 30. * @example 5 */ limit?: number; /** Return inline JPEG base64 or an in-webview fetchable URL. * @example "base64" */ result?: BdkMediaResultMode; /** Longest edge in pixels; zero preserves dimensions only in fileUrl mode. * @example 2048 */ maxDimensionPx?: number; /** JPEG encoder quality from 0.1 through 1.0. * @example 0.8 */ jpegQuality?: number; } /** Options for system-camera still capture. * @example * const options: BdkMediaTakePhotoOptions = { camera: "front", result: "fileUrl" }; */ interface BdkMediaTakePhotoOptions extends Omit { /** Preferred camera. Android treats this as a best-effort hint. * @example "front" */ camera?: "back" | "front"; } /** Uniform JPEG item returned by the new media actions. * @example * const show = (item: BdkMediaItem) => bdk.media.toDataUri(item); */ interface BdkMediaItem { kind: "image"; mimeType: "image/jpeg"; base64: string | null; fileUrl: string | null; width: number; height: number; sizeBytes: number; name: string; } /** Registered error codes returned by the new media actions. * @example * const code: BdkMediaErrorCode = "media/load_failed"; */ type BdkMediaErrorCode = "common/cancelled" | "common/invalid_options" | "common/permission_denied" | "common/feature_disabled" | "common/unsupported_platform" | "common/internal" | "common/timeout" | "media/no_camera" | "media/load_failed"; /** Error envelope returned by the new media actions. * @example * if (isBdkError(result)) console.log((result as BdkMediaError).code); */ type BdkMediaError = BdkActionErrorEnvelope & { action: "bdk.media.pickPhotos" | "bdk.media.takePhoto"; code: BdkMediaErrorCode; }; /** Successful multi-photo selection. * @example * const consume = (result: BdkMediaPickPhotosSuccess) => console.log(result.items.length); */ interface BdkMediaPickPhotosSuccess extends BdkActionSuccessEnvelope { action: "bdk.media.pickPhotos"; selectedCount: number; succeededCount: number; failedCount: number; count: number; items: BdkMediaItem[]; } /** Result returned by `bdk.media.pickPhotos`. * @example * const result: BdkMediaPickPhotosResult = await bdk.media.pickPhotos(); */ type BdkMediaPickPhotosResult = BdkMediaPickPhotosSuccess | BdkMediaError; /** Successful system-camera capture. * @example * const consume = (result: BdkMediaTakePhotoSuccess) => console.log(result.item.name); */ interface BdkMediaTakePhotoSuccess extends BdkActionSuccessEnvelope { action: "bdk.media.takePhoto"; item: BdkMediaItem; } /** Result returned by `bdk.media.takePhoto`. * @example * const result: BdkMediaTakePhotoResult = await bdk.media.takePhoto(); */ type BdkMediaTakePhotoResult = BdkMediaTakePhotoSuccess | BdkMediaError; /** Text item accepted by `bdk.share.send`. * @example * const item: BdkShareTextItem = { type: "text", text: "Quarterly report" }; */ interface BdkShareTextItem { type: "text"; text: string; } /** Link item accepted by `bdk.share.send` without fetching. * @example * const item: BdkShareUrlItem = { type: "url", url: "https://example.com/report" }; */ interface BdkShareUrlItem { type: "url"; url: string; } /** Remote or local file item accepted by `bdk.share.send`. * @example * const item: BdkShareFileItem = { type: "file", url: "https://example.com/report.pdf" }; */ type BdkShareFileItem = { type: "file" | "image" | "video" | "audio"; /** Optional share-sheet filename. * @example "Q3-report.pdf" */ filename?: string; } & ({ /** Preferred remote URL or local path key. * @example "https://example.com/report.pdf" */ url: string; /** Compatibility alias with identical scheme-detected behavior. * @example "/tmp/report.pdf" */ file_url?: string; } | { url?: string; /** Compatibility alias with identical scheme-detected behavior. * @example "/tmp/report.pdf" */ file_url: string; }); /** One item accepted by `bdk.share.send`. * @example * const item: BdkShareItem = { type: "text", text: "Hello" }; */ type BdkShareItem = BdkShareTextItem | BdkShareUrlItem | BdkShareFileItem; /** Options for mixed text, link, and file sharing. * @example * const options: BdkShareSendOptions = { items: [{ type: "text", text: "See attachment" }], urls: ["https://example.com/report.pdf"] }; */ type BdkShareSendOptions = { /** Requested Android chooser title; ignored on iOS. * @example "Share report" */ title?: string; } & ({ items: BdkShareItem[]; /** File URLs expanded after `items` by native. * @example ["https://example.com/report.pdf"] */ urls?: string[]; } | { items?: BdkShareItem[]; /** File URLs expanded after `items` by native. * @example ["https://example.com/report.pdf"] */ urls: string[]; }); /** Optional chooser settings for `bdk.share.files`. * @example * const options: BdkShareFilesOptions = { title: "Share files" }; */ interface BdkShareFilesOptions { title?: string; } /** Registered error codes returned by outbound sharing. * @example * const code: BdkShareErrorCode = "share/fetch_failed"; */ type BdkShareErrorCode = "common/cancelled" | "common/invalid_options" | "common/feature_disabled" | "common/internal" | "common/network" | "common/timeout" | "share/fetch_failed" | "share/too_large"; /** Error envelope returned by `bdk.share.send`. * @example * if (isBdkError(result)) console.log((result as BdkShareError).code); */ type BdkShareError = BdkActionErrorEnvelope & { action: "bdk.share.send"; code: BdkShareErrorCode; }; /** Successful outbound share-sheet result. * @example * const consume = (result: BdkShareSuccess) => console.log(result.outcome, result.items.shared); */ interface BdkShareSuccess extends BdkActionSuccessEnvelope { action: "bdk.share.send"; outcome: "completed" | "presented"; app?: string; items: { requested: number; shared: number; }; } /** Result returned by `bdk.share.send` and `bdk.share.files`. * @example * const result: BdkShareResult = await bdk.share.files(["https://example.com/report.pdf"]); */ type BdkShareResult = BdkShareSuccess | BdkShareError; /** Options for explicit external-browser OAuth/OIDC sign-in. * @example * const options: BdkAuthSignInOptions = { url: authorizeUrl, handoff: "page" }; */ interface BdkAuthSignInOptions { /** Full HTTPS provider authorization URL. * @example "https://idp.example.com/authorize?redirect_uri=com.example.app%3A%2F%2Foauth%2Freturn" */ url: string; /** Callback URI when it cannot be derived from the authorization URL. * @example "com.example.app://oauth/return" */ redirectUri?: string; /** `webview` resolves when callback navigation is enqueued, not when it finishes. * Listen for `auth.completed` to observe the completed load. * @example "webview" */ handoff?: "page" | "webview"; /** Request an ephemeral iOS custom-scheme session when supported. * @example true */ preferEphemeral?: boolean; /** Return-trip timeout in milliseconds; native validates 60000 through 3600000. * @example 900000 */ timeoutMs?: number; } /** Registered error codes returned by explicit OAuth sign-in. * @example * const code: BdkAuthErrorCode = "auth/callback_mismatch"; */ type BdkAuthErrorCode = "common/feature_disabled" | "common/invalid_options" | "common/cancelled" | "common/timeout" | "common/internal" | "auth/redirect_unroutable" | "auth/in_progress" | "auth/callback_mismatch" | "auth/provider_denied" | "auth/session_failed"; /** Error envelope returned by `bdk.auth.signIn`. * @example * if (isBdkError(result)) console.log((result as BdkAuthError).code); */ type BdkAuthError = BdkActionErrorEnvelope & { action: "bdk.auth.signIn"; code: BdkAuthErrorCode; }; /** Optional OAuth success diagnostics for accepted-but-platform-ignored options. * @example * const details: BdkAuthSuccessDetails = { preferEphemeral: "ignored" }; */ interface BdkAuthSuccessDetails { /** Present when `preferEphemeral` was accepted but unsupported for this flow. * @example "ignored" */ preferEphemeral?: "ignored"; [key: string]: unknown; } /** Page-handoff success from `bdk.auth.signIn`. * @example * const consume = (result: BdkAuthPageSuccess) => console.log(result.params.code); */ interface BdkAuthPageSuccess extends BdkActionSuccessEnvelope { action: "bdk.auth.signIn"; handoff: "page"; callbackUrl: string; params: Record; details?: BdkAuthSuccessDetails; } /** Webview-handoff enqueue acknowledgement from `bdk.auth.signIn`. * @example * const consume = (result: BdkAuthWebviewSuccess) => { if (result.loaded) console.log("navigation enqueued"); }; */ interface BdkAuthWebviewSuccess extends BdkActionSuccessEnvelope { action: "bdk.auth.signIn"; handoff: "webview"; /** True means navigation was enqueued; listen for `auth.completed` for load completion. * @example true */ loaded: true; details?: BdkAuthSuccessDetails; } /** Result returned by `bdk.auth.signIn`. * @example * const result: BdkAuthSignInResult = await bdk.auth.signIn({ url: authorizeUrl }); */ type BdkAuthSignInResult = BdkAuthPageSuccess | BdkAuthWebviewSuccess | BdkAuthError; /** Provider label emitted by native OAuth events. * @example * const provider: BdkAuthProvider = "google"; */ type BdkAuthProvider = "google" | "facebook" | "line" | "kakao" | "custom" | "explicit"; /** Successful OAuth completion event from auto or explicit mode. * @example * bdk.on("auth.completed", (event) => console.log(event.mode, event.provider)); */ interface BdkAuthCompletedEvent extends BdkEventPayload { event: "auth.completed"; ts: number; mode: "auto" | "explicit"; provider: BdkAuthProvider; handoff: "page" | "webview"; } /** OAuth cancellation/denial/timeout event from auto or explicit mode. * @example * bdk.on("auth.cancelled", (event) => console.log(event.reason)); */ interface BdkAuthCancelledEvent extends BdkEventPayload { event: "auth.cancelled"; ts: number; mode: "auto" | "explicit"; provider: BdkAuthProvider; reason: "dismissed" | "provider_denied" | "timeout"; } /** Media payload returned by photo, video, screenshot, and audio events. * @example * bdk.on("photoCaptured", (photo) => console.log(photo.fileUrl)); */ interface MediaResult { /** File URL returned by native code. * @example "https://example.com/photo.jpg" */ fileUrl: string | null; /** Data URI returned by native code. * @example "data:image/jpeg;base64,..." */ dataUri: string | null; /** Native metadata payload. * @example { id: 1 } */ data: unknown; /** Media content type. * @example "image/jpeg" */ contentType: string | null; } /** Biometric authentication event payload. * @example * bdk.on("biometricResult", (result) => console.log(result.status)); */ interface BiometricResult { /** Native biometric result data. * @example { attempt_login: "true" } */ data: unknown; /** Native biometric status. * @example "success" */ status: unknown; /** Platform that produced the biometric result. * @example "ios" */ platform: "ios" | "android"; } /** Smart Login credentials returned by native code. * @example * bdk.on("smartLoginCredentials", (credentials) => console.log(credentials.email)); */ interface SmartLoginCredentials { /** Stored email address. * @example "user@example.com" */ email: string | null; /** Stored password. * @example "secret" */ password: string | null; } /** Device-variable cache result. * @example * bdk.on("deviceVariable", (item) => console.log(item.name, item.data)); */ interface DeviceVariableResult { /** Variable name. * @example "token" */ name: string; /** Variable data. `null` when the key was never stored. * @example "abc" */ data: unknown; } /** Contact item returned by the native address book. * @example * bdk.on("contacts", (contacts) => console.log(contacts[0]?.name)); */ interface ContactResult { /** Contact display name. * @example "Demo Contact" */ name?: string; /** Contact phone data from the native address book. * @example "+10000000000" */ phone?: unknown; /** Contact email data from the native address book. * @example "person@example.com" */ email?: unknown; } /** Stable label category used by normalized F01/F02 contact fields. */ type BdkContactLabelType = "mobile" | "home" | "work" | "other" | "custom"; /** A normalized phone number returned by the permissionless picker or address-book list. */ interface BdkContactPhone { type: BdkContactLabelType; label: string; number: string; } /** A normalized email address returned by the permissionless picker or address-book list. */ interface BdkContactEmail { type: BdkContactLabelType; label: string; address: string; } /** Cross-platform normalized contact shape for the new contacts namespace. */ interface BdkContact { name: string; givenName: string; familyName: string; phones: BdkContactPhone[]; emails: BdkContactEmail[]; } /** Success result for `bdk.contacts.pick`. */ interface BdkContactsPickSuccess extends BdkActionSuccessEnvelope { action: "bdk.contacts.pick"; contacts: BdkContact[]; } type BdkContactsPickResult = BdkContactsPickSuccess | BdkActionErrorEnvelope; /** Success result for `bdk.contacts.list`. */ interface BdkContactsListSuccess extends BdkActionSuccessEnvelope { action: "bdk.contacts.list"; access: "full" | "limited"; total: number; offset: number; hasMore: boolean; nextOffset: number | null; contacts: BdkContact[]; } type BdkContactsListResult = BdkContactsListSuccess | BdkActionErrorEnvelope; /** Success result returned by the F16c badge set/clear/get actions. */ interface BdkBadgeSuccess extends BdkActionSuccessEnvelope { action: "bdk.badge.set" | "bdk.badge.clear" | "bdk.badge.get"; /** Current badge or notification count when supplied by the action. */ count?: number; /** Native source of the reported count. */ source?: "system_badge" | "active_notifications"; /** Android counts notifications and therefore marks the result approximate. */ approximate?: boolean; /** Number of cancellable Android notifications actually removed. */ clearedNotifications?: number; } type BdkBadgeResult = BdkBadgeSuccess | BdkActionErrorEnvelope; /** Menu-selection event payload. * @example * bdk.on("menuClicked", (item) => console.log(item.returned_data)); */ interface MenuSelectionResult { /** Selected item title. * @example "Settings" */ selected_title?: string; /** Selected item data. * @example "settings" */ returned_data?: unknown; /** Selected item id. * @example "menu-demo" */ id?: string; /** Selected item text. * @example "Settings" */ text?: string; } /** Barcode or QR scan result. * @example * bdk.on("barcodeScanned", (barcode) => console.log(barcode.content)); */ interface BarcodeResult { /** Barcode type. * @example "qr" */ type?: string; /** Scanned content. * @example "BDK-DEMO" */ content?: string; } /** Native location result. * @example * bdk.on("location", (location) => console.log(location)); */ type LocationResult = string | { /** Latitude. * @example 12.34 */ latitude?: number; /** Longitude. * @example 56.78 */ longitude?: number; /** Native provider payload. * @example { accuracy: 10 } */ data?: unknown; }; /** Purchase, receipt, restore, and consume event payload. * @example * bdk.on("purchaseSuccess", (purchase) => console.log(purchase.platform, purchase.data)); */ interface PurchaseEvent { /** Platform that produced the purchase event. * @example "ios" */ platform: "ios" | "android"; /** Native purchase payload. * @example { productId: "pro" } */ data: unknown; } /** Background location enabled event payload. * @example * bdk.on("backgroundLocationEnabled", (state) => console.log(state.enabled)); */ interface BackgroundLocationEnabledResult { /** Whether background location is enabled. * @example "true" */ enabled: unknown; /** Whether tracking was already running. * @example "false" */ alreadyRunning: unknown; /** Native status reason. * @example "started" */ reason: unknown; } /** Background location disabled event payload. * @example * bdk.on("backgroundLocationDisabled", (state) => console.log(state.enabled)); */ interface BackgroundLocationDisabledResult { /** Whether background location is enabled after the disable request. * @example "false" */ enabled: unknown; } /** Fired once on the page that opened a modal, after the modal closes. `url` is the original destination you passed to navigate. `reason` is how it closed. * @example * bdk.on("navigation.dismissed", (event) => console.log(event.reason, event.url)); */ interface NavigationDismissedEvent extends BdkEventPayload { event: "navigation.dismissed"; /** How the modal closed. * @example "swipe" */ reason: "swipe" | "button" | "back" | "deeplink" | "push"; /** Original destination passed to `navigate`. * @example "https://example.com/checkout" */ url: string; } /** * Typed GATE-01+ named multiplexed events delivered via `window.bdkEvent` fan-out. * Used by `bdk.on("permissions.changed", …)` so the listener payload is * `PermissionsChangedEvent` rather than the generic `BdkEventPayload`. * Unknown event names still fall through to the string overload. * @example * bdk.on("permissions.changed", (payload) => console.log(payload.changed)); */ interface BdkNamedEvents { "permissions.changed": PermissionsChangedEvent; "att.changed": AttChangedEvent; "deeplink.received": BdkDeepLinkReceivedEvent; "auth.completed": BdkAuthCompletedEvent; "auth.cancelled": BdkAuthCancelledEvent; "push.dataReceived": BdkPushDataReceivedEvent; "push.clicked": BdkPushClickEvent; "share.received": BdkInboundShareReceivedEvent; "share.uploadProgress": BdkInboundShareUploadProgressEvent; "nfc.launchTag": BdkNfcLaunchTagEvent; "iap.purchaseCompleted": IapPurchaseCompletedEvent; "iap.transactionUpdated": IapTransactionUpdatedEvent; "navigation.dismissed": NavigationDismissedEvent; } /** Typed BDK Native event map used by `bdk.on`. * @example * bdk.on("photoCaptured", (photo) => console.log(photo.fileUrl)); */ interface BdkNativeEvents { /** Native device info changed. * @example * bdk.on("deviceInfo", (info) => console.log(info.deviceOS)); */ deviceInfo: BdkDeviceInfo; /** Contacts were returned from the native address book. * @example * bdk.on("contacts", (contacts) => console.log(contacts.length)); */ contacts: ContactResult[]; /** Screenshot image data was returned. * @example * bdk.on("screenshot", (imageData) => console.log(imageData)); */ screenshot: string; /** A photo was selected from the library. * @example * bdk.on("photoSelected", (photo) => console.log(photo.fileUrl)); */ photoSelected: MediaResult; /** A photo was captured with the camera. * @example * bdk.on("photoCaptured", (photo) => console.log(photo.fileUrl)); */ photoCaptured: MediaResult; /** A video was selected from the library. * @example * bdk.on("videoSelected", (video) => console.log(video.fileUrl)); */ videoSelected: MediaResult; /** A video was captured with the camera. * @example * bdk.on("videoCaptured", (video) => console.log(video.fileUrl)); */ videoCaptured: MediaResult; /** A native menu item was selected. * @example * bdk.on("menuClicked", (item) => console.log(item.returned_data)); */ menuClicked: MenuSelectionResult; /** A barcode or QR code was scanned. * @example * bdk.on("barcodeScanned", (barcode) => console.log(barcode.content)); */ barcodeScanned: BarcodeResult; /** A native location result was returned. * @example * bdk.on("location", (location) => console.log(location)); */ location: LocationResult; /** A device cache value was returned. * @example * bdk.on("deviceVariable", (item) => console.log(item.data)); */ deviceVariable: DeviceVariableResult; /** Native header menu button was tapped. * @example * bdk.on("headerMenuClicked", () => console.log("header menu")); */ headerMenuClicked: undefined; /** Native back button was pressed. * @example * bdk.on("backButtonPressed", () => console.log("back")); */ backButtonPressed: undefined; /** Audio recording completed. * @example * bdk.on("audioRecorded", (audio) => console.log(audio.fileUrl)); */ audioRecorded: MediaResult; /** Native popup was closed. * @example * bdk.on("popupClosed", (button) => console.log(button)); */ popupClosed: string | Record; /** Native date/time picker returned a value. * @example * bdk.on("datePicked", (date) => console.log(date)); */ datePicked: string | number; /** Native option picker returned a value. * @example * bdk.on("optionPicked", (option) => console.log(option)); */ optionPicked: string | Record; /** Biometric authentication returned a result. * @example * bdk.on("biometricResult", (result) => console.log(result.status)); */ biometricResult: BiometricResult; /** Smart Login credentials were returned. * @example * bdk.on("smartLoginCredentials", (credentials) => console.log(credentials.email)); */ smartLoginCredentials: SmartLoginCredentials; /** Native purchase succeeded. * @example * bdk.on("purchaseSuccess", (purchase) => console.log(purchase.data)); */ purchaseSuccess: PurchaseEvent; /** Native purchase failed. * @example * bdk.on("purchaseFailed", (purchase) => console.log(purchase.data)); */ purchaseFailed: PurchaseEvent; /** Native receipt data was received. * @example * bdk.on("receiptReceived", (receipt) => console.log(receipt.data)); */ receiptReceived: PurchaseEvent; /** Purchase history was restored. * @example * bdk.on("purchaseHistoryRestored", (purchase) => console.log(purchase.data)); */ purchaseHistoryRestored: PurchaseEvent; /** Product consumption succeeded. * @example * bdk.on("productConsumed", (purchase) => console.log(purchase.data)); */ productConsumed: PurchaseEvent; /** Product consumption failed. * @example * bdk.on("productConsumeFailed", (purchase) => console.log(purchase.data)); */ productConsumeFailed: PurchaseEvent; /** Native location tracking was cancelled. * @example * bdk.on("locationTrackingCancelled", (data) => console.log(data)); */ locationTrackingCancelled: string | Record; /** Audio recording was cancelled. * @example * bdk.on("audioRecordCancelled", (data) => console.log(data)); */ audioRecordCancelled: string | Record | undefined; /** Background location was enabled. * @example * bdk.on("backgroundLocationEnabled", (state) => console.log(state.enabled)); */ backgroundLocationEnabled: BackgroundLocationEnabledResult; /** Background location was disabled. * @example * bdk.on("backgroundLocationDisabled", (state) => console.log(state.enabled)); */ backgroundLocationDisabled: BackgroundLocationDisabledResult; /** Capability handshake payload was returned. * @example * bdk.on("capabilities", (capabilities) => console.log(capabilities.features)); */ capabilities: BdkCapabilities; /** Multiplexed GATE-01+ native event (every `window.bdkEvent` delivery). * * Prefer this generic listener for unknown/future event names. Named events * are also fanned out via `bdk.on("", …)` (string overload). * @example * bdk.on("bdkEvent", (payload) => console.log(payload.event)); */ bdkEvent: BdkEventPayload; /** SDK error event. * @example * bdk.on("error", (error) => console.error(error.code)); */ error: BdkError; } /** IAP product category normalized across App Store and Play Billing. * @example * const kind: BdkIapProductKind = "subscription"; */ type BdkIapProductKind = "consumable" | "nonConsumable" | "subscription" | "nonRenewingSubscription"; /** Store price normalized for display and server-safe decimal handling. * @example * const price: BdkIapPrice = { amount: "9.99", currency: "USD", formatted: "$9.99" }; */ interface BdkIapPrice { amount: string; currency: string; formatted: string; } /** One ordered billing phase in a subscription plan. * @example * const phase: BdkIapPricingPhase = { type: "trial", price: { amount: "0", currency: "USD", formatted: "Free" }, period: "P1W", cycles: 1 }; */ interface BdkIapPricingPhase { type: "trial" | "intro" | "base"; price: BdkIapPrice; period: string; /** `null` means an indefinitely recurring phase; zero is never emitted. */ cycles: number | null; } /** Purchasable subscription plan/offer. * @example * const plan: BdkIapPlan = { planId: "monthly", offerId: null, phases: [] }; */ interface BdkIapPlan { planId: string; offerId: string | null; phases: BdkIapPricingPhase[]; raw?: { prepaid?: boolean; [key: string]: unknown; }; } /** Subscription metadata attached to a normalized IAP product. * @example * const subscription: BdkIapSubscription = { groupId: null, period: "P1M", plans: [] }; */ interface BdkIapSubscription { groupId: string | null; period: string; plans: BdkIapPlan[]; } /** Product returned by `bdk.iap.products`. * @example * const product: BdkIapProduct = { id: "pro_monthly", kind: "subscription", title: "Pro", description: "Pro access", price: { amount: "9.99", currency: "USD", formatted: "$9.99" }, subscription: { groupId: null, period: "P1M", plans: [] } }; */ interface BdkIapProduct { id: string; kind: BdkIapProductKind; title: string; description: string; price: BdkIapPrice; subscription?: BdkIapSubscription; raw?: Record; } /** SDK timing controls shared by envelope-aware IAP fetches. * @example * const timing: BdkIapTimingOptions = { timeoutMs: 60000, capabilityTimeoutMs: 1500 }; */ interface BdkIapTimingOptions { /** Milliseconds to wait for the native action envelope. */ timeoutMs?: number; /** Milliseconds to wait for the capability probe before using cold-agent dispatch. */ capabilityTimeoutMs?: number; } /** Options for `bdk.iap.purchase`. * @example * await bdk.iap.purchase({ id: "pro_monthly", planId: "monthly" }); */ interface BdkIapPurchaseOptions { id: string; planId?: string; offerId?: string; /** Android product id of the active subscription being replaced. */ replaces?: string; /** Optional caller correlation id, at most 64 characters. */ requestId?: string; capabilityTimeoutMs?: number; } /** Options for the opt-in interactive `bdk.iap.purchaseAndWait` helper. * @example * await bdk.iap.purchaseAndWait({ id: "pro_monthly", timeoutMs: 300000 }); */ interface BdkIapPurchaseAndWaitOptions extends BdkIapPurchaseOptions { /** Bounds launch through the first matching outcome; not deferred settlement. */ timeoutMs?: number; } /** Transaction embedded in IAP purchase and update events. * @example * const transaction: BdkIapTransaction = { id: "2000000123", productId: "pro_monthly", planId: null, purchaseToken: null, jws: "eyJ...", autoRenewing: true }; */ interface BdkIapTransaction { id: string | null; productId: string; planId: string | null; purchaseToken: string | null; jws: string | null; autoRenewing: boolean; } /** First purchase outcome emitted for a correlated request, including `pending`. * @example * bdk.on("iap.purchaseCompleted", (event: IapPurchaseCompletedEvent) => console.log(event.state)); */ interface IapPurchaseCompletedEvent { event: "iap.purchaseCompleted"; ts: number; platform: "ios" | "android"; requestId: string | null; ok: boolean; state: "purchased" | "pending" | "cancelled" | "failed"; code: string | null; transaction?: BdkIapTransaction; } /** Unsolicited renewal, revocation, or external transaction event. * @example * bdk.on("iap.transactionUpdated", (event: IapTransactionUpdatedEvent) => console.log(event.reason)); */ interface IapTransactionUpdatedEvent { event: "iap.transactionUpdated"; ts: number; platform: "ios" | "android"; reason: "renewal" | "revoked" | "external"; transaction: BdkIapTransaction; } /** Current store entitlement normalized across platforms. * @example * const entitlement: BdkIapEntitlement = { productId: "pro_monthly", kind: "subscription", state: "active", expiresAt: null, willRenew: true, planId: null, latestTransactionId: "1", purchaseToken: null, acknowledged: true }; */ interface BdkIapEntitlement { productId: string; kind: BdkIapProductKind; state: "active" | "gracePeriod" | "billingRetry" | "revoked" | "expired"; expiresAt: string | null; willRenew: boolean; planId: string | null; latestTransactionId: string; purchaseToken: string | null; acknowledged: boolean; } /** Successful product-list response. * @example * const result: BdkIapProductsSuccess = { ok: true, action: "bdk.iap.products", platform: "ios", products: [], invalidIds: [] }; */ interface BdkIapProductsSuccess extends BdkActionSuccessEnvelope { action: "bdk.iap.products"; platform: "ios" | "android"; products: BdkIapProduct[]; invalidIds: string[]; } /** Immediate successful purchase-launch acknowledgement. * @example * const result: BdkIapPurchaseSuccess = { ok: true, action: "bdk.iap.purchase", platform: "android", state: "launched", requestId: "iap-1" }; */ interface BdkIapPurchaseSuccess extends BdkActionSuccessEnvelope { action: "bdk.iap.purchase"; platform: "ios" | "android"; state: "launched"; requestId: string; } /** Successful entitlement response. * @example * const result: BdkIapEntitlementsSuccess = { ok: true, action: "bdk.iap.entitlements", platform: "ios", entitlements: [] }; */ interface BdkIapEntitlementsSuccess extends BdkActionSuccessEnvelope { action: "bdk.iap.entitlements"; platform: "ios" | "android"; entitlements: BdkIapEntitlement[]; } /** Successful restore response. * @example * const result: BdkIapRestoreSuccess = { ok: true, action: "bdk.iap.restore", platform: "ios", restored: [] }; */ interface BdkIapRestoreSuccess extends BdkActionSuccessEnvelope { action: "bdk.iap.restore"; platform: "ios" | "android"; restored: BdkIapEntitlement[]; } /** Android receipt row accepted directly by `verifyAndroidReceipt`. * @example * await verifyAndroidReceipt(receipt.purchases[0]); */ interface BdkIapAndroidReceiptPurchase { productId: string; purchaseToken: string; packageName: string; productType: "product" | "subscription"; product_id_android: string; purchase_token_android: string; package_name_android: string; } /** Successful iOS receipt response. * @example * const receipt: BdkIapIosReceiptSuccess = { ok: true, action: "bdk.iap.receipt", platform: "ios", receipt: "base64", jws: [] }; */ interface BdkIapIosReceiptSuccess extends BdkActionSuccessEnvelope { action: "bdk.iap.receipt"; platform: "ios"; receipt: string; jws: string[]; } /** Successful Android receipt response. * @example * const receipt: BdkIapAndroidReceiptSuccess = { ok: true, action: "bdk.iap.receipt", platform: "android", purchases: [] }; */ interface BdkIapAndroidReceiptSuccess extends BdkActionSuccessEnvelope { action: "bdk.iap.receipt"; platform: "android"; purchases: BdkIapAndroidReceiptPurchase[]; } /** Successful consume response. * @example * const result: BdkIapConsumeSuccess = { ok: true, action: "bdk.iap.consume", platform: "android", consumed: true }; */ interface BdkIapConsumeSuccess extends BdkActionSuccessEnvelope { action: "bdk.iap.consume"; platform: "ios" | "android"; consumed: true; /** Remaining locally tracked units on iOS consumables. */ remaining?: number; } /** IAP capability configuration reported by native. * @example * const config: BdkIapCapabilityConfig = { planChooser: true, consumableIds: ["coins"] }; */ interface BdkIapCapabilityConfig { planChooser: boolean; consumableIds: string[]; } /** Result union for product loading, including honest cold-agent acknowledgements. * @example * const result: BdkIapProductsResult = await bdk.iap.products(["pro"]); */ type BdkIapProductsResult = BdkIapProductsSuccess | BdkActionErrorEnvelope | NativeCommandResult; /** Result union for immediate purchase launch. * @example * const result: BdkIapPurchaseResult = await bdk.iap.purchase({ id: "pro" }); */ type BdkIapPurchaseResult = BdkIapPurchaseSuccess | BdkActionErrorEnvelope | NativeCommandResult; /** Result union for the first correlated purchase outcome. * @example * const result: BdkIapPurchaseAndWaitResult = await bdk.iap.purchaseAndWait({ id: "pro" }); */ type BdkIapPurchaseAndWaitResult = IapPurchaseCompletedEvent | BdkActionErrorEnvelope | NativeCommandResult; /** Result union for current entitlements. * @example * const result: BdkIapEntitlementsResult = await bdk.iap.entitlements(); */ type BdkIapEntitlementsResult = BdkIapEntitlementsSuccess | BdkActionErrorEnvelope | NativeCommandResult; /** Result union for restore. * @example * const result: BdkIapRestoreResult = await bdk.iap.restore(); */ type BdkIapRestoreResult = BdkIapRestoreSuccess | BdkActionErrorEnvelope | NativeCommandResult; /** Result union for platform receipt data. * @example * const result: BdkIapReceiptResult = await bdk.iap.receipt(); */ type BdkIapReceiptResult = BdkIapIosReceiptSuccess | BdkIapAndroidReceiptSuccess | BdkActionErrorEnvelope | NativeCommandResult; /** Result union for consumption. * @example * const result: BdkIapConsumeResult = await bdk.iap.consume("coins"); */ type BdkIapConsumeResult = BdkIapConsumeSuccess | BdkActionErrorEnvelope | NativeCommandResult; export { type BdkHealthActionOptions as $, type AttStatusResult as A, type BdkNativeEvents as B, type BdkMediaPickPhotosResult as C, type BdkMediaTakePhotoOptions as D, type BdkMediaTakePhotoResult as E, type BdkMediaItem as F, type BdkAuthSignInOptions as G, type BdkAuthSignInResult as H, type BdkIapTimingOptions as I, type BdkIapProductsResult as J, type BdkIapPurchaseOptions as K, type BdkIapPurchaseResult as L, type BdkIapPurchaseAndWaitOptions as M, type NativeCommandResult as N, type BdkIapPurchaseAndWaitResult as O, type PermissionsStatusOptions as P, type BdkIapRestoreResult as Q, type BdkIapEntitlementsResult as R, type BdkIapReceiptResult as S, type BdkIapConsumeResult as T, type BdkShareSendOptions as U, type BdkShareResult as V, type BdkShareFilesOptions as W, type BdkInboundSharesResult as X, type BdkInboundShareRetryOptions as Y, type BdkInboundShareRetryResult as Z, type BdkInboundShare as _, type BdkNamedEvents as a, type BdkHealthQuantitySample as a$, type BdkHealthStatusResult as a0, type BdkHealthRequestOptions as a1, type BdkHealthRequestResult as a2, type BdkHealthReadOptions as a3, type BdkHealthReadResult as a4, type BdkHealthAggregateOptions as a5, type BdkHealthAggregateResult as a6, type HealthTypeId as a7, type BdkNfcReadOptions as a8, type BdkNfcReadResult as a9, type BdkAuthWebviewSuccess as aA, type BdkBadgeSuccess as aB, type BdkCapabilityFeature as aC, type BdkContact as aD, type BdkContactEmail as aE, type BdkContactLabelType as aF, type BdkContactPhone as aG, type BdkContactsListSuccess as aH, type BdkContactsPickSuccess as aI, type BdkCriticalNotificationStatus as aJ, type BdkDeepLinkBuildPathOptions as aK, type BdkDeepLinkBuildUrlOptions as aL, type BdkDeepLinkCapabilityConfig as aM, type BdkDeepLinkEmptySuccess as aN, type BdkDeepLinkPathRecord as aO, type BdkDeepLinkQuery as aP, type BdkDeepLinkReceivedEvent as aQ, type BdkDeepLinkReceivedSuccess as aR, type BdkDeepLinkRecordBase as aS, type BdkDeepLinkUrlRecord as aT, BdkError as aU, type BdkErrorCode as aV, type BdkErrorOptions as aW, type BdkHealthAggregateSuccess as aX, type BdkHealthAuthorizationEntry as aY, type BdkHealthCapabilityConfig as aZ, type BdkHealthDiscreteBucket as a_, type BdkNfcWriteOptions as aa, type BdkNfcWriteResult as ab, type BdkNfcCancelResult as ac, type BdkNfcLaunchTagResult as ad, type BdkNfcOpenSettingsResult as ae, type BdkCapabilities as af, type BdkNativeConfig as ag, type BdkDeviceInfo as ah, type BdkEnvironment as ai, type AttChangedEvent as aj, type AttRequestSuccess as ak, type AttStatus as al, type AttStatusSuccess as am, type BackgroundLocationDisabledResult as an, type BackgroundLocationEnabledResult as ao, type BarcodeResult as ap, type BdkActionErrorEnvelope as aq, type BdkActionSuccessEnvelope as ar, type BdkAuthCancelledEvent as as, type BdkAuthCompletedEvent as at, type BdkAuthError as au, type BdkAuthErrorCode as av, type BdkAuthOAuthCapabilityConfig as aw, type BdkAuthPageSuccess as ax, type BdkAuthProvider as ay, type BdkAuthSuccessDetails as az, type BdkEventPayload as b, type BdkPermissionType as b$, type BdkHealthReadSuccess as b0, type BdkHealthRequestSuccess as b1, type BdkHealthSleepSample as b2, type BdkHealthSleepStage as b3, type BdkHealthStatusSuccess as b4, type BdkHealthSumBucket as b5, type BdkHealthTypeId as b6, type BdkHealthWorkoutSample as b7, type BdkIapAndroidReceiptPurchase as b8, type BdkIapAndroidReceiptSuccess as b9, type BdkMediaError as bA, type BdkMediaErrorCode as bB, type BdkMediaPickPhotosSuccess as bC, type BdkMediaResultMode as bD, type BdkMediaTakePhotoSuccess as bE, type BdkNavigationModalCapabilityConfig as bF, type BdkNfcCancelSuccess as bG, type BdkNfcCapabilityConfig as bH, type BdkNfcErrorCode as bI, type BdkNfcExternalRecord as bJ, type BdkNfcLaunchTagEvent as bK, type BdkNfcLaunchTagSuccess as bL, type BdkNfcOpenSettingsSuccess as bM, type BdkNfcReadSuccess as bN, type BdkNfcRecord as bO, type BdkNfcTag as bP, type BdkNfcTextRecord as bQ, type BdkNfcUnknownRecord as bR, type BdkNfcUriRecord as bS, type BdkNfcWritableRecord as bT, type BdkNfcWriteSuccess as bU, type BdkNotificationAuthorization as bV, type BdkNotificationsCapabilityConfig as bW, type BdkNotificationsOpenSettingsSuccess as bX, type BdkNotificationsStatusSuccess as bY, type BdkPermissionEntry as bZ, type BdkPermissionStatus as b_, type BdkIapCapabilityConfig as ba, type BdkIapConsumeSuccess as bb, type BdkIapEntitlement as bc, type BdkIapEntitlementsSuccess as bd, type BdkIapIosReceiptSuccess as be, type BdkIapPlan as bf, type BdkIapPrice as bg, type BdkIapPricingPhase as bh, type BdkIapProduct as bi, type BdkIapProductKind as bj, type BdkIapProductsSuccess as bk, type BdkIapPurchaseSuccess as bl, type BdkIapRestoreSuccess as bm, type BdkIapSubscription as bn, type BdkIapTransaction as bo, type BdkInboundShareCapabilityConfig as bp, type BdkInboundShareFileItem as bq, type BdkInboundShareItem as br, type BdkInboundShareReceivedEvent as bs, type BdkInboundShareRetrySuccess as bt, type BdkInboundShareTextItem as bu, type BdkInboundShareUpload as bv, type BdkInboundShareUploadProgressEvent as bw, type BdkInboundShareUrlItem as bx, type BdkInboundSharesSuccess as by, type BdkMediaCapabilityConfig as bz, type BdkPushClickEvent as c, type BdkPlatform as c0, type BdkPushClickCapabilityConfig as c1, type BdkPushDataCapabilityConfig as c2, type BdkPushDataMessage as c3, type BdkPushDataMessagesSuccess as c4, type BdkPushDataReceivedEvent as c5, type BdkPushPendingClicksSuccess as c6, type BdkRequestCriticalSuccess as c7, type BdkShareError as c8, type BdkShareErrorCode as c9, type PushPermissionStatus as cA, type PushPermissionSuccess as cB, type RemoveLoadingMode as cC, type SmartLoginCredentials as cD, UnsupportedPlatformError as cE, UnsupportedVersionError as cF, ValidationError as cG, isBdkError as cH, isBdkSuccess as cI, toErrorMessage as cJ, type BdkShareFileItem as ca, type BdkShareFilesCapabilityConfig as cb, type BdkShareItem as cc, type BdkShareSuccess as cd, type BdkShareTextItem as ce, type BdkShareUrlItem as cf, type BdkTimeSensitiveStatus as cg, type BiometricResult as ch, type ContactResult as ci, type DeviceVariableResult as cj, type IapPurchaseCompletedEvent as ck, type IapTransactionUpdatedEvent as cl, ListenerError as cm, type LocationResult as cn, type MediaResult as co, type MenuSelectionResult as cp, NativeUnavailableError as cq, type NavigationDismissedEvent as cr, NotNativeError as cs, type PageFitMode as ct, type PermissionStatusSuccess as cu, type PermissionsChangedEvent as cv, type PermissionsOpenSettingsSuccess as cw, ProviderError as cx, type PurchaseEvent as cy, type PushOpenSettingsSuccess as cz, type BdkActionEnvelope as d, type PermissionStatusResult as e, type PermissionsOpenSettingsOptions as f, type PermissionsOpenSettingsResult as g, type PermissionControlOptions as h, type PushPermissionResult as i, type PushOpenSettingsResult as j, type BdkPushDataMessagesResult as k, type BdkPushPendingClicksResult as l, type BdkPushClickRecord as m, type BdkNotificationsStatusResult as n, type BdkPhase5TimingOptions as o, type BdkRequestCriticalResult as p, type BdkNotificationsOpenSettingsOptions as q, type BdkNotificationsOpenSettingsResult as r, type AttRequestResult as s, type BdkContactsPickResult as t, type BdkContactsListResult as u, type BdkBadgeResult as v, type BdkDeepLinkGetResult as w, type BdkDeepLinkRecord as x, type BdkDeepLinkBuildOptions as y, type BdkMediaPickPhotosOptions as z };