Listen for events

Subscribe with bdk.on(event, listener) to receive the results native features report back.

Subscribe to an event

Register a listener for a native event. The payload is typed from the event name (see BdkNativeEvents). Dot-named events such as iap.purchaseCompleted and deeplink.received use the same bdk.on call. Subscribe right after createBdkNative() so you don't miss a result. bdk.on returns an unsubscribe function — call it on unmount.

import { createBdkNative } from "@bdk/native/browser";

const bdk = createBdkNative();

const off = bdk.on("deviceInfo", (info) =>
  console.log(info.deviceOS, info.bdkRelease, info.playerId)
);

off(); // stop listening

Get the result of a call

Subscribe before you call the method. Awaiting the call confirms it was dispatched, not that it succeeded — the result arrives on the event. Some events fire quickly (photos, barcode, location, pickers, popups, contacts, screenshots); others may resolve much later or never (purchases, receipts, biometrics, Smart Login).

iap.purchaseIos / purchaseAndroid take { id, type }, where type is "product" or "subscription". Match these key names exactly — they are the native contract.

bdk.on("barcodeScanned", (code) => console.log("scanned", code));
bdk.on("location", (loc) => console.log("location", loc));

await bdk.media.scanBarcode();
await bdk.location.getCurrentPosition();

All events and payloads

Every event and the payload its listener receives. The field-level shape of each object is in Objects.

EventListener receives
deviceInfoBdkDeviceInfo
photoSelected / photoCapturedMediaResult
audioRecordedMediaResult
screenshotthe captured screenshot image (a data URI you can preview or upload)
barcodeScannedthe scanned code: its type and decoded content
contactsthe device address book: each contact's name, phone numbers, and emails
locationthe device position as a "latitude,longitude" string or an object with latitude and longitude
backgroundLocationEnabled{ enabled, alreadyRunning, reason }
backgroundLocationDisabled{ enabled }
deviceVariable{ name, data }
menuClickedthe menu item the user tapped
popupClosedwhich button dismissed the popup
datePickedthe date/time the user selected
backButtonPressedundefined
biometricResult{ data, status, platform }
smartLoginCredentials{ email, password }
purchaseSuccess / purchaseFailed{ platform, data }
receiptReceived{ platform, data }
capabilitiesBdkCapabilities
permissions.changed{ changed, previous, permissions }
att.changed{ status, idfa }
deeplink.receivedBdkDeepLinkRecord
auth.completed{ mode, provider, handoff }
auth.cancelled{ reason }
push.dataReceived{ id, receivedAt, appState, data }
share.received{ share } (BdkInboundShare)
share.uploadProgress{ shareId, itemIndex, bytesSent, totalBytes, progress }
nfc.launchTag{ url, tag }
iap.purchaseCompleted{ platform, requestId, ok, state, code, transaction }
iap.transactionUpdated{ reason, transaction }
errorBdkError
// The payload type is inferred from the event name.
bdk.on("deviceInfo", (info) => info.playerId);          // BdkDeviceInfo
bdk.on("photoCaptured", (photo) => photo.fileUrl);       // MediaResult
bdk.on("iap.purchaseCompleted", (e) => e.state);         // { platform, requestId, ok, state, ... }
bdk.on("biometricResult", ({ status, platform }) => {}); // { data, status, platform }
bdk.on("error", (err) => err.code);                      // BdkError

Handle errors

A throwing listener doesn't break the others. Catch errors centrally via the error event or the onError config callback — both receive a BdkError.

bdk.on("error", (err) => console.error(err.code, err.message, err.details));

// or at init:
const bdk = createBdkNative({
  onError: (err) => reportToSentry(err)
});