API Reference
Complete reference for ProphetXProvider props, all hooks, events, and exported types across React, React Native, and JavaScript SDKs.
The Flutter SDK (
prophetx_sdk) mirrors the React Native surface — same provider, same options, same event payloads. Differences are called out per-section: hooks becomeChangeNotifierflow controllers onProphetX.of(context), callbacks fire on DartFunctiontypes, and the event bus is a DartStream.
useOnboarding/openOnboardingis not available. It used to combine terms + KYC + a first deposit, but the route is permanently gated off with an error screen today (the underlying Verified Inc API integration was never approved for that integration type). Use 1-Click Signup (useOneClickSignup) for new users instead, and Document verification (useKyc/useIdUpload) for re-verifying an existing user — see those sections below.onGeofenceBlocked/PROPHETX_GEOFENCE_BLOCKEDis real and defined on every flow except 1-Click Signup, but geo-eligibility for the embed is enforced at token issuance rather than per-request — don't expect it to fire in normal operation with a validly-issued embed token.
ProphetXProvider
Props
Environment
Pass a preset name or a custom config object:
| Name | Embed URL | API Base URL |
|---|---|---|
"production" | https://embed.prophetx.co | https://isv-api.prophetx.co |
"staging" | https://isv-embed-fe-embed.vercel.app | https://isv-api.staging.prophetx.dev |
"sandbox" | https://isv-embed-fe-embed-sandbox.vercel.app | https://isv-api.sandbox.prophetx.dev |
Custom config:
type EnvironmentConfig = {
embedUrl: string;
apiBaseUrl: string;
};AuthConfig
Optional. When provided, the SDK manages authentication internally — you don't need to pass token yourself.
| Field | Type | Required | Description |
|---|---|---|---|
apiBaseUrl | string | Yes | API base URL for authentication requests. |
refreshBufferSeconds | number | No | Auto-refresh the token this many seconds before expiry. Default: 30. |
onAuthStateChanged | (state: AuthState) => void | No | Called whenever auth state changes. |
getCredentials | () => LoginCredentials | Promise<LoginCredentials> | No | Returns credentials on demand for auto-refresh. Avoids storing plaintext credentials in memory. |
storage | StorageAdapter | No | Custom storage adapter. Defaults to browser localStorage. |
http | HttpAdapter | No | Custom HTTP adapter. Defaults to fetch. |
random | RandomAdapter | No | Custom random number adapter. |
DevToolsConfig
| Field | Type | Required | Description |
|---|---|---|---|
enabled | boolean | No | Enable or disable devtools. |
logLevel | "none" | "error" | "warn" | "info" | "debug" | No | Log level threshold. |
redactPII | boolean | No | When true, masks tokens, passwords, and emails in log output. |
onEvent | (entry: DevToolsLogEntry) => void | No | Custom log sink — receives every log entry. |
Deposit flow
Opens the deposit flow. The SDK renders a modal that handles the full deposit UI. React/React Native expose this via the useDeposit hook; the Flutter SDK exposes a DepositFlow controller on ProphetX.of(context).deposit.
Controller surface
| Surface | Field | Type | Description |
|---|---|---|---|
| React / React Native | open | (options?: OpenDepositOptions) => void | Opens the deposit modal. |
| React / React Native | close | () => void | Closes the deposit modal programmatically. |
| React / React Native | isOpen | boolean | Whether the deposit modal is currently open. |
| Flutter | open | ([OpenDepositOptions?]) => void | Opens the deposit modal. |
| Flutter | close | () => void | Closes the deposit modal programmatically. |
| Flutter | isOpen | bool | Whether the deposit modal is currently open. Notifies via ChangeNotifier. |
OpenDepositOptions
| Option | Type | Description |
|---|---|---|
onSuccess | (transactionId: string, amount?: number) => void | Fires when the deposit completes. Store transactionId on your backend to track the deposit. |
onError | (code: string, message: string) => void | Fires on any error. See Error Codes. |
onCancel | () => void | Fires when the user closes the modal without completing the deposit. |
onReady | () => void | Fires when the embed iframe has loaded and is ready to interact. |
onGeofenceBlocked | (stateCode: string, reason: string) => void | Fires when the user's location is outside a permitted jurisdiction. |
The JavaScript SDK's
OpenOptionsalso acceptstoken,theme, andonSessionExpired— these are passed per-call instead of through a provider.
Withdraw flow
Opens the withdrawal flow. Follows the same pattern as the deposit flow above. React/React Native expose useWithdraw; Flutter exposes ProphetX.of(context).withdraw.
Controller surface
| Surface | Field | Type | Description |
|---|---|---|---|
| React / React Native | open | (options?: OpenWithdrawOptions) => void | Opens the withdraw modal. |
| React / React Native | close | () => void | Closes the withdraw modal programmatically. |
| React / React Native | isOpen | boolean | Whether the withdraw modal is currently open. |
| Flutter | open | ([OpenWithdrawOptions?]) => void | Opens the withdraw modal. |
| Flutter | close | () => void | Closes the withdraw modal programmatically. |
| Flutter | isOpen | bool | Whether the withdraw modal is currently open. Notifies via ChangeNotifier. |
OpenWithdrawOptions
| Option | Type | Description |
|---|---|---|
onSuccess | (transactionId: string, amount?: number) => void | Fires when the withdrawal completes. |
onError | (code: string, message: string) => void | Fires on any error. See Error Codes. |
onCancel | () => void | Fires when the user closes the modal without completing the withdrawal. |
onReady | () => void | Fires when the embed iframe has loaded and is ready to interact. |
onGeofenceBlocked | (stateCode: string, reason: string) => void | Fires when the user's location is outside a permitted jurisdiction. |
1-Click Signup flow
Replaces the old "Onboarding flow."
useOnboarding/openOnboardingopened a combined terms + KYC + first-deposit experience that is not available in the current embed — the route is permanently gated off with an error screen, because the underlying Verified Inc API integration was never approved for that integration type. 1-Click Signup, documented below, is the real, live path for creating a new user from a phone number. It has a different contract: notoken(it runs before a user exists), a backend-mintedsessionKeyinstead, andonOneClick*callbacks rather thanonKyc*. If you need terms acceptance too, open the Terms flow separately after redeeming the identity.
Creates a ProphetX user from a phone number in about ten seconds, with no signup form of your own. The user confirms their phone by one-time code inside Verified Inc's own hosted modal, reviews the identity Verified already holds for them, and shares it. Your backend redeems that identity and the user exists — KYC has not run yet at that point; it starts once your backend redeems the identity. React/React Native expose useOneClickSignup; Flutter exposes ProphetX.of(context).oneClickSignup.
This is the one flow with no embed token at all — it carries a single-use sessionKey (minted by your backend via POST /private/v1/one-click/sessions) instead.
Controller surface
| Surface | Field | Type | Description |
|---|---|---|---|
| React / React Native | open | (options: OpenOneClickSignupOptions) => void | Opens the modal. Unlike other flows, options are required — there's no opening this one without a sessionKey. |
| React / React Native | close | () => void | Closes the modal programmatically. |
| React / React Native | isOpen | boolean | Whether the modal is currently open. |
| Flutter | open | (OpenOneClickSignupOptions) => void | Opens the modal. Options are required here too. |
| Flutter | close | () => void | Closes the modal programmatically. |
| Flutter | isOpen | bool | Whether the modal is currently open. Notifies via ChangeNotifier. |
OpenOneClickSignupOptions
| Option | Type | Description |
|---|---|---|
sessionKey | string (required) | Single-use key from POST /private/v1/one-click/sessions. Consumed by one modal open — a spent or lapsed key must be re-minted. |
environment | 'sandbox' | 'production' (required) | Must match the environment the key was minted for. Passed straight to Verified's own SDK. |
onOneClickSuccess | (identityUuid: string) => void | Always present — unlike document verification's KYC success, 1-Click always yields an identity. |
onOneClickDeclined | () => void | The user chose not to share. Not an error — fall back to manual signup. |
onOneClickFailed | (reason: string, retryable?: boolean) => void | Terminal. retryable is true only for a spent/lapsed session key — everything else (no credentials found, risk score, exhausted attempts) is not recoverable by reopening. |
onCancel | () => void | Fires when the user closes the modal. |
onError | (code: string, message: string) => void | Fires on any error. See Error Codes. |
onReady | () => void | Fires when the embed iframe has loaded. |
There is no token or redirectUrl on this flow. onGeofenceBlocked is defined and wired identically to every other flow, but it will never actually fire here — 1-Click runs before a user exists, so its tokenless session is treated as always-allowed by the geo gate rather than being evaluated against it.
Terms flow
There is no
useTerms/openTermsSDK method. A previous version of this page presented terms acceptance as a first-class hook alongside deposit/withdraw/KYC. It isn't — the SDK's flow-route union covers deposit, withdraw, 1-Click Signup, and document verification only. Terms acceptance is a standalone route (/tandc) you host yourself in a raw iframe, driving the low-levelpostMessagehandshake directly (see postMessage Protocol). It genuinely is gated on deposit and withdraw, though — every deposit/withdraw permission requires the terms gate, so a user who has never accepted anything getsPERMISSION_DENIEDwithtermsinpending_gateson those calls.
Point an iframe at {embedBaseUrl}/tandc and run the same session handshake every flow uses: wait for PROPHETX_EMBED_LOADED, then post PROPHETX_SESSION with your token (and optionally PROPHETX_THEME).
// React — no useTerms hook; a plain iframe + postMessage listener
function AcceptTermsFrame({ token, onAccepted, onCancel }) {
const iframeRef = useRef(null);
useEffect(() => {
function handleMessage(event) {
if (event.origin !== embedOrigin) return;
const { type, payload } = event.data;
switch (type) {
case "PROPHETX_EMBED_LOADED":
iframeRef.current.contentWindow.postMessage(
{ type: "PROPHETX_SESSION", payload: { token } },
embedOrigin
);
break;
case "PROPHETX_SUCCESS":
// payload is always { transactionId: "tandc", amount: 0 } — not a
// real transaction reference, don't reconcile it as one.
onAccepted();
break;
case "PROPHETX_CANCEL":
onCancel();
break;
// This route never emits PROPHETX_ERROR — fetch/accept failures
// render their own in-embed error screen with Try Again instead.
}
}
window.addEventListener("message", handleMessage);
return () => window.removeEventListener("message", handleMessage);
}, [token]);
return <iframe ref={iframeRef} src={`${embedBaseUrl}/tandc`} />;
}Messages this route sends
| Message | When | Payload |
|---|---|---|
PROPHETX_READY | Once the terms fetch resolves (or fails) — not just once the session validates | — |
PROPHETX_SUCCESS | Acceptance POST returned 200 | { transactionId: "tandc", amount: 0 } |
PROPHETX_CANCEL | User closes out. In the shipped screen the only route to this is Close on the success page — the terms screen itself has no back/cancel control | — |
PROPHETX_GEOFENCE_BLOCKED | Location check fails | { stateCode, reason } |
PROPHETX_RESIZE | Content height changes (document list length drives this) | { height } |
This route never emits PROPHETX_ERROR — a terms-fetch failure and an accept failure both render an error page inside the embed with Try Again, so don't wait on an error message to know something went wrong.
What users see
- Document list. The documents come from
GET /embed/v1/termsverbatim, with document typesPRIVACY_POLICY,TERMS_OF_USE,MARKET_PARTICIPANT_AGREEMENT,RISK_DISCLOSURE_STATEMENT,RULEBOOK, each with a checkbox and a link to the full document. An "Accept all" checkbox toggles all documents at once. Continue stays disabled until every document is checked — there's no partial acceptance. - Continue. Submits acceptance in a single request. The screen goes back to the same loading state as the initial fetch — a submit and a fetch look identical.
- Terminal state. Success shows a result page and sends
PROPHETX_SUCCESS; failure shows an in-embed error page with Try Again (which restarts from the terms fetch, wiping any checked boxes).
Don't log or reconcile transactionId as a payment reference — it's the literal string "tandc", and amount: 0 doesn't mean a zero-value transaction; no money moves in this flow at all.
Document verification flow
This is not a phone/OTP flow. A previous version of this page described
useKycas opening a phone-entry → SMS-OTP → PII-confirmation experience. That's Verified Inc's UI, and it's what 1-Click Signup uses (see above) —useKycnever opened it.useKycopens a document-photo-upload flow reviewed by IDComply, described below.
For a user who already exists and whose automated KYC check came back FAILURE, this opens a government-ID photo upload reviewed by IDComply. React/React Native expose useKyc (a historical alias, kept for backward compatibility) and useIdUpload (the current preferred name) — both open the exact same flow. Flutter exposes ProphetX.of(context).idUpload.
This flow is narrow by design: it only reaches the document step for a user whose automated check actually came back FAILURE. Anyone already verified, still under review, or out of attempts sees the matching terminal screen within a second or two instead — that's expected behavior, not a bug. Gate any "Verify ID" entry point on the user's KYC status rather than showing it unconditionally.
Controller surface
| Surface | Field | Type | Description |
|---|---|---|---|
| React / React Native | open | (options?: OpenIdUploadOptions) => void | Opens the modal. |
| React / React Native | close | () => void | Closes the modal programmatically. |
| React / React Native | isOpen | boolean | Whether the modal is currently open. |
| Flutter | open | ([OpenIdUploadOptions?]) => void | Opens the modal. |
| Flutter | close | () => void | Closes the modal programmatically. |
| Flutter | isOpen | bool | Whether the modal is currently open. Notifies via ChangeNotifier. |
OpenIdUploadOptions vs. OpenKycOptions
These two option types are identical except for exactly one field, redirectUrl — present on OpenIdUploadOptions, absent on OpenKycOptions. That's the one functional reason to prefer useIdUpload over the legacy useKyc alias: on native, a user who finishes in the device browser without a redirectUrl lands on the vendor's own web page instead of back in your app. On web there's no functional difference — migrating is housekeeping, not a fix.
| Option | Type | Description |
|---|---|---|
redirectUrl | string — useIdUpload only, not on useKyc | Absolute URL IDComply returns the user to when they finish. Defaults to an in-embed "you can close this" page. Native apps must set this to a deep link (e.g. myapp://kyc/return) — otherwise the OS browser can't hand control back to your app. This is effectively required for native, which is why native integrations should call useIdUpload, not useKyc. |
onSuccess | (transactionId: string, amount?: number) => void | Not emitted by this flow (no transaction) — present only for parity with the shared callbacks union. |
onKycSuccess | (identityUuid?: string) => void | Fires when the document is verified. No identityUuid — the IDPV API returns none. You already have the user's UUID from POST /users. |
onKycFailed | (reason: string, retryable?: boolean) => void | Fires when rejected. retryable is false for compliance outcomes and exhausted attempts — branch on it, not reason, which is for logging only. |
onKycPending | () => void | Fires when the document was submitted but review hasn't resolved yet. |
onError | (code: string, message: string) => void | Fires on any error. See Error Codes. |
onCancel | () => void | Fires when the user closes the modal. |
onReady | () => void | Fires when the embed iframe has loaded and is ready to interact. |
onGeofenceBlocked | (stateCode: string, reason: string) => void | See the geofence note at the top of this page. |
What users see
Once you call open():
- The embed reads the user's KYC status first. If they're not eligible (already verified, still under review, compliance-failed, or attempts exhausted), it stops here and shows the matching terminal screen — no attempt is consumed. All four ineligible cases answer the same
409 kyc_not_retryablefrom the API; the embed disambiguates by checking status first, so you just receive the resolved outcome. - If eligible, it mints an IDComply session and opens the hosted form in a second browser tab — IDComply sets
X-Frame-Options/frame-ancestors, so it cannot be shown in an iframe. There is no in-modal fallback. - The modal shows a "Finish Verifying Your Identity" waiting screen and polls while the user is in the other tab. Document capture takes minutes, so this wait is deliberately generous.
- When the session finishes, the verdict resolves and the modal lands on a terminal screen, then fires the corresponding callback. Unlike 1-Click Signup, there's no further async step after this — by the time your callback fires, the decision is final.
Wallet
Fetches and returns the user's current wallet balance. Requires ProphetXProvider with an environment configured. React/React Native expose useWallet; Flutter exposes ProphetX.of(context).wallet (a ChangeNotifier).
Return value (React / React Native)
| Field | Type | Description |
|---|---|---|
balance | WalletBalance | null | Current balance, or null if not yet fetched. |
loading | boolean | Whether a fetch is in progress. |
error | ProphetXApiError | null | Last error, or null. |
refetch | () => Promise<void> | Call to re-fetch the balance. Not automatic — call it on mount and after deposits/withdrawals. |
WalletBalance
| Field | Type | Description |
|---|---|---|
totalBalance | number | The user's available balance. |
currency | string | Currency code (e.g. "USD"). |
JavaScript SDK
The vanilla SDK exposes a wallet property on the SDK instance:
| Method | Type | Description |
|---|---|---|
sdk.wallet.getBalance() | () => Promise<WalletBalance> | Returns the user's balance. sdk.wallet is null if auth was not configured. |
Flutter
ProphetX.of(context).wallet is a WalletClient that extends ChangeNotifier. Pair it with ListenableBuilder to react to balance / loading / error transitions.
| Field | Type | Description |
|---|---|---|
balance | WalletBalance? | Current balance, or null if not yet fetched. |
loading | bool | Whether a fetch is in progress. |
error | Object? | Last error, or null. |
refetch | Future<WalletBalance?> Function() | Re-fetches the balance. Call on mount and after deposits/withdrawals. |
Auth
Manages user authentication. Requires ProphetXProvider with the auth prop configured. React/React Native expose useAuth; Flutter exposes ProphetX.of(context).auth (an AuthManager that extends ChangeNotifier).
Return value (React / React Native)
| Field | Type | Description |
|---|---|---|
state | AuthState | Current authentication state. See AuthState. |
login | (credentials: LoginCredentials) => Promise<LoginResult> | Authenticate with email and password. |
logout | () => void | Clear the token and reset state. |
token | string | null | Current JWT, or null if unauthenticated. |
isAuthenticated | boolean | Convenience boolean — true when state.status === "authenticated". |
AuthState
| Status | Fields | Description |
|---|---|---|
"unauthenticated" | — | No active session. |
"authenticating" | — | Login in progress. |
"authenticated" | token: string, expiresAt: number | Active session with a valid JWT. |
"expired" | lastToken: string | Session expired. Contains the last token for reference. |
"error" | error: ProphetXAuthError | Authentication failed. |
LoginCredentials
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | User's email address. |
password | string | Yes | User's password. |
deviceId | string | No | Optional device identifier. |
LoginResult
| Field | Type | Description |
|---|---|---|
token | string | Signed JWT. |
expiresAt | number | Unix timestamp (ms) when the token expires. |
ProphetXAuthError
| Field | Type | Description |
|---|---|---|
type | "AUTH_ERROR" | Always "AUTH_ERROR". |
code | "INVALID_CREDENTIALS" | "NETWORK_ERROR" | "SERVER_ERROR" | "TIMEOUT" | Error category. |
message | string | Human-readable error message. |
status | number | undefined | HTTP status code, if applicable. |
JavaScript SDK
The vanilla SDK exposes an auth property on the SDK instance:
| Method | Type | Description |
|---|---|---|
sdk.auth.login(credentials) | (LoginCredentials) => Promise<LoginResult> | Authenticate. |
sdk.auth.logout() | () => void | Clear the session. |
sdk.auth.getToken() | () => string | null | Get the current JWT. |
sdk.auth.getState() | () => AuthState | Get the current auth state. |
sdk.auth.onStateChange(cb) | (cb: (state: AuthState) => void) => () => void | Subscribe to state changes. Returns an unsubscribe function. |
sdk.auth.handleSessionExpired() | () => Promise<string | null> | Re-authenticates using the getCredentials callback from AuthConfig. |
sdk.auth.destroy() | () => void | Tear down the auth manager and clear timers. |
sdk.authisnullifAuthConfigwas not passed tocreateProphetX.
Flutter
ProphetX.of(context).auth is an AuthManager that extends ChangeNotifier. state is a sealed hierarchy (Unauthenticated, Authenticating, Authenticated, Expired, AuthError) — match on it with Dart 3 pattern syntax.
| Member | Type | Description |
|---|---|---|
login | Future<LoginResult> Function(LoginCredentials) | Authenticate with email + password. Throws ProphetXAuthError. |
logout | void Function() | Clear the session. |
token | String? | Current JWT, or null when not in the Authenticated state. |
isAuthenticated | bool | true when state is Authenticated. |
state | AuthState | Sealed hierarchy. See enum below. |
handleSessionExpired | Future<String?> Function() | Re-authenticates using the getCredentials callback from AuthConfig. Used internally as the default onSessionExpired. |
AuthState subtypes: Unauthenticated, Authenticating, Authenticated(token, expiresAt), Expired(lastToken), AuthError(error). expiresAt on Flutter is Unix seconds (the JS SDKs use milliseconds).
ProphetXAuthError.code is the Dart enum AuthErrorCode { invalidCredentials, networkError, serverError, timeout }.
Events
Subscribes to all SDK events globally. Useful for analytics, logging, or cross-cutting concerns that apply regardless of which flow is open. React/React Native expose useEvents; Flutter exposes a broadcast Stream on ProphetX.of(context).events.
ProphetXEventHandlers (React / React Native)
All fields are optional. Pass only the events you care about.
| Handler | Payload | Description |
|---|---|---|
onReady | — | Embed iframe loaded and ready. |
onSuccess | { transactionId: string, amount?: number } | Transaction completed. |
onError | { code: string, message: string } | An error occurred. |
onCancel | — | User closed the modal. |
onKycSuccess | { identityUuid: string } | Identity verification passed. |
onKycFailed | { reason: string } | Identity verification failed. |
onKycPending | — | Identity verification submitted, awaiting result. |
onGeofenceBlocked | { stateCode: string, reason: string } | User's location is not permitted. |
Note:
useEventsreceives payload data as objects (e.g.{ transactionId, amount }), while flow hook callbacks receive them as positional arguments (e.g.(transactionId, amount)).
Flutter event types
The Flutter SDK uses a sealed ProphetXEvent hierarchy. Subscribe to a single subtype with events.on<T>(handler) or to the full union with events.stream.listen(...).
| Event subtype | Fields | Description |
|---|---|---|
ReadyEvent | — | Embed iframe loaded and ready. |
SuccessEvent | transactionId: String, amount: num? | Transaction completed. |
ErrorEvent | code: String, message: String | An error occurred. |
CancelEvent | — | User dismissed the modal. |
KycSuccessEvent | identityUuid: String | Identity verification passed. |
KycFailedEvent | reason: String | Identity verification failed. |
KycPendingEvent | — | Identity verification submitted, awaiting result. |
GeofenceBlockedEvent | stateCode: String, reason: String | User's location is not permitted. |
SessionExpiredEvent | — | The session token has expired. |
SessionRefreshedEvent | token: String | A new session token was obtained after expiry. |
FlowOpenEvent | flow: String | A flow modal was opened. flow is "deposit", "withdraw", "onboarding", or "kyc". |
FlowCloseEvent | flow: String | A flow modal was closed. |
ProphetXEmbed
Low-level iframe component. Use this when you need direct control over the embed lifecycle — most integrations should use the hooks above instead.
This component is only available in
@prophetx/sdk-react.
function CustomEmbed() {
const ref = useRef<ProphetXEmbedHandle>(null);
return (
<ProphetXEmbed
ref={ref}
open={true}
onOpenChange={(open) => console.log("Open state:", open)}
src="https://embed.prophetx.co/deposit"
token={token}
title="Deposit"
theme={{ mode: "dark" }}
onSuccess={(transactionId, amount) => console.log("Success:", transactionId)}
onError={(code, message) => console.error("Error:", code, message)}
onCancel={() => console.log("Cancelled")}
onReady={() => console.log("Ready")}
onGeofenceBlocked={(stateCode, reason) => console.log("Blocked:", stateCode)}
onKycSuccess={(identityUuid) => console.log("KYC passed:", identityUuid)}
onKycFailed={(reason) => console.log("KYC failed:", reason)}
onKycPending={() => console.log("KYC pending")}
onSessionExpired={async () => {
const fresh = await fetchToken();
return fresh;
}}
/>
);
}Props
| Prop | Type | Required | Description |
|---|---|---|---|
open | boolean | Yes | Controls whether the embed is visible. |
onOpenChange | (open: boolean) => void | Yes | Called when the open state should change (e.g. user closes the modal). |
src | string | Yes | Full URL of the embed page to load. |
token | string | Yes | Partner session JWT. |
title | string | No | Accessible title for the iframe. |
theme | EmbedTheme | No | Theme overrides. |
locale | string | No | BCP 47 locale tag (e.g. "en", "es"). Sent to the embed via PROPHETX_LOCALE. Defaults to "en". |
onSuccess | (transactionId: string, amount?: number) => void | No | Transaction completed. |
onError | (code: string, message: string) => void | No | An error occurred. |
onCancel | () => void | No | User closed the modal. |
onReady | () => void | No | Embed iframe loaded and ready. |
onGeofenceBlocked | (stateCode: string, reason: string) => void | No | Location not permitted. |
onKycSuccess | (identityUuid: string) => void | No | Identity verification passed. |
onKycFailed | (reason: string) => void | No | Identity verification failed. |
onKycPending | () => void | No | Identity verification pending. |
onSessionExpired | () => Promise<string | null> | No | Return a fresh JWT or null to abort. |
ProphetXEmbedHandle (ref)
Access the imperative handle via useRef<ProphetXEmbedHandle>:
| Method | Type | Description |
|---|---|---|
sendMessage | (message: { type: string; payload?: unknown }) => void | Send a raw postMessage to the iframe. |
reload | () => void | Reload the iframe. |
JavaScript SDK instance
The object returned by createProphetX().
| Method / Property | Type | Description |
|---|---|---|
openDeposit(opts) | (OpenOptions) => void | Open the deposit flow. |
openWithdraw(opts) | (OpenOptions) => void | Open the withdraw flow. |
openOneClickSignup(opts) | (OpenOneClickSignupOptions) => void | Open the 1-Click Signup flow (new users). opts is required — needs sessionKey/environment. |
openKyc(opts) / openIdUpload(opts) | (OpenIdUploadOptions) => void | Open the document verification flow (existing users). Same flow, two names. |
close() | () => void | Close any open flow. |
destroy() | () => void | Tear down the SDK — removes DOM elements, clears listeners, destroys auth manager. |
updateTheme(theme) | (EmbedTheme) => void | Update the theme on a currently open embed. |
on(event, handler) | See EventEmitter | Subscribe to an event. Returns an unsubscribe function. |
off(event, handler) | See EventEmitter | Unsubscribe from an event. |
auth | AuthManager | null | Auth manager instance. null if AuthConfig was not provided. |
wallet | WalletClient | null | Wallet client instance. null if auth was not configured. |
OpenOptions (JavaScript SDK)
| Option | Type | Description |
|---|---|---|
token | string | Session JWT. Required unless using the auth module. |
theme | EmbedTheme | Per-flow theme overrides. |
locale | string | BCP 47 locale tag (e.g. "en", "es"). Defaults to "en". |
onSuccess | (transactionId: string, amount?: number) => void | Transaction completed. |
onError | (code: string, message: string) => void | An error occurred. |
onCancel | () => void | User closed the modal. |
onReady | () => void | Embed loaded and ready. |
onGeofenceBlocked | (stateCode: string, reason: string) => void | Location not permitted. |
onSessionExpired | () => Promise<string | null> | Return a fresh JWT or null to abort. |
KycOpenOptions (JavaScript SDK)
| Option | Type | Description |
|---|---|---|
token | string | Session JWT. Required unless using the auth module. |
theme | EmbedTheme | Per-flow theme overrides. |
locale | string | BCP 47 locale tag (e.g. "en", "es"). Defaults to "en". |
onKycSuccess | (identityUuid: string) => void | Identity verification passed. |
onKycFailed | (reason: string) => void | Identity verification failed. |
onKycPending | () => void | Identity verification pending. |
onError | (code: string, message: string) => void | An error occurred. |
onCancel | () => void | User closed the modal. |
onReady | () => void | Embed loaded and ready. |
onGeofenceBlocked | (stateCode: string, reason: string) => void | Location not permitted. |
onSessionExpired | () => Promise<string | null> | Return a fresh JWT or null to abort. |
Events
The SDK has three event layers. Most integrations only use callback events (passed to open()). Use the EventEmitter for global analytics or logging. Use the postMessage protocol only if building a custom integration without the SDK.
Callback events
Passed as options to open() on each flow hook. See the individual hook sections above for the full list per flow.
Summary of all callback events across flows:
| Callback | Available on | Payload |
|---|---|---|
onSuccess | All flows | (transactionId: string, amount?: number) |
onError | All flows | (code: string, message: string) |
onCancel | All flows | — |
onReady | All flows | — |
onGeofenceBlocked | All flows | (stateCode: string, reason: string) |
onOneClickSuccess | useOneClickSignup | (identityUuid: string) |
onOneClickDeclined | useOneClickSignup | — |
onOneClickFailed | useOneClickSignup | (reason: string, retryable?: boolean) |
onKycSuccess | useKyc, useIdUpload | (identityUuid?: string) — always absent |
onKycFailed | useKyc, useIdUpload | (reason: string, retryable?: boolean) |
onKycPending | useKyc, useIdUpload | — |
EventEmitter
A typed pub/sub system available in all three SDKs. In React/React Native, use useEvents. In JavaScript, use sdk.on() / sdk.off().
| Event name | Payload type | Description |
|---|---|---|
ready | — | Embed iframe loaded and ready to interact. |
success | { transactionId: string; amount?: number } | Transaction completed successfully. |
error | { code: string; message: string } | An error occurred. |
cancel | — | User dismissed the modal. |
kycSuccess | { identityUuid: string } | Identity verification passed. |
kycFailed | { reason: string } | Identity verification failed. |
kycPending | — | Identity verification submitted, awaiting result. |
geofenceBlocked | { stateCode: string; reason: string } | User's location is outside a permitted jurisdiction. |
resize | { height: number } | Embed content height changed. Useful for inline (non-modal) embeds. |
sessionExpired | — | The session token has expired. |
sessionRefreshed | { token: string } | A new session token was obtained after expiry. |
open | { flow: string } | A flow modal was opened. flow is "deposit", "withdraw", "onboarding", or "kyc". |
close | { flow: string } | A flow modal was closed. |
EventEmitter API:
// Subscribe — returns an unsubscribe function
const unsub = sdk.on("success", ({ transactionId, amount }) => { ... });
// Unsubscribe by reference
sdk.off("success", handler);
// Unsubscribe via return value
unsub();postMessage protocol
Raw messages exchanged between the host page and the ProphetX iframe via window.postMessage. The SDK handles these automatically — use this reference only if you are building a custom integration without the SDK.
Outbound messages (iframe to host)
These messages are sent by the ProphetX embed to your page:
| Message type | Payload | Description |
|---|---|---|
PROPHETX_READY | — | Embed loaded and ready. |
PROPHETX_EMBED_LOADED | — | Iframe DOM content loaded. |
PROPHETX_SUCCESS | { transactionId: string; amount?: number } | Transaction completed. |
PROPHETX_ERROR | { code: string; message: string } | An error occurred. |
PROPHETX_CANCEL | — | User dismissed the flow. |
PROPHETX_RESIZE | { height: number } | Embed content height changed. |
PROPHETX_GEOFENCE_BLOCKED | { stateCode: string; reason: string } | User's location isn't eligible. Defined on every flow except 1-Click Signup; in practice this is enforced at token issuance, not per-request, so it rarely fires with a validly-issued embed token. |
PROPHETX_KYC_SUCCESS | { identityUuid?: string } | Document verification (useKyc/useIdUpload) resolved successfully. identityUuid is always absent — the IDPV API returns none. Final — no further async step. |
PROPHETX_KYC_FAILED | { reason: string; retryable?: boolean } | Document verification was rejected. Branch on retryable, not reason (log/route only). |
PROPHETX_KYC_PENDING | {} | Document submitted, review not yet resolved. |
PROPHETX_ONE_CLICK_SUCCESS | { identityUuid: string } | 1-Click Signup: user shared their identity. KYC has not run yet — redeem via POST /private/v1/users/one-click to start it. |
PROPHETX_ONE_CLICK_FAILED | { reason: string; retryable?: boolean } | 1-Click Signup: terminal failure. retryable is only ever true for a spent/lapsed session key. |
PROPHETX_ONE_CLICK_DECLINED | {} | 1-Click Signup: user chose not to share. Not an error. |
PROPHETX_SESSION_EXPIRED | — | Session token expired. |
Inbound messages (host to iframe)
Send these messages to the ProphetX iframe:
| Message type | Payload | Description |
|---|---|---|
PROPHETX_SESSION | { token: string } | Provide the session JWT when opening a flow. |
PROPHETX_SESSION_REFRESH | { token: string } | Provide a refreshed JWT after a PROPHETX_SESSION_EXPIRED event. |
PROPHETX_THEME | EmbedTheme | Update the embed's theme. |
PROPHETX_CLOSE | — | Close the embed. |
Example — listening without the SDK:
window.addEventListener("message", (event) => {
// Validate origin
if (event.origin !== "https://embed.prophetx.co") return;
const { type, payload } = event.data;
switch (type) {
case "PROPHETX_READY":
console.log("Embed ready");
break;
case "PROPHETX_SUCCESS":
console.log("Transaction:", payload.transactionId, payload.amount);
break;
case "PROPHETX_ERROR":
console.error("Error:", payload.code, payload.message);
break;
case "PROPHETX_CANCEL":
console.log("Cancelled");
break;
case "PROPHETX_SESSION_EXPIRED":
// Fetch a new token and send it back
fetchToken().then((token) => {
iframe.contentWindow.postMessage(
{ type: "PROPHETX_SESSION_REFRESH", payload: { token } },
"https://embed.prophetx.co"
);
});
break;
}
});EmbedTheme
Theme overrides applied to the embed UI. Pass via the theme prop on ProphetXProvider (React/React Native), as part of OpenOptions (JavaScript SDK), or dynamically via sdk.updateTheme().
type EmbedTheme = {
mode?: "light" | "dark";
primaryColor?: string;
colorOverrides?: Partial<ColorOverrides>;
spacingOverrides?: Partial<SpacingOverrides>;
radiusOverrides?: Partial<RadiusOverrides>;
fontSizeOverrides?: Partial<FontSizeOverrides>;
};Top-level fields
| Field | Type | Description |
|---|---|---|
mode | "light" | "dark" | Base color scheme. Defaults to "dark". |
primaryColor | string | Primary brand color. Applied to primary, primaryHover, cta, and ctaHover tokens. |
colorOverrides
Fine-grained color tokens. All fields are optional CSS color strings.
| Token | Description |
|---|---|
primary | Primary brand color |
primaryHover | Hover state for primary elements |
primaryForeground | Text/icon color on primary backgrounds |
secondary | Secondary color |
secondaryHover | Hover state for secondary elements |
background | Page background |
surface | Card/panel background |
surfaceElevated | Elevated surface (modals, dropdowns) |
text | Default text color |
textMuted | De-emphasized text |
textSubtle | Least prominent text (placeholders, hints) |
border | Default border color |
borderSubtle | Subtle border (dividers, separators) |
error | Error text/icon color |
errorBackground | Error background (alerts, badges) |
success | Success text/icon color |
successBackground | Success background |
warning | Warning text/icon color |
warningBackground | Warning background |
cta | Call-to-action button color |
ctaHover | CTA hover state |
ctaForeground | Text on CTA buttons |
filled | Filled/solid button color |
filledHover | Filled button hover state |
filledForeground | Text on filled buttons |
danger | Destructive action color |
dangerHover | Destructive action hover state |
dangerForeground | Text on destructive action buttons |
spacingOverrides
| Token | Description |
|---|---|
xs | Extra-small spacing |
sm | Small spacing |
md | Medium spacing |
lg | Large spacing |
xl | Extra-large spacing |
radiusOverrides
| Token | Description |
|---|---|
sm | Small border radius |
md | Medium border radius |
lg | Large border radius |
full | Fully rounded (pill shape) |
fontSizeOverrides
| Token | Description |
|---|---|
xs | Extra-small font size |
sm | Small font size |
md | Medium (base) font size |
lg | Large font size |
xl | Extra-large font size |
DevToolsLogEntry
Entries emitted by the devtools system. Receive them via DevToolsConfig.onEvent.
| Field | Type | Description |
|---|---|---|
timestamp | number | Unix timestamp (ms). |
category | "auth" | "message" | "api" | "lifecycle" | "event" | Log category. |
level | "error" | "warn" | "info" | "debug" | Severity level. |
message | string | Human-readable log message. |
data | Record<string, unknown> | undefined | Optional structured data. |
Type exports
All types are exported from the SDK package you're using. Import them alongside components and hooks:
Updated 15 days ago
