@snapkyc-ooru/consent-handoff-react 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +257 -103
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/http/errors.ts","../src/theme.ts","../src/http/normalizeStatus.ts","../src/demographicDisplay.ts","../src/react/SnapConsentHandoffFlow.tsx","../src/device/detectIntentPlatform.ts","../src/config.ts","../src/http/envelope.ts","../src/http/auth.ts","../src/http/client.ts","../src/http/endpoints.ts","../src/http/pollTxn.ts","../src/purposeSelection.ts","../src/uiHelpers.ts","../src/react/FlowErrorBoundary.tsx","../src/react/PoweredBySnapKyc.tsx","../src/react/TxnSuccessPanel.tsx","../src/react/openSnapConsentHandoffFlow.tsx"],"sourcesContent":["export class SnapSdkHttpError extends Error {\n readonly name = \"SnapSdkHttpError\";\n\n constructor(\n public readonly url: string,\n public readonly status: number,\n message: string,\n public readonly bodyText?: string,\n ) {\n super(message);\n }\n}\n\nexport class SnapSdkJsonError extends Error {\n readonly name = \"SnapSdkJsonError\";\n\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n }\n}\n","import type { CSSProperties } from \"react\";\n\n/**\n * Resolved visual tokens for the consent handoff UI.\n * Pass a partial object via `theme` on `SnapConsentHandoffFlow` to override defaults.\n */\nexport type SnapConsentHandoffTheme = {\n fontFamily: string;\n /** Primary brand color (buttons, selected states, accents). */\n primary: string;\n /** Text/icon color on top of primary (typically white). */\n onPrimary: string;\n /** Sheet / panel background (e.g. warm light gray). */\n canvas: string;\n /** Default “card” surface (e.g. unselected purpose rows). */\n surface: string;\n /** Muted surface (agreement notice, selected purpose row). */\n surfaceMuted: string;\n text: string;\n textMuted: string;\n border: string;\n /** Strong border for selected / emphasized controls. */\n borderActive: string;\n modalOverlay: string;\n danger: string;\n /** Corner radius for cards, rows, and buttons (e.g. `12px`). */\n radius: string;\n gap: string;\n maxWidth: string;\n modalZ: string;\n /** Success state (shield, status checkmarks). */\n success: string;\n /** Success screen status summary card background. */\n successStatusSurface: string;\n /** Success screen confirmed-purposes panel background. */\n successPurposesSurface: string;\n /** Accordion borders on the success demographic panel. */\n successAccordionBorder: string;\n};\n\nexport const DEFAULT_SNAP_CONSENT_THEME: SnapConsentHandoffTheme = {\n fontFamily: `system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif`,\n primary: \"#E87D43\",\n onPrimary: \"#ffffff\",\n canvas: \"#FAFAF9\",\n surface: \"#ffffff\",\n surfaceMuted: \"#FFF7ED\",\n text: \"#1c1917\",\n textMuted: \"#57534e\",\n border: \"#e7e5e4\",\n borderActive: \"#E87D43\",\n modalOverlay: \"rgba(28, 25, 23, 0.55)\",\n danger: \"#b91c1c\",\n radius: \"12px\",\n gap: \"12px\",\n maxWidth: \"720px\",\n modalZ: \"10000\",\n success: \"#16a34a\",\n successStatusSurface: \"#fff5f0\",\n successPurposesSurface: \"#f0f2ff\",\n successAccordionBorder: \"#e0d7d0\",\n};\n\nexport function resolveSnapConsentTheme(partial?: Partial<SnapConsentHandoffTheme>): SnapConsentHandoffTheme {\n const merged = { ...DEFAULT_SNAP_CONSENT_THEME, ...partial };\n if (partial?.primary !== undefined && partial.borderActive === undefined) {\n merged.borderActive = partial.primary;\n }\n return merged;\n}\n\n/**\n * Maps resolved theme tokens to CSS custom properties on `.snap-consent-handoff`.\n */\nexport function themeToCssProperties(theme: SnapConsentHandoffTheme): CSSProperties {\n return {\n \"--snap-consent-font-family\": theme.fontFamily,\n \"--snap-consent-text\": theme.text,\n \"--snap-consent-muted\": theme.textMuted,\n \"--snap-consent-bg\": theme.canvas,\n \"--snap-consent-surface\": theme.surface,\n \"--snap-consent-surface-muted\": theme.surfaceMuted,\n \"--snap-consent-border\": theme.border,\n \"--snap-consent-border-active\": theme.borderActive,\n \"--snap-consent-overlay\": theme.modalOverlay,\n \"--snap-consent-accent\": theme.primary,\n \"--snap-consent-on-primary\": theme.onPrimary,\n \"--snap-consent-danger\": theme.danger,\n \"--snap-consent-radius\": theme.radius,\n \"--snap-consent-gap\": theme.gap,\n \"--snap-consent-max-width\": theme.maxWidth,\n \"--snap-consent-modal-z\": theme.modalZ,\n \"--snap-consent-success\": theme.success,\n \"--snap-consent-success-status-bg\": theme.successStatusSurface,\n \"--snap-consent-success-purposes-bg\": theme.successPurposesSurface,\n \"--snap-consent-success-accordion-border\": theme.successAccordionBorder,\n } as CSSProperties;\n}\n","import type { DemographicData, TxnStatusEvidence, TxnStatusResponse } from \"./types\";\n\nfunction parseJsonObject(raw: unknown): Record<string, unknown> | null {\n if (raw == null) return null;\n if (typeof raw === \"string\") {\n const trimmed = raw.trim();\n if (!trimmed) return null;\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n return parseJsonObject(parsed);\n } catch {\n return null;\n }\n }\n if (Array.isArray(raw) || typeof raw !== \"object\") return null;\n return raw as Record<string, unknown>;\n}\n\nexport function parseDemographicPayload(raw: unknown): DemographicData | null {\n const obj = parseJsonObject(raw);\n if (!obj) return null;\n return obj as DemographicData;\n}\n\nfunction parseEvidencePayload(raw: unknown): TxnStatusEvidence | undefined {\n const obj = parseJsonObject(raw);\n if (!obj) return undefined;\n\n const demographic =\n parseDemographicPayload(obj.demographic_data) ??\n parseDemographicPayload(obj.demographicData);\n\n return {\n ...obj,\n aadhaar_uuid: typeof obj.aadhaar_uuid === \"string\" ? obj.aadhaar_uuid : undefined,\n sd_jwt: typeof obj.sd_jwt === \"string\" ? obj.sd_jwt : undefined,\n disclosures: Array.isArray(obj.disclosures) ? obj.disclosures : undefined,\n demographic_data: demographic ?? undefined,\n };\n}\n\nfunction parsePurposes(raw: unknown): { id: string; name: string }[] {\n if (!Array.isArray(raw)) return [];\n return raw\n .map((item) => {\n if (!item || typeof item !== \"object\") return null;\n const row = item as Record<string, unknown>;\n const id = typeof row.id === \"string\" ? row.id : \"\";\n const name = typeof row.name === \"string\" ? row.name : \"\";\n if (!id && !name) return null;\n return { id: id || name, name: name || id };\n })\n .filter((row): row is { id: string; name: string } => row != null);\n}\n\n/**\n * Normalizes status payloads from GET …/transactions/{id}/status into a stable shape\n * for UI + onSuccess, even if the host accidentally passes the full API envelope.\n */\nexport function normalizeTxnStatusPayload(input: unknown): TxnStatusResponse {\n const root = parseJsonObject(input);\n if (!root) {\n return { txn_id: \"\", status: \"UNKNOWN\" };\n }\n\n // Full API envelope: { data: { txn_id, status, evidence, ... } }\n if (\n root.data &&\n typeof root.data === \"object\" &&\n !Array.isArray(root.data) &&\n (\"txn_id\" in (root.data as object) || \"status\" in (root.data as object))\n ) {\n return normalizeTxnStatusPayload(root.data);\n }\n\n const txn_id =\n typeof root.txn_id === \"string\"\n ? root.txn_id\n : typeof root.txnId === \"string\"\n ? root.txnId\n : \"\";\n\n const status = typeof root.status === \"string\" ? root.status : String(root.status ?? \"UNKNOWN\");\n\n const created_at = typeof root.created_at === \"string\" ? root.created_at : undefined;\n\n const purposes = parsePurposes(root.purposes);\n\n let evidence = parseEvidencePayload(root.evidence);\n\n const flatDemo =\n parseDemographicPayload(root.demographic_data) ?? parseDemographicPayload(root.demographicData);\n\n if (flatDemo) {\n evidence = { ...(evidence ?? {}), demographic_data: flatDemo };\n }\n\n return {\n ...root,\n txn_id,\n status,\n created_at,\n purposes,\n evidence,\n };\n}\n","import { parseDemographicPayload } from \"./http/normalizeStatus\";\nimport type { DemographicData, TxnStatusResponse } from \"./http/types\";\n\nexport type DemographicField = {\n /** Original API field name (snake_case). */\n key: string;\n label: string;\n value: string;\n};\n\nexport type DemographicAccordionSection = {\n id: string;\n title: string;\n fields: DemographicField[];\n /** When true, render resident photo in this section (Personal Details only). */\n includePhoto: boolean;\n};\n\nconst SKIP_DEMOGRAPHIC_KEYS = new Set([\"resident_image\"]);\n\nconst PERSONAL_DETAIL_KEYS = new Set([\n \"resident_name\",\n \"resident_name_local_language\",\n \"date_of_birth\",\n \"gender\",\n \"care_of\",\n \"care_of_local_language\",\n \"is_age_above_18\",\n \"is_age_above_50\",\n \"is_age_above_60\",\n \"is_age_above_75\",\n \"is_non_resident_indian\",\n]);\n\nconst CONTACT_DETAIL_KEYS = new Set([\n \"mobile_number\",\n \"masked_mobile_number\",\n \"email_address\",\n \"masked_email_address\",\n]);\n\nconst ADDRESS_DETAIL_KEYS = new Set([\n \"full_address\",\n \"regional_address\",\n \"building\",\n \"street\",\n \"locality\",\n \"landmark\",\n \"village_town_city\",\n \"sub_district\",\n \"district\",\n \"state\",\n \"postal_code\",\n \"post_office_name\",\n]);\n\nconst GROUPED_DETAIL_KEYS = new Set<string>([\n ...PERSONAL_DETAIL_KEYS,\n ...CONTACT_DETAIL_KEYS,\n ...ADDRESS_DETAIL_KEYS,\n]);\n\n/** Skip inline photos above ~110KB decoded to avoid freezing the modal. */\nconst MAX_RESIDENT_IMAGE_B64_CHARS = 150_000;\n\n/** Preferred display order; any other keys from the API are appended alphabetically. */\nconst DEMOGRAPHIC_KEY_ORDER: string[] = [\n \"resident_name\",\n \"resident_name_local_language\",\n \"date_of_birth\",\n \"gender\",\n \"care_of\",\n \"care_of_local_language\",\n \"mobile_number\",\n \"masked_mobile_number\",\n \"email_address\",\n \"masked_email_address\",\n \"full_address\",\n \"regional_address\",\n \"building\",\n \"street\",\n \"locality\",\n \"landmark\",\n \"village_town_city\",\n \"sub_district\",\n \"district\",\n \"state\",\n \"postal_code\",\n \"post_office_name\",\n \"enrolment_date\",\n \"enrolment_number\",\n \"credential_issuing_date\",\n \"is_age_above_18\",\n \"is_age_above_50\",\n \"is_age_above_60\",\n \"is_age_above_75\",\n \"is_non_resident_indian\",\n];\n\nexport function extractDemographicData(status: TxnStatusResponse | null | undefined): DemographicData | null {\n if (!status || typeof status !== \"object\") return null;\n\n const fromEvidence = parseDemographicPayload(status.evidence?.demographic_data);\n if (fromEvidence) return fromEvidence;\n\n return parseDemographicPayload(status.demographic_data);\n}\n\nexport function hasDisplayableDemographics(status: TxnStatusResponse | null | undefined): boolean {\n const data = extractDemographicData(status);\n if (!data) return false;\n if (demographicFieldsForDisplay(data).length > 0) return true;\n const raw = data.resident_image;\n if (typeof raw !== \"string\" || !raw.trim()) return false;\n return raw.trim().length <= MAX_RESIDENT_IMAGE_B64_CHARS;\n}\n\nexport function formatDisplayValue(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (typeof value === \"string\") return value.trim() === \"\" ? \"null\" : value;\n if (typeof value === \"object\") return \"null\";\n return String(value);\n}\n\nexport function humanizeDemographicKey(key: string): string {\n return key\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (ch) => ch.toUpperCase());\n}\n\nfunction orderedDemographicKeys(data: DemographicData): string[] {\n const keys = Object.keys(data).filter((k) => !SKIP_DEMOGRAPHIC_KEYS.has(k));\n const rank = new Map(DEMOGRAPHIC_KEY_ORDER.map((k, i) => [k, i]));\n\n return keys.sort((a, b) => {\n const ra = rank.get(a) ?? Number.MAX_SAFE_INTEGER;\n const rb = rank.get(b) ?? Number.MAX_SAFE_INTEGER;\n if (ra !== rb) return ra - rb;\n return a.localeCompare(b);\n });\n}\n\n/** All demographic_data fields; empty / object values render as `null`. */\nexport function demographicFieldsForDisplay(data: DemographicData): DemographicField[] {\n return orderedDemographicKeys(data).map((key) => ({\n key,\n label: humanizeDemographicKey(key),\n value: formatDisplayValue(data[key]),\n }));\n}\n\n/**\n * Groups demographic fields into accordion sections (Personal, Contact, Address, Additional).\n * Personal Details may include a photo slot when `includePhoto` is true.\n */\nexport function demographicAccordionSections(\n data: DemographicData,\n options: { includePhoto: boolean },\n): DemographicAccordionSection[] {\n const all = demographicFieldsForDisplay(data);\n const byKey = (keys: Set<string>) => all.filter((f) => keys.has(f.key));\n const personalFields = byKey(PERSONAL_DETAIL_KEYS);\n const contactFields = byKey(CONTACT_DETAIL_KEYS);\n const addressFields = byKey(ADDRESS_DETAIL_KEYS);\n const additionalFields = all.filter((f) => !GROUPED_DETAIL_KEYS.has(f.key));\n\n const sections: DemographicAccordionSection[] = [];\n\n if (personalFields.length > 0 || options.includePhoto) {\n sections.push({\n id: \"personal\",\n title: \"Personal Details\",\n fields: personalFields,\n includePhoto: options.includePhoto,\n });\n }\n\n if (contactFields.length > 0) {\n sections.push({\n id: \"contact\",\n title: \"Contact Information\",\n fields: contactFields,\n includePhoto: false,\n });\n }\n\n if (addressFields.length > 0) {\n sections.push({\n id: \"address\",\n title: \"Address Details\",\n fields: addressFields,\n includePhoto: false,\n });\n }\n\n if (additionalFields.length > 0) {\n sections.push({\n id: \"additional\",\n title: \"Additional details\",\n fields: additionalFields,\n includePhoto: false,\n });\n }\n\n return sections;\n}\n\nexport function residentImageDataUrl(data: DemographicData): string | null {\n const raw = data.resident_image;\n if (typeof raw !== \"string\" || !raw.trim()) return null;\n const b64 = raw.trim();\n if (b64.length > MAX_RESIDENT_IMAGE_B64_CHARS) return null;\n if (b64.startsWith(\"data:\")) return b64;\n return `data:image/jpeg;base64,${b64}`;\n}\n\nexport function formatPurposeLabel(name: unknown): string {\n if (typeof name !== \"string\" || !name.trim()) return \"Purpose\";\n return name\n .split(\"_\")\n .map((part) => part.charAt(0) + part.slice(1).toLowerCase())\n .join(\" \");\n}\n","/* eslint-disable @typescript-eslint/no-floating-promises */\nimport DOMPurify from \"dompurify\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport type { IntentOs } from \"../device/detectIntentPlatform\";\nimport { detectIntentPlatform } from \"../device/detectIntentPlatform\";\nimport type { CompletionResult, FlowEvent, SnapConsentHandoffPublicProps } from \"../flowTypes\";\nimport { createIntent, generateQr, getAgreement, initiateTxn } from \"../http/endpoints\";\nimport type { AgreementEnvelope } from \"../http/types\";\nimport { normalizeTxnStatusPayload } from \"../http/normalizeStatus\";\nimport type { TxnStatusResponse } from \"../http/types\";\nimport { pollTxnUntilTerminal } from \"../http/pollTxn\";\nimport { buildSelectablePurposes } from \"../purposeSelection\";\nimport { resolveSnapConsentTheme, themeToCssProperties } from \"../theme\";\nimport { agreementTextHtml, coerceForcedIntentOs } from \"../uiHelpers\";\nimport { FlowErrorBoundary } from \"./FlowErrorBoundary\";\nimport { PoweredBySnapKyc } from \"./PoweredBySnapKyc\";\nimport { TxnSuccessPanel } from \"./TxnSuccessPanel\";\n\nconst defaultQrSize = 376;\n\nfunction emitEvt(onFlowEvent: SnapConsentHandoffPublicProps[\"onFlowEvent\"], evt: FlowEvent) {\n try {\n onFlowEvent?.(evt);\n // eslint-disable-next-line no-empty\n } catch {\n //\n }\n}\n\nexport function SnapConsentHandoffFlow(props: SnapConsentHandoffPublicProps) {\n const {\n integrationToken,\n rpContext,\n agreementId: _agreementIdProp,\n acceptLanguage,\n handoffMode,\n qrRequestBody,\n pollIntervalMs = 1500,\n pollDeadlineMs = 120_000,\n onFlowEvent,\n onSuccess,\n onError,\n onRequestClose,\n displayMode = \"modal\",\n title,\n userAgent,\n theme: themePartial,\n } = props;\n\n const themeCss = useMemo(() => themeToCssProperties(resolveSnapConsentTheme(themePartial)), [themePartial]);\n\n const forcedOs = coerceForcedIntentOs(props);\n\n const flowAbortRef = useRef<AbortController>(new AbortController());\n useEffect(() => {\n flowAbortRef.current.abort();\n flowAbortRef.current = new AbortController();\n\n return () => {\n flowAbortRef.current.abort();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- host remount rotates controller on auth changes\n }, [integrationToken, handoffMode]);\n\n const qrObjectUrlRef = useRef<string | null>(null);\n const sheetRef = useRef<HTMLDivElement>(null);\n\n /** Revoke object URLs on exit */\n useEffect(() => {\n return () => {\n if (qrObjectUrlRef.current) URL.revokeObjectURL(qrObjectUrlRef.current);\n qrObjectUrlRef.current = null;\n };\n }, []);\n\n const signal = (): AbortSignal => flowAbortRef.current.signal;\n\n const [fatalError, setFatalError] = useState<string | null>(null);\n const [agreementEnvelope, setAgreementEnvelope] = useState<AgreementEnvelope | null>(null);\n const [loadingAgreement, setLoadingAgreement] = useState(true);\n const [busyConsent, setBusyConsent] = useState(false);\n\n const [txnIdDisplay, setTxnIdDisplay] = useState<string | null>(null);\n const [intentUrl, setIntentUrl] = useState<string | null>(null);\n\n /** When intent flow cannot infer OS */\n const [intentNeedsPick, setIntentNeedsPick] = useState(false);\n\n const [qrObjectUrl, setQrObjectUrl] = useState<string | null>(null);\n\n /** status lines */\n const [busyPolling, setBusyPolling] = useState(false);\n\n const [completed, setCompleted] = useState<CompletionResult | null>(null);\n\n /** When host omits `onRequestClose`, hide the UI after user dismisses (Done / Cancel / close). */\n const [flowDismissed, setFlowDismissed] = useState(false);\n\n useEffect(() => {\n setFlowDismissed(false);\n }, [integrationToken, handoffMode]);\n\n const selectable = useMemo(() => {\n if (!agreementEnvelope) return [];\n return buildSelectablePurposes(agreementEnvelope.data);\n }, [agreementEnvelope]);\n\n const [selectedPurposesMap, setSelectedPurposesMap] = useState<Record<string, boolean>>({});\n\n useEffect(() => {\n setSelectedPurposesMap((prev) => {\n const next: Record<string, boolean> = {};\n for (const row of selectable) {\n next[row.id] = prev[row.id] ?? false;\n }\n return next;\n });\n }, [selectable]);\n\n const hydrateAgreementHtml = useCallback(\n (data: AgreementEnvelope[\"data\"]) => {\n const html = agreementTextHtml(data, acceptLanguage);\n if (!html) return null;\n return DOMPurify.sanitize(html, { ALLOWED_TAGS: [\"br\"], ALLOWED_ATTR: [] });\n },\n [acceptLanguage],\n );\n\n const agreementHtml = useMemo(() => {\n if (!agreementEnvelope) return null;\n return hydrateAgreementHtml(agreementEnvelope.data);\n }, [agreementEnvelope, hydrateAgreementHtml]);\n\n const revokeQrIfAny = () => {\n if (qrObjectUrlRef.current) URL.revokeObjectURL(qrObjectUrlRef.current);\n qrObjectUrlRef.current = null;\n setQrObjectUrl(null);\n };\n\n const finishWithSuccess = useCallback(\n (raw: TxnStatusResponse, txnIdHint?: string) => {\n const normalized = normalizeTxnStatusPayload(raw);\n\n revokeQrIfAny();\n setIntentUrl(null);\n setIntentNeedsPick(false);\n setTxnIdDisplay(null);\n setBusyPolling(false);\n setBusyConsent(false);\n\n const completion: CompletionResult = {\n txn_id: normalized.txn_id || txnIdHint,\n status: normalized.status,\n raw: normalized,\n };\n\n setCompleted(completion);\n emitEvt(onFlowEvent, { phase: \"completed\", txnId: completion.txn_id });\n\n // Let the success UI paint before host onSuccess handlers (often dispose the modal).\n queueMicrotask(() => {\n onSuccess?.(completion);\n });\n },\n [onFlowEvent, onSuccess],\n );\n\n useEffect(() => {\n if (!completed) return;\n sheetRef.current?.scrollTo({ top: 0, behavior: \"smooth\" });\n }, [completed]);\n\n /** Initial agreement bootstrap */\n useEffect(() => {\n emitEvt(onFlowEvent, { phase: \"agreement-loading\" });\n let cancelled = false;\n\n async function bootstrap() {\n try {\n setLoadingAgreement(true);\n setFatalError(null);\n const env = await getAgreement({\n integrationToken,\n signal: signal(),\n acceptLanguage,\n });\n if (cancelled) return;\n if (env.error) throw new Error(env.error_message ?? env.message ?? \"Agreement fetch error\");\n setAgreementEnvelope(env);\n emitEvt(onFlowEvent, { phase: \"agreement-ready\" });\n } catch (e: unknown) {\n if ((e as DOMException)?.name === \"AbortError\") return;\n const msg = e instanceof Error ? e.message : String(e);\n setFatalError(msg);\n emitEvt(onFlowEvent, { phase: \"failed\", error: e });\n onError?.(e);\n } finally {\n if (!cancelled) setLoadingAgreement(false);\n }\n }\n\n void bootstrap();\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [integrationToken, acceptLanguage]);\n\n async function finalizeIntentAndPoll(currentTxnId: string, platform: IntentOs): Promise<void> {\n revokeQrIfAny();\n emitEvt(onFlowEvent, {\n phase: \"handoff-loading\",\n txnId: currentTxnId,\n meta: { kind: \"ambiguous-choice\", chosen: platform },\n });\n try {\n setIntentNeedsPick(false);\n setFatalError(null);\n\n const res = await createIntent({\n integrationToken,\n txnId: currentTxnId,\n platform,\n signal: signal(),\n });\n\n setIntentUrl(res.intent_url);\n\n emitEvt(onFlowEvent, {\n phase: \"handoff-ready\",\n txnId: currentTxnId,\n meta: { kind: \"ambiguous-choice\", chosen: platform },\n });\n\n emitEvt(onFlowEvent, { phase: \"polling\", txnId: currentTxnId });\n setBusyPolling(true);\n const raw = await pollTxnUntilTerminal({\n integrationToken,\n txnId: currentTxnId,\n signal: signal(),\n pollIntervalMs,\n deadlineMs: pollDeadlineMs,\n });\n finishWithSuccess(raw, currentTxnId);\n } catch (e: unknown) {\n setBusyPolling(false);\n if ((e as DOMException)?.name === \"AbortError\") return;\n const msg = e instanceof Error ? e.message : String(e);\n setFatalError(msg);\n emitEvt(onFlowEvent, { phase: \"failed\", txnId: currentTxnId, error: e });\n onError?.(e);\n }\n }\n\n async function runQrHandoff(currentTxnId: string): Promise<void> {\n emitEvt(onFlowEvent, { phase: \"handoff-loading\", txnId: currentTxnId });\n revokeQrIfAny();\n const blob = await generateQr({\n integrationToken,\n txnId: currentTxnId,\n size: qrRequestBody?.size ?? defaultQrSize,\n signal: signal(),\n });\n const url = URL.createObjectURL(blob);\n qrObjectUrlRef.current = url;\n setQrObjectUrl(url);\n emitEvt(onFlowEvent, { phase: \"handoff-ready\", txnId: currentTxnId });\n }\n\n async function runIntentHandoff(currentTxnId: string, platform: IntentOs): Promise<void> {\n emitEvt(onFlowEvent, {\n phase: \"handoff-loading\",\n txnId: currentTxnId,\n meta: forcedOs ? { kind: \"forced\", platform } : { kind: \"resolved\", platform },\n });\n\n const res = await createIntent({\n integrationToken,\n txnId: currentTxnId,\n platform,\n signal: signal(),\n });\n\n setIntentUrl(res.intent_url);\n\n emitEvt(onFlowEvent, {\n phase: \"handoff-ready\",\n txnId: currentTxnId,\n meta: forcedOs ? { kind: \"forced\", platform } : { kind: \"resolved\", platform },\n });\n }\n\n /** Primary consent acknowledgement */\n const handleContinueConsent = async () => {\n if (!agreementEnvelope) return;\n\n emitEvt(onFlowEvent, { phase: \"txn-initiating\" });\n revokeQrIfAny();\n setIntentUrl(null);\n setIntentNeedsPick(false);\n setCompleted(null);\n\n try {\n setBusyConsent(true);\n setFatalError(null);\n\n const purposeIds = selectable.filter((item) => selectedPurposesMap[item.id]).map((item) => item.id);\n\n if (!purposeIds.length) throw new Error(\"Please select at least one purpose.\");\n\n const txn = await initiateTxn({\n integrationToken,\n body: {\n purpose_ids: purposeIds,\n rp_context: {\n ref_id: rpContext.reference_id,\n },\n },\n signal: signal(),\n });\n\n setTxnIdDisplay(txn.txn_id);\n emitEvt(onFlowEvent, { phase: \"txn-created\", txnId: txn.txn_id });\n\n if (handoffMode === \"qr\") {\n await runQrHandoff(txn.txn_id);\n emitEvt(onFlowEvent, { phase: \"polling\", txnId: txn.txn_id });\n setBusyPolling(true);\n try {\n const raw = await pollTxnUntilTerminal({\n integrationToken,\n txnId: txn.txn_id,\n signal: signal(),\n pollIntervalMs,\n deadlineMs: pollDeadlineMs,\n });\n finishWithSuccess(raw, txn.txn_id);\n } catch (pollErr: unknown) {\n setBusyPolling(false);\n throw pollErr;\n }\n } else {\n if (forcedOs) {\n setIntentNeedsPick(false);\n await runIntentHandoff(txn.txn_id, forcedOs);\n\n emitEvt(onFlowEvent, { phase: \"polling\", txnId: txn.txn_id });\n setBusyPolling(true);\n try {\n const raw = await pollTxnUntilTerminal({\n integrationToken,\n txnId: txn.txn_id,\n signal: signal(),\n pollIntervalMs,\n deadlineMs: pollDeadlineMs,\n });\n finishWithSuccess(raw, txn.txn_id);\n } catch (pollErr: unknown) {\n setBusyPolling(false);\n throw pollErr;\n }\n } else {\n const inferred = detectIntentPlatform(userAgent);\n if (inferred.kind === \"resolved\") {\n setIntentNeedsPick(false);\n\n emitEvt(onFlowEvent, {\n phase: \"txn-created\",\n txnId: txn.txn_id,\n meta: { kind: \"resolved\", platform: inferred.platform },\n });\n\n await runIntentHandoff(txn.txn_id, inferred.platform);\n\n emitEvt(onFlowEvent, { phase: \"polling\", txnId: txn.txn_id });\n setBusyPolling(true);\n try {\n const raw = await pollTxnUntilTerminal({\n integrationToken,\n txnId: txn.txn_id,\n signal: signal(),\n pollIntervalMs,\n deadlineMs: pollDeadlineMs,\n });\n finishWithSuccess(raw, txn.txn_id);\n } catch (pollErr: unknown) {\n setBusyPolling(false);\n throw pollErr;\n }\n } else {\n emitEvt(onFlowEvent, {\n phase: \"txn-created\",\n txnId: txn.txn_id,\n meta: { kind: \"ambiguous-choice\" },\n });\n setIntentNeedsPick(true);\n }\n }\n }\n\n setBusyConsent(false);\n } catch (e: unknown) {\n setBusyConsent(false);\n setBusyPolling(false);\n if ((e as DOMException)?.name === \"AbortError\") return;\n const msg = e instanceof Error ? e.message : String(e);\n setFatalError(msg);\n emitEvt(onFlowEvent, { phase: \"failed\", error: e });\n onError?.(e);\n }\n };\n\n const handlePickIntent = (os: IntentOs) => async () => {\n if (!txnIdDisplay) return;\n await finalizeIntentAndPoll(txnIdDisplay, os);\n };\n\n /** Copy deeplink clipboard */\n const handleCopyIntent = async () => {\n try {\n if (!intentUrl) return;\n await navigator.clipboard.writeText(intentUrl);\n // eslint-disable-next-line no-empty\n } catch {\n //\n }\n };\n\n /** Close / Cancel / Done — aborts in-flight work and notifies host. */\n const handleClosePressed = () => {\n emitEvt(onFlowEvent, { phase: \"cancelled\" });\n flowAbortRef.current.abort();\n const close = onRequestClose;\n queueMicrotask(() => {\n close?.();\n if (close === undefined) {\n setFlowDismissed(true);\n }\n });\n };\n\n /** Render */\n const shellClass = displayMode === \"modal\" ? \"snap-consent-handoff_overlay\" : \"snap-consent-handoff_inline\";\n const headingFallback = agreementEnvelope?.data.name ?? \"Consent\";\n\n if (flowDismissed) {\n return null;\n }\n\n return (\n <div className=\"snap-consent-handoff\" style={themeCss}>\n <div className={shellClass} data-testid=\"snap-consent-handoff-shell\">\n <div className=\"snap-consent-handoff_body\">\n <div\n ref={sheetRef}\n className=\"snap-consent-handoff_sheet\"\n role=\"dialog\"\n aria-modal={displayMode === \"modal\"}\n >\n <header className=\"snap-consent-handoff_hdr\">\n <h2 className=\"snap-consent-handoff_title\">{title ?? headingFallback}</h2>\n {displayMode === \"modal\" ? (\n <button\n type=\"button\"\n className=\"snap-consent-handoff_btnIcon\"\n aria-label=\"Close\"\n data-testid=\"snap-consent-handoff-close\"\n onClick={handleClosePressed}\n >\n ×\n </button>\n ) : null}\n </header>\n\n {completed ? (\n <div className=\"snap-consent-handoff_done\" data-testid=\"snap-consent-handoff-done\">\n <FlowErrorBoundary>\n <TxnSuccessPanel status={normalizeTxnStatusPayload(completed.raw)} />\n </FlowErrorBoundary>\n\n <div className=\"snap-consent-handoff_actions\">\n <button\n type=\"button\"\n className=\"snap-consent-handoff_btnPrimary\"\n data-testid=\"snap-consent-handoff-done-button\"\n onClick={handleClosePressed}\n >\n Done\n </button>\n </div>\n </div>\n ) : null}\n\n {!completed && fatalError ? <div className=\"snap-consent-handoff_err\">{fatalError}</div> : null}\n\n {!completed && loadingAgreement ? <div aria-busy>Loading agreement…</div> : null}\n\n {!completed && agreementEnvelope ? (\n <div aria-live=\"polite\">\n {agreementHtml ? (\n // eslint-disable-next-line react/no-danger -- sanitized via DOMPurify\n <article className=\"snap-consent-handoff_notice\" dangerouslySetInnerHTML={{ __html: agreementHtml }} />\n ) : null}\n\n {!txnIdDisplay ? (\n <section>\n <h3 className=\"snap-consent-handoff_headingSm\">Consent Required</h3>\n <div className=\"snap-consent-handoff_list\">\n {selectable.map((row) => {\n const rowDisabled = busyConsent || busyPolling || loadingAgreement;\n return (\n <label\n key={row.id}\n className={\n [\n \"snap-consent-handoff_row\",\n selectedPurposesMap[row.id] ? \"snap-consent-handoff_row--selected\" : \"\",\n rowDisabled ? \"snap-consent-handoff_row--disabled\" : \"\",\n ]\n .filter(Boolean)\n .join(\" \")\n }\n htmlFor={`purpose-${row.id}`}\n >\n <input\n id={`purpose-${row.id}`}\n type=\"checkbox\"\n checked={Boolean(selectedPurposesMap[row.id])}\n disabled={busyConsent || busyPolling || loadingAgreement}\n onChange={(e) =>\n setSelectedPurposesMap((prev) => ({\n ...prev,\n [row.id]: e.target.checked,\n }))\n }\n />\n <div style={{ fontWeight: 600 }}>{row.label}</div>\n </label>\n );\n })}\n </div>\n\n <div className=\"snap-consent-handoff_actions snap-consent-handoff_actions--split\">\n <button\n type=\"button\"\n className=\"snap-consent-handoff_btnSecondary\"\n data-testid=\"snap-consent-handoff-cancel\"\n disabled={busyConsent || busyPolling || loadingAgreement}\n onClick={handleClosePressed}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"snap-consent-handoff_btnPrimary\"\n data-testid=\"snap-consent-handoff-submit\"\n disabled={busyConsent || busyPolling || loadingAgreement}\n onClick={() => void handleContinueConsent()}\n >\n I Agree\n </button>\n </div>\n </section>\n ) : null}\n\n {txnIdDisplay ? (\n <section style={{ marginTop: \"14px\" }} data-testid=\"snap-consent-handoff-active-txn\">\n {handoffMode === \"intent\" ? (\n <>\n {intentNeedsPick ? (\n <div className=\"snap-consent-handoff_intents\" role=\"group\" aria-label=\"Choose OS\">\n <p className=\"snap-consent-handoff_muted\">\n Automatic platform detection couldn’t confidently choose Android vs iOS. Pick yours:\n </p>\n <button\n type=\"button\"\n className=\"snap-consent-handoff_btnPrimary\"\n onClick={() => void handlePickIntent(\"android\")()}\n disabled={busyConsent || busyPolling}\n >\n Continue with Android\n </button>\n <button\n type=\"button\"\n className=\"snap-consent-handoff_btnPrimary\"\n onClick={() => void handlePickIntent(\"ios\")()}\n disabled={busyConsent || busyPolling}\n >\n Continue with iPhone / iPad\n </button>\n </div>\n ) : intentUrl ? (\n <div>\n <textarea readOnly value={intentUrl} className=\"snap-consent-handoff_codeBox\" />\n <div className=\"snap-consent-handoff_actions\">\n <button type=\"button\" className=\"snap-consent-handoff_btnSecondary\" onClick={() => void handleCopyIntent()}>\n Copy deeplink\n </button>\n {/* eslint-disable-next-line react/jsx-no-target-blank -- external deeplink */}\n <a className=\"snap-consent-handoff_btnSecondary\" href={intentUrl} style={{ textDecoration: \"none\" }}>\n Open app\n </a>\n </div>\n <p className=\"snap-consent-handoff_muted\" style={{ fontSize: \"12px\" }}>\n Some in-app browsers block custom-url schemes — use Safari/Chrome where possible.\n </p>\n\n {(busyConsent || busyPolling) && intentUrl ? (\n <div className=\"snap-consent-handoff_notice\" aria-live=\"polite\">\n {busyPolling ? \"Polling transaction status...\" : \"\"}\n </div>\n ) : null}\n </div>\n ) : busyConsent ? (\n <div>Preparing app link...</div>\n ) : busyPolling ? (\n <div>Waiting on device handshake...</div>\n ) : null}\n </>\n ) : null}\n\n {handoffMode === \"qr\" ? (\n qrObjectUrl ? (\n <figure className=\"snap-consent-handoff_qr\" data-testid=\"snap-consent-handoff-qr\">\n <img alt=\"QR code\" src={qrObjectUrl} />\n <figcaption className=\"snap-consent-handoff_muted\">\n Scan with your authorised app to proceed.{busyPolling ? \" Listening for confirmation...\" : null}\n </figcaption>\n </figure>\n ) : busyConsent ? (\n <div>Generating QR...</div>\n ) : busyPolling ? (\n <div>Waiting for scanned confirmation...</div>\n ) : null\n ) : null}\n </section>\n ) : null}\n </div>\n ) : null}\n </div>\n <PoweredBySnapKyc />\n </div>\n </div>\n </div>\n );\n}\n","export type IntentOs = \"android\" | \"ios\";\n\nexport type IntentDetection =\n | { kind: \"resolved\"; platform: IntentOs }\n | { kind: \"ambiguous\"; reason?: string };\n\n/**\n * Lightweight UA heuristic for requesting android vs ios deeplinks from the backend.\n */\nexport function detectIntentPlatform(userAgent?: string): IntentDetection {\n const uaRaw = userAgent ?? (typeof navigator !== \"undefined\" ? navigator.userAgent : \"\");\n const ua = uaRaw.toLowerCase();\n\n if (!ua) return { kind: \"ambiguous\", reason: \"missing-user-agent\" };\n\n const isAndroid = /android/.test(ua);\n const touchPoints =\n typeof navigator !== \"undefined\" ? Number(navigator.maxTouchPoints ?? 0) : 0;\n const isIOSDevice = /iphone|ipad|ipod/.test(ua) || (ua.includes(\"macintosh\") && touchPoints > 1);\n\n if (isAndroid && !isIOSDevice) return { kind: \"resolved\", platform: \"android\" };\n if (!isAndroid && isIOSDevice) return { kind: \"resolved\", platform: \"ios\" };\n\n return { kind: \"ambiguous\", reason: \"ambiguous-or-non-mobile\" };\n}\n","/**\n * API origin bundled with the SDK. Replace at publish-time (staging/prod) via your build pipeline\n * or bump this constant per release artefact — hosts cannot override `baseUrl` at runtime.\n */\nexport const API_ORIGIN = \"https://staging-api.snapkyc.com/\";\n\nexport const paths = {\n agreement: () => `${API_ORIGIN}/api/integrations/agreement`,\n txnInitiate: () => `${API_ORIGIN}/api/integrations/transactions/initiate`,\n generateQr: () => `${API_ORIGIN}/api/integrations/generate-qr`,\n generateIntent: (platform: \"android\" | \"ios\") =>\n `${API_ORIGIN}/api/integrations/generate-intent?platform=${platform}`,\n txnStatus: (txnId: string) =>\n `${API_ORIGIN}/api/integrations/transactions/${encodeURIComponent(txnId)}/status`,\n};\n","export type ApiEnvelope<T> = {\n request_id: string;\n status_code: number;\n message: string;\n data: T | null;\n error: boolean;\n error_message: unknown;\n};\n\nexport function unwrapEnvelope<T>(envelope: ApiEnvelope<T>, fallbackMessage = \"API error\"): T {\n if (envelope.error || envelope.data == null) {\n const detail =\n typeof envelope.error_message === \"string\"\n ? envelope.error_message\n : envelope.error_message != null\n ? JSON.stringify(envelope.error_message)\n : envelope.message;\n throw new Error(detail || fallbackMessage);\n }\n return envelope.data;\n}\n","export function authorizationHeaders(integrationToken: string): Record<string, string> {\n return {\n Authorization: `Token ${integrationToken}`,\n };\n}\n","import { authorizationHeaders } from \"./auth\";\nimport { SnapSdkHttpError as HttpErr } from \"./errors\";\n\nasync function assertOk(res: Response, url: string): Promise<void> {\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n const err = new HttpErr(url, res.status, `HTTP ${res.status} calling ${url}`, text);\n throw err;\n }\n}\n\nexport async function fetchJson<T>(options: {\n url: string;\n integrationToken: string;\n method?: \"GET\" | \"POST\";\n body?: unknown;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n}): Promise<T> {\n const { url, integrationToken, method = \"GET\", body, signal, headers = {} } = options;\n\n const res = await fetch(url, {\n method,\n signal,\n headers: {\n ...authorizationHeaders(integrationToken),\n Accept: \"application/json\",\n ...(body !== undefined ? { \"Content-Type\": \"application/json\" } : {}),\n ...headers,\n },\n body: body === undefined ? undefined : JSON.stringify(body),\n }).catch((e: unknown) => {\n throw e;\n });\n\n await assertOk(res, url);\n\n return (await res.json()) as T;\n}\n\nexport async function fetchBlob(options: {\n url: string;\n integrationToken: string;\n method?: \"POST\";\n body?: unknown;\n signal?: AbortSignal;\n}): Promise<Blob> {\n const { url, integrationToken, method = \"POST\", body, signal } = options;\n\n const res = await fetch(url, {\n method,\n signal,\n headers: {\n ...authorizationHeaders(integrationToken),\n Accept: \"image/png,*/*\",\n ...(body !== undefined ? { \"Content-Type\": \"application/json\" } : {}),\n },\n body: body === undefined ? undefined : JSON.stringify(body),\n }).catch((e: unknown) => {\n throw e;\n });\n\n await assertOk(res, url);\n\n return await res.blob();\n}\n\nexport { SnapSdkHttpError } from \"./errors\";\n","import { paths } from \"../config\";\nimport { unwrapEnvelope, type ApiEnvelope } from \"./envelope\";\nimport { normalizeTxnStatusPayload } from \"./normalizeStatus\";\nimport { fetchBlob, fetchJson } from \"./client\";\nimport type {\n AgreementEnvelope,\n InitiateTxnBody,\n InitiateTxnData,\n InitiateTxnResponse,\n IntentResponseBody,\n TxnStatusData,\n TxnStatusResponse,\n} from \"./types\";\n\nexport async function getAgreement(options: {\n integrationToken: string;\n signal?: AbortSignal;\n acceptLanguage?: string;\n}): Promise<AgreementEnvelope> {\n return fetchJson<AgreementEnvelope>({\n url: paths.agreement(),\n integrationToken: options.integrationToken,\n method: \"GET\",\n signal: options.signal,\n headers: options.acceptLanguage\n ? {\n \"Accept-Language\": options.acceptLanguage,\n }\n : {},\n });\n}\n\nexport async function initiateTxn(options: {\n integrationToken: string;\n body: InitiateTxnBody;\n signal?: AbortSignal;\n}): Promise<InitiateTxnResponse> {\n const envelope = await fetchJson<ApiEnvelope<InitiateTxnData>>({\n url: paths.txnInitiate(),\n integrationToken: options.integrationToken,\n method: \"POST\",\n body: options.body,\n signal: options.signal,\n });\n return unwrapEnvelope(envelope, \"Transaction initiate failed\");\n}\n\nexport async function generateQr(options: {\n integrationToken: string;\n txnId: string;\n size?: number;\n signal?: AbortSignal;\n}): Promise<Blob> {\n return fetchBlob({\n url: paths.generateQr(),\n integrationToken: options.integrationToken,\n body: {\n txn_id: options.txnId,\n size: options.size ?? 376,\n },\n signal: options.signal,\n });\n}\n\nexport async function createIntent(options: {\n integrationToken: string;\n txnId: string;\n platform: \"android\" | \"ios\";\n signal?: AbortSignal;\n}): Promise<IntentResponseBody> {\n const envelope = await fetchJson<ApiEnvelope<IntentResponseBody>>({\n url: paths.generateIntent(options.platform),\n integrationToken: options.integrationToken,\n method: \"POST\",\n body: { txn_id: options.txnId },\n signal: options.signal,\n });\n return unwrapEnvelope(envelope, \"Intent generation failed\");\n}\n\nexport async function pollTxnStatus(options: {\n integrationToken: string;\n txnId: string;\n signal?: AbortSignal;\n}): Promise<TxnStatusResponse> {\n const envelope = await fetchJson<ApiEnvelope<TxnStatusData>>({\n url: paths.txnStatus(options.txnId),\n integrationToken: options.integrationToken,\n method: \"GET\",\n signal: options.signal,\n });\n return normalizeTxnStatusPayload(unwrapEnvelope(envelope, \"Transaction status fetch failed\"));\n}\n","import { hasDisplayableDemographics } from \"../demographicDisplay\";\nimport { pollTxnStatus } from \"./endpoints\";\nimport type { TxnStatusResponse } from \"./types\";\n\nconst successStatusesLower = new Set([\"success\", \"completed\", \"complete\"]);\n\nconst pendingHintsLower = new Set([\n \"pending\",\n \"in_progress\",\n \"processing\",\n \"initiated\",\n \"waiting\",\n \"started\",\n]);\n\nconst failureStatusesLower = new Set([\"failed\", \"failure\", \"error\", \"rejected\", \"expired\"]);\n\n/** After SUCCESS, keep polling briefly so late-arriving demographic_data can be captured. */\nconst DEMOGRAPHIC_WAIT_AFTER_SUCCESS_MS = 15_000;\n\nfunction normalizeStatus(raw: unknown): string {\n return typeof raw === \"string\" ? raw.trim().toLowerCase() : \"\";\n}\n\n/** Anything that is neither a known success nor a known failure is treated as pending and keeps polling until timeout. */\nexport function classifyTxnStatus(raw: unknown): \"success\" | \"failure\" | \"pending\" {\n const s = normalizeStatus(raw);\n if (!s) return \"pending\";\n if (successStatusesLower.has(s)) return \"success\";\n if (failureStatusesLower.has(s)) return \"failure\";\n if (pendingHintsLower.has(s)) return \"pending\";\n return \"pending\";\n}\n\nasync function delay(ms: number, signal: AbortSignal): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n if (signal.aborted) {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n return;\n }\n const timer = globalThis.setTimeout(() => resolve(), ms);\n signal.addEventListener(\n \"abort\",\n () => {\n globalThis.clearTimeout(timer);\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n },\n { once: true },\n );\n });\n}\n\nexport async function pollTxnUntilTerminal(options: {\n integrationToken: string;\n txnId: string;\n signal: AbortSignal;\n pollIntervalMs: number;\n deadlineMs: number;\n}): Promise<TxnStatusResponse> {\n const start = Date.now();\n let successAt: number | null = null;\n let lastSuccess: TxnStatusResponse | null = null;\n\n while (true) {\n if (options.signal.aborted) {\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n\n if (Date.now() - start > options.deadlineMs) {\n if (lastSuccess) return lastSuccess;\n throw new Error(`Txn polling timed out after ${options.deadlineMs}ms`);\n }\n\n const latest = await pollTxnStatus({\n integrationToken: options.integrationToken,\n txnId: options.txnId,\n signal: options.signal,\n });\n\n const bucket = classifyTxnStatus(latest.status);\n\n if (bucket === \"success\") {\n lastSuccess = latest;\n if (successAt == null) successAt = Date.now();\n\n if (hasDisplayableDemographics(latest)) return latest;\n\n if (Date.now() - successAt >= DEMOGRAPHIC_WAIT_AFTER_SUCCESS_MS) return latest;\n } else {\n successAt = null;\n lastSuccess = null;\n\n if (bucket === \"failure\") {\n throw new Error(`Txn failed with terminal status '${String(latest.status)}'`);\n }\n }\n\n await delay(options.pollIntervalMs, options.signal);\n }\n}\n","import type { AgreementEnvelope } from \"./http/types\";\nimport type { SelectablePurpose } from \"./flowTypes\";\n\n/** Purposes selectable for `POST …/transactions/initiate` (`purpose_ids`). */\nexport function buildSelectablePurposes(data: AgreementEnvelope[\"data\"]): SelectablePurpose[] {\n return (data.purposes ?? []).map((purpose) => ({\n id: purpose.id,\n label: purpose.description?.en ?? purpose.name,\n }));\n}\n","import type { IntentOs } from \"./device/detectIntentPlatform\";\nimport type { AgreementEnvelope } from \"./http/types\";\n\nexport function agreementTextHtml(\n data: AgreementEnvelope[\"data\"],\n acceptLanguage?: string,\n): string | null {\n const texts = data.agreement_text ?? {};\n const preferredLang = acceptLanguage?.split(\",\")[0]?.trim();\n const key =\n preferredLang && texts[preferredLang]\n ? preferredLang\n : texts.en\n ? \"en\"\n : Object.keys(texts)[0];\n\n const raw = key ? texts[key] : \"\";\n const text = typeof raw === \"string\" ? raw.trim() : \"\";\n if (!text) return null;\n\n // Treat as plain-ish text; callers should still sanitize HTML with DOMPurify.\n const escaped = text\n .replaceAll(\"&\", \"&\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\");\n\n return escaped.replace(/\\n/g, \"<br />\");\n}\n\nexport function coerceForcedIntentOs(props: {\n _dangerouslyForceIntentPlatform?: IntentOs;\n dangerousForceIntentPlatform?: IntentOs;\n intentPlatformOverride?: IntentOs;\n}): IntentOs | undefined {\n return props._dangerouslyForceIntentPlatform ?? props.dangerousForceIntentPlatform ?? props.intentPlatformOverride;\n}\n","import { Component, type ErrorInfo, type ReactNode } from \"react\";\n\ntype Props = {\n children: ReactNode;\n fallback?: ReactNode;\n};\n\ntype State = {\n error: Error | null;\n};\n\nexport class FlowErrorBoundary extends Component<Props, State> {\n state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo): void {\n // eslint-disable-next-line no-console\n console.error(\"[snap-consent-handoff] render error\", error, info.componentStack);\n }\n\n render(): ReactNode {\n if (this.state.error) {\n return (\n this.props.fallback ?? (\n <div className=\"snap-consent-handoff_err\" role=\"alert\">\n Something went wrong displaying the verification result. Please check the browser console or use the\n data returned in <code>onSuccess</code>.\n </div>\n )\n );\n }\n\n return this.props.children;\n }\n}\n","import snapkycLogo from \"../assets/snapkycog.svg\";\n\nexport function PoweredBySnapKyc() {\n return (\n <footer className=\"snap-consent-handoff_powered\" data-testid=\"snap-consent-handoff-powered\">\n <span className=\"snap-consent-handoff_poweredLabel\">Powered by</span>\n <img className=\"snap-consent-handoff_poweredLogo\" src={snapkycLogo} alt=\"snapkyc\" />\n </footer>\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\n\nimport {\n type DemographicAccordionSection,\n demographicAccordionSections,\n extractDemographicData,\n formatDisplayValue,\n formatPurposeLabel,\n residentImageDataUrl,\n} from \"../demographicDisplay\";\nimport { normalizeTxnStatusPayload } from \"../http/normalizeStatus\";\nimport type { TxnStatusResponse } from \"../http/types\";\n\nfunction SuccessShieldIcon() {\n return (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden>\n <path\n d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"m9 12 2 2 4-4\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction SmallCheckIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden>\n <path\n d=\"M3.5 8.2 6.3 11l6.2-6.2\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction SectionListIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden>\n <path d=\"M8 6h13M8 12h13M8 18h13\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n <path\n d=\"M3.5 6l1 1-1 1M3.5 12l1 1-1 1M3.5 18l1 1-1 1\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction SectionUserIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden>\n <path\n d=\"M12 11a3 3 0 1 0-3-3 3 3 0 0 0 3 3zm0 2c-3.3 0-6 1.6-6 3.5V19h12v-2.5C18 14.6 15.3 13 12 13z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n}\n\nfunction AccordionChevron({ open }: { open: boolean }) {\n return (\n <span\n className={\n open\n ? \"snap-consent-handoff_accordionChevron snap-consent-handoff_accordionChevron--open\"\n : \"snap-consent-handoff_accordionChevron\"\n }\n aria-hidden\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 9l6 6 6-6\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </span>\n );\n}\n\nexport function TxnSuccessPanel({ status }: { status: TxnStatusResponse | null | undefined }) {\n const normalized = useMemo(() => normalizeTxnStatusPayload(status), [status]);\n\n const demographics = useMemo(() => extractDemographicData(normalized), [normalized]);\n const photoUrl = demographics ? residentImageDataUrl(demographics) : null;\n const photoOmitted = Boolean(\n demographics &&\n typeof demographics.resident_image === \"string\" &&\n demographics.resident_image.trim().length > 0 &&\n !photoUrl,\n );\n\n const accordionSections = useMemo(() => {\n if (!demographics) return [];\n return demographicAccordionSections(demographics, {\n includePhoto: Boolean(photoUrl || photoOmitted),\n });\n }, [demographics, photoUrl, photoOmitted]);\n\n const defaultOpenId = useMemo(() => {\n const personal = accordionSections.find((s) => s.id === \"personal\");\n return personal?.id ?? accordionSections[0]?.id ?? \"\";\n }, [accordionSections]);\n\n const [openAccordionId, setOpenAccordionId] = useState(defaultOpenId);\n\n useEffect(() => {\n setOpenAccordionId(defaultOpenId);\n }, [defaultOpenId]);\n\n const purposes = Array.isArray(normalized.purposes) ? normalized.purposes : [];\n\n const hasSummaryPayload = Boolean(normalized.txn_id || normalized.status);\n\n if (!hasSummaryPayload) {\n return (\n <p className=\"snap-consent-handoff_muted\" style={{ marginTop: \"12px\" }}>\n Verification completed, but no status payload was available to display.\n </p>\n );\n }\n\n const showDemographicsBlock =\n demographics && (accordionSections.length > 0 || photoOmitted);\n\n function toggleAccordion(id: string) {\n setOpenAccordionId((prev) => (prev === id ? \"\" : id));\n }\n\n return (\n <div className=\"snap-consent-handoff_successBody\" data-testid=\"snap-consent-handoff-success-body\">\n <div className=\"snap-consent-handoff_successHero\">\n <div className=\"snap-consent-handoff_successBadge\">\n <SuccessShieldIcon />\n </div>\n <div className=\"snap-consent-handoff_successHeroText\">\n <h2 className=\"snap-consent-handoff_successTitle\">Verification successful</h2>\n <p className=\"snap-consent-handoff_successSubtitle\">Identity has been verified successfully.</p>\n </div>\n </div>\n\n <section className=\"snap-consent-handoff_statusStrip\" aria-label=\"Transaction summary\">\n <div className=\"snap-consent-handoff_statusStripCol\">\n <p className=\"snap-consent-handoff_statusLabel\">Status</p>\n <p className=\"snap-consent-handoff_statusValue\">\n <span className=\"snap-consent-handoff_statusCheck\" aria-hidden>\n <SmallCheckIcon />\n </span>\n {formatDisplayValue(normalized.status)}\n </p>\n </div>\n <div className=\"snap-consent-handoff_statusStripCol snap-consent-handoff_statusStripCol--end\">\n <p className=\"snap-consent-handoff_statusLabel snap-consent-handoff_statusLabel--neutral\">Completed at</p>\n <p className=\"snap-consent-handoff_statusMeta\">{formatDisplayValue(normalized.created_at)}</p>\n </div>\n </section>\n\n {purposes.length > 0 ? (\n <section className=\"snap-consent-handoff_purposeCard\" data-testid=\"snap-consent-handoff-purposes\">\n <h3 className=\"snap-consent-handoff_successSectionTitle\">\n <span className=\"snap-consent-handoff_successSectionIcon\" aria-hidden>\n <SectionListIcon />\n </span>\n Confirmed purposes\n </h3>\n <ul className=\"snap-consent-handoff_purposeGrid\">\n {purposes.map((purpose, index) => (\n <li key={purpose?.id ?? `purpose-${index}`} className=\"snap-consent-handoff_purposeGridItem\">\n <span className=\"snap-consent-handoff_purposeCheck\" aria-hidden>\n <SmallCheckIcon />\n </span>\n <span>{formatPurposeLabel(purpose?.name)}</span>\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {showDemographicsBlock ? (\n <section className=\"snap-consent-handoff_demographics\" data-testid=\"snap-consent-handoff-demographics\">\n <h3 className=\"snap-consent-handoff_successSectionTitle\">\n <span className=\"snap-consent-handoff_successSectionIcon\" aria-hidden>\n <SectionUserIcon />\n </span>\n Demographic data\n </h3>\n\n <div className=\"snap-consent-handoff_accordionList\">\n {accordionSections.map((section) => (\n <DemographicAccordion\n key={section.id}\n section={section}\n photoUrl={section.includePhoto ? photoUrl : null}\n photoOmitted={section.includePhoto ? photoOmitted : false}\n expanded={openAccordionId === section.id}\n onToggle={() => toggleAccordion(section.id)}\n />\n ))}\n </div>\n </section>\n ) : (\n <p className=\"snap-consent-handoff_muted snap-consent-handoff_successNoDemo\">\n No demographic details were returned for this transaction.\n </p>\n )}\n </div>\n );\n}\n\nfunction DemographicAccordion({\n section,\n photoUrl,\n photoOmitted,\n expanded,\n onToggle,\n}: {\n section: DemographicAccordionSection;\n photoUrl: string | null;\n photoOmitted: boolean;\n expanded: boolean;\n onToggle: () => void;\n}) {\n const panelId = `snap-demo-accordion-${section.id}`;\n const headerId = `snap-demo-accordion-h-${section.id}`;\n\n return (\n <div className=\"snap-consent-handoff_accordion\">\n <button\n type=\"button\"\n id={headerId}\n className=\"snap-consent-handoff_accordionHeader\"\n aria-expanded={expanded}\n aria-controls={panelId}\n onClick={onToggle}\n >\n <span className=\"snap-consent-handoff_accordionTitle\">{section.title}</span>\n <AccordionChevron open={expanded} />\n </button>\n <div\n id={panelId}\n role=\"region\"\n aria-labelledby={headerId}\n className={\n expanded\n ? \"snap-consent-handoff_accordionPanel snap-consent-handoff_accordionPanel--open\"\n : \"snap-consent-handoff_accordionPanel\"\n }\n >\n {photoOmitted ? (\n <p className=\"snap-consent-handoff_muted snap-consent-handoff_accordionNote\">\n Photo omitted (too large to preview in the browser).\n </p>\n ) : null}\n <div\n className={\n photoUrl\n ? \"snap-consent-handoff_accordionBody snap-consent-handoff_accordionBody--withPhoto\"\n : \"snap-consent-handoff_accordionBody\"\n }\n >\n {photoUrl ? (\n <div className=\"snap-consent-handoff_accordionPhoto\">\n <img src={photoUrl} alt=\"Resident\" loading=\"lazy\" decoding=\"async\" />\n </div>\n ) : null}\n {section.fields.length > 0 ? (\n <dl className=\"snap-consent-handoff_successFields\">\n {section.fields.map((row) => (\n <div key={row.key} className=\"snap-consent-handoff_successField\">\n <dt>{row.label}</dt>\n <dd>{row.value}</dd>\n </div>\n ))}\n </dl>\n ) : photoUrl || photoOmitted ? null : (\n <p className=\"snap-consent-handoff_muted\">No fields in this category.</p>\n )}\n </div>\n </div>\n </div>\n );\n}\n","import { StrictMode } from \"react\";\nimport { createRoot } from \"react-dom/client\";\n\nimport type { SnapConsentHandoffPublicProps } from \"../flowTypes\";\n\nimport { SnapConsentHandoffFlow } from \"./SnapConsentHandoffFlow\";\n\nexport type OpenSnapConsentHandoffOptions = Omit<\n SnapConsentHandoffPublicProps,\n \"displayMode\" | \"onRequestClose\"\n> &\n Partial<Pick<SnapConsentHandoffPublicProps, \"displayMode\">> & {\n /**\n * Render in StrictMode — mostly useful during development.\n * Default false to avoid duplicated effects/timeouts surprises in overlays.\n */\n strict?: boolean;\n };\n\n/**\n * Opens a modal consent + handoff flow mounted on `document.body`.\n *\n * Important: callers should keep the returned `{ dispose }` and invoke it when navigating away so\n * polling aborts cleanly and blob/object URLs revoke via component unmount.\n */\nexport function openSnapConsentHandoffFlow(options: OpenSnapConsentHandoffOptions): {\n dispose(): void;\n} {\n if (typeof document === \"undefined\") {\n throw new Error(\"openSnapConsentHandoffFlow requires a browser environment\");\n }\n\n const { strict = false, displayMode = \"modal\", ...flowProps } = options;\n\n const mount = document.createElement(\"div\");\n mount.setAttribute(\"data-snap-consent-handoff-host\", \"\");\n\n const root = createRoot(mount);\n document.body.appendChild(mount);\n\n let disposed = false;\n\n function dispose(): void {\n if (disposed) return;\n disposed = true;\n try {\n root.unmount();\n } finally {\n mount.remove();\n }\n }\n\n const element = (\n <SnapConsentHandoffFlow {...flowProps} displayMode={displayMode} onRequestClose={() => dispose()} />\n );\n\n try {\n root.render(strict ? <StrictMode>{element}</StrictMode> : element);\n } catch (e: unknown) {\n dispose();\n throw e instanceof Error ? e : new Error(String(e));\n }\n\n return { dispose };\n}\n\n/**\n * Deprecated alias kept for docs that referenced a QR-specific opener name.\n */\nexport const openSnapConsentQrFlow = openSnapConsentHandoffFlow;\n"],"mappings":"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","names":["useEffect","useMemo","useState","jsx","jsxs","jsx","jsxs","jsx","jsxs","useMemo","useEffect","useState","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/http/errors.ts","../src/theme.ts","../src/http/normalizeStatus.ts","../src/demographicDisplay.ts","../src/react/SnapConsentHandoffFlow.tsx","../src/device/detectIntentPlatform.ts","../src/config.ts","../src/http/envelope.ts","../src/http/auth.ts","../src/http/client.ts","../src/http/endpoints.ts","../src/http/pollTxn.ts","../src/purposeSelection.ts","../src/uiHelpers.ts","../src/react/FlowErrorBoundary.tsx","../src/react/PoweredBySnapKyc.tsx","../src/react/TxnSuccessPanel.tsx","../src/react/openSnapConsentHandoffFlow.tsx"],"sourcesContent":["export class SnapSdkHttpError extends Error {\n readonly name = \"SnapSdkHttpError\";\n\n constructor(\n public readonly url: string,\n public readonly status: number,\n message: string,\n public readonly bodyText?: string,\n ) {\n super(message);\n }\n}\n\nexport class SnapSdkJsonError extends Error {\n readonly name = \"SnapSdkJsonError\";\n\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n }\n}\n","import type { CSSProperties } from \"react\";\n\n/**\n * Resolved visual tokens for the consent handoff UI.\n * Pass a partial object via `theme` on `SnapConsentHandoffFlow` to override defaults.\n */\nexport type SnapConsentHandoffTheme = {\n fontFamily: string;\n /** Primary brand color (buttons, selected states, accents). */\n primary: string;\n /** Text/icon color on top of primary (typically white). */\n onPrimary: string;\n /** Sheet / panel background (e.g. warm light gray). */\n canvas: string;\n /** Default “card” surface (e.g. unselected purpose rows). */\n surface: string;\n /** Muted surface (agreement notice, selected purpose row). */\n surfaceMuted: string;\n text: string;\n textMuted: string;\n border: string;\n /** Strong border for selected / emphasized controls. */\n borderActive: string;\n modalOverlay: string;\n danger: string;\n /** Corner radius for cards, rows, and buttons (e.g. `12px`). */\n radius: string;\n gap: string;\n maxWidth: string;\n modalZ: string;\n /** Success state (shield, status checkmarks). */\n success: string;\n /** Success screen status summary card background. */\n successStatusSurface: string;\n /** Success screen confirmed-purposes panel background. */\n successPurposesSurface: string;\n /** Accordion borders on the success demographic panel. */\n successAccordionBorder: string;\n};\n\nexport const DEFAULT_SNAP_CONSENT_THEME: SnapConsentHandoffTheme = {\n fontFamily: `system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif`,\n primary: \"#E87D43\",\n onPrimary: \"#ffffff\",\n canvas: \"#FAFAF9\",\n surface: \"#ffffff\",\n surfaceMuted: \"#FFF7ED\",\n text: \"#1c1917\",\n textMuted: \"#57534e\",\n border: \"#e7e5e4\",\n borderActive: \"#E87D43\",\n modalOverlay: \"rgba(28, 25, 23, 0.55)\",\n danger: \"#b91c1c\",\n radius: \"12px\",\n gap: \"12px\",\n maxWidth: \"720px\",\n modalZ: \"10000\",\n success: \"#16a34a\",\n successStatusSurface: \"#fff5f0\",\n successPurposesSurface: \"#f0f2ff\",\n successAccordionBorder: \"#e0d7d0\",\n};\n\nexport function resolveSnapConsentTheme(partial?: Partial<SnapConsentHandoffTheme>): SnapConsentHandoffTheme {\n const merged = { ...DEFAULT_SNAP_CONSENT_THEME, ...partial };\n if (partial?.primary !== undefined && partial.borderActive === undefined) {\n merged.borderActive = partial.primary;\n }\n return merged;\n}\n\n/**\n * Maps resolved theme tokens to CSS custom properties on `.snap-consent-handoff`.\n */\nexport function themeToCssProperties(theme: SnapConsentHandoffTheme): CSSProperties {\n return {\n \"--snap-consent-font-family\": theme.fontFamily,\n \"--snap-consent-text\": theme.text,\n \"--snap-consent-muted\": theme.textMuted,\n \"--snap-consent-bg\": theme.canvas,\n \"--snap-consent-surface\": theme.surface,\n \"--snap-consent-surface-muted\": theme.surfaceMuted,\n \"--snap-consent-border\": theme.border,\n \"--snap-consent-border-active\": theme.borderActive,\n \"--snap-consent-overlay\": theme.modalOverlay,\n \"--snap-consent-accent\": theme.primary,\n \"--snap-consent-on-primary\": theme.onPrimary,\n \"--snap-consent-danger\": theme.danger,\n \"--snap-consent-radius\": theme.radius,\n \"--snap-consent-gap\": theme.gap,\n \"--snap-consent-max-width\": theme.maxWidth,\n \"--snap-consent-modal-z\": theme.modalZ,\n \"--snap-consent-success\": theme.success,\n \"--snap-consent-success-status-bg\": theme.successStatusSurface,\n \"--snap-consent-success-purposes-bg\": theme.successPurposesSurface,\n \"--snap-consent-success-accordion-border\": theme.successAccordionBorder,\n } as CSSProperties;\n}\n","import type { DemographicData, TxnStatusEvidence, TxnStatusResponse } from \"./types\";\n\nfunction parseJsonObject(raw: unknown): Record<string, unknown> | null {\n if (raw == null) return null;\n if (typeof raw === \"string\") {\n const trimmed = raw.trim();\n if (!trimmed) return null;\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n return parseJsonObject(parsed);\n } catch {\n return null;\n }\n }\n if (Array.isArray(raw) || typeof raw !== \"object\") return null;\n return raw as Record<string, unknown>;\n}\n\nexport function parseDemographicPayload(raw: unknown): DemographicData | null {\n const obj = parseJsonObject(raw);\n if (!obj) return null;\n return obj as DemographicData;\n}\n\nfunction parseEvidencePayload(raw: unknown): TxnStatusEvidence | undefined {\n const obj = parseJsonObject(raw);\n if (!obj) return undefined;\n\n const demographic =\n parseDemographicPayload(obj.demographic_data) ??\n parseDemographicPayload(obj.demographicData);\n\n return {\n ...obj,\n aadhaar_uuid: typeof obj.aadhaar_uuid === \"string\" ? obj.aadhaar_uuid : undefined,\n sd_jwt: typeof obj.sd_jwt === \"string\" ? obj.sd_jwt : undefined,\n disclosures: Array.isArray(obj.disclosures) ? obj.disclosures : undefined,\n demographic_data: demographic ?? undefined,\n };\n}\n\nfunction parsePurposes(raw: unknown): { id: string; name: string }[] {\n if (!Array.isArray(raw)) return [];\n return raw\n .map((item) => {\n if (!item || typeof item !== \"object\") return null;\n const row = item as Record<string, unknown>;\n const id = typeof row.id === \"string\" ? row.id : \"\";\n const name = typeof row.name === \"string\" ? row.name : \"\";\n if (!id && !name) return null;\n return { id: id || name, name: name || id };\n })\n .filter((row): row is { id: string; name: string } => row != null);\n}\n\n/**\n * Normalizes status payloads from GET …/transactions/{id}/status into a stable shape\n * for UI + onSuccess, even if the host accidentally passes the full API envelope.\n */\nexport function normalizeTxnStatusPayload(input: unknown): TxnStatusResponse {\n const root = parseJsonObject(input);\n if (!root) {\n return { txn_id: \"\", status: \"UNKNOWN\" };\n }\n\n // Full API envelope: { data: { txn_id, status, evidence, ... } }\n if (\n root.data &&\n typeof root.data === \"object\" &&\n !Array.isArray(root.data) &&\n (\"txn_id\" in (root.data as object) || \"status\" in (root.data as object))\n ) {\n return normalizeTxnStatusPayload(root.data);\n }\n\n const txn_id =\n typeof root.txn_id === \"string\"\n ? root.txn_id\n : typeof root.txnId === \"string\"\n ? root.txnId\n : \"\";\n\n const status = typeof root.status === \"string\" ? root.status : String(root.status ?? \"UNKNOWN\");\n\n const created_at = typeof root.created_at === \"string\" ? root.created_at : undefined;\n\n const purposes = parsePurposes(root.purposes);\n\n let evidence = parseEvidencePayload(root.evidence);\n\n const flatDemo =\n parseDemographicPayload(root.demographic_data) ?? parseDemographicPayload(root.demographicData);\n\n if (flatDemo) {\n evidence = { ...(evidence ?? {}), demographic_data: flatDemo };\n }\n\n return {\n ...root,\n txn_id,\n status,\n created_at,\n purposes,\n evidence,\n };\n}\n","import { parseDemographicPayload } from \"./http/normalizeStatus\";\nimport type { DemographicData, TxnStatusResponse } from \"./http/types\";\n\nexport type DemographicField = {\n /** Original API field name (snake_case). */\n key: string;\n label: string;\n value: string;\n};\n\nexport type DemographicAccordionSection = {\n id: string;\n title: string;\n fields: DemographicField[];\n /** When true, render resident photo in this section (Personal Details only). */\n includePhoto: boolean;\n};\n\nconst SKIP_DEMOGRAPHIC_KEYS = new Set([\"resident_image\"]);\n\nconst PERSONAL_DETAIL_KEYS = new Set([\n \"resident_name\",\n \"resident_name_local_language\",\n \"date_of_birth\",\n \"gender\",\n \"care_of\",\n \"care_of_local_language\",\n \"is_age_above_18\",\n \"is_age_above_50\",\n \"is_age_above_60\",\n \"is_age_above_75\",\n \"is_non_resident_indian\",\n]);\n\nconst CONTACT_DETAIL_KEYS = new Set([\n \"mobile_number\",\n \"masked_mobile_number\",\n \"email_address\",\n \"masked_email_address\",\n]);\n\nconst ADDRESS_DETAIL_KEYS = new Set([\n \"full_address\",\n \"regional_address\",\n \"building\",\n \"street\",\n \"locality\",\n \"landmark\",\n \"village_town_city\",\n \"sub_district\",\n \"district\",\n \"state\",\n \"postal_code\",\n \"post_office_name\",\n]);\n\nconst GROUPED_DETAIL_KEYS = new Set<string>([\n ...PERSONAL_DETAIL_KEYS,\n ...CONTACT_DETAIL_KEYS,\n ...ADDRESS_DETAIL_KEYS,\n]);\n\n/** Skip inline photos above ~110KB decoded to avoid freezing the modal. */\nconst MAX_RESIDENT_IMAGE_B64_CHARS = 150_000;\n\n/** Preferred display order; any other keys from the API are appended alphabetically. */\nconst DEMOGRAPHIC_KEY_ORDER: string[] = [\n \"resident_name\",\n \"resident_name_local_language\",\n \"date_of_birth\",\n \"gender\",\n \"care_of\",\n \"care_of_local_language\",\n \"mobile_number\",\n \"masked_mobile_number\",\n \"email_address\",\n \"masked_email_address\",\n \"full_address\",\n \"regional_address\",\n \"building\",\n \"street\",\n \"locality\",\n \"landmark\",\n \"village_town_city\",\n \"sub_district\",\n \"district\",\n \"state\",\n \"postal_code\",\n \"post_office_name\",\n \"enrolment_date\",\n \"enrolment_number\",\n \"credential_issuing_date\",\n \"is_age_above_18\",\n \"is_age_above_50\",\n \"is_age_above_60\",\n \"is_age_above_75\",\n \"is_non_resident_indian\",\n];\n\nexport function extractDemographicData(status: TxnStatusResponse | null | undefined): DemographicData | null {\n if (!status || typeof status !== \"object\") return null;\n\n const fromEvidence = parseDemographicPayload(status.evidence?.demographic_data);\n if (fromEvidence) return fromEvidence;\n\n return parseDemographicPayload(status.demographic_data);\n}\n\nexport function hasDisplayableDemographics(status: TxnStatusResponse | null | undefined): boolean {\n const data = extractDemographicData(status);\n if (!data) return false;\n if (demographicFieldsForDisplay(data).length > 0) return true;\n const raw = data.resident_image;\n if (typeof raw !== \"string\" || !raw.trim()) return false;\n return raw.trim().length <= MAX_RESIDENT_IMAGE_B64_CHARS;\n}\n\nexport function formatDisplayValue(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (typeof value === \"string\") return value.trim() === \"\" ? \"null\" : value;\n if (typeof value === \"object\") return \"null\";\n return String(value);\n}\n\nexport function humanizeDemographicKey(key: string): string {\n return key\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (ch) => ch.toUpperCase());\n}\n\nfunction orderedDemographicKeys(data: DemographicData): string[] {\n const keys = Object.keys(data).filter((k) => !SKIP_DEMOGRAPHIC_KEYS.has(k));\n const rank = new Map(DEMOGRAPHIC_KEY_ORDER.map((k, i) => [k, i]));\n\n return keys.sort((a, b) => {\n const ra = rank.get(a) ?? Number.MAX_SAFE_INTEGER;\n const rb = rank.get(b) ?? Number.MAX_SAFE_INTEGER;\n if (ra !== rb) return ra - rb;\n return a.localeCompare(b);\n });\n}\n\n/** All demographic_data fields; empty / object values render as `null`. */\nexport function demographicFieldsForDisplay(data: DemographicData): DemographicField[] {\n return orderedDemographicKeys(data).map((key) => ({\n key,\n label: humanizeDemographicKey(key),\n value: formatDisplayValue(data[key]),\n }));\n}\n\n/**\n * Groups demographic fields into accordion sections (Personal, Contact, Address, Additional).\n * Personal Details may include a photo slot when `includePhoto` is true.\n */\nexport function demographicAccordionSections(\n data: DemographicData,\n options: { includePhoto: boolean },\n): DemographicAccordionSection[] {\n const all = demographicFieldsForDisplay(data);\n const byKey = (keys: Set<string>) => all.filter((f) => keys.has(f.key));\n const personalFields = byKey(PERSONAL_DETAIL_KEYS);\n const contactFields = byKey(CONTACT_DETAIL_KEYS);\n const addressFields = byKey(ADDRESS_DETAIL_KEYS);\n const additionalFields = all.filter((f) => !GROUPED_DETAIL_KEYS.has(f.key));\n\n const sections: DemographicAccordionSection[] = [];\n\n if (personalFields.length > 0 || options.includePhoto) {\n sections.push({\n id: \"personal\",\n title: \"Personal Details\",\n fields: personalFields,\n includePhoto: options.includePhoto,\n });\n }\n\n if (contactFields.length > 0) {\n sections.push({\n id: \"contact\",\n title: \"Contact Information\",\n fields: contactFields,\n includePhoto: false,\n });\n }\n\n if (addressFields.length > 0) {\n sections.push({\n id: \"address\",\n title: \"Address Details\",\n fields: addressFields,\n includePhoto: false,\n });\n }\n\n if (additionalFields.length > 0) {\n sections.push({\n id: \"additional\",\n title: \"Additional details\",\n fields: additionalFields,\n includePhoto: false,\n });\n }\n\n return sections;\n}\n\nexport function residentImageDataUrl(data: DemographicData): string | null {\n const raw = data.resident_image;\n if (typeof raw !== \"string\" || !raw.trim()) return null;\n const b64 = raw.trim();\n if (b64.length > MAX_RESIDENT_IMAGE_B64_CHARS) return null;\n if (b64.startsWith(\"data:\")) return b64;\n return `data:image/jpeg;base64,${b64}`;\n}\n\nexport function formatPurposeLabel(name: unknown): string {\n if (typeof name !== \"string\" || !name.trim()) return \"Purpose\";\n return name\n .split(\"_\")\n .map((part) => part.charAt(0) + part.slice(1).toLowerCase())\n .join(\" \");\n}\n","/* eslint-disable @typescript-eslint/no-floating-promises */\nimport DOMPurify from \"dompurify\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport type { IntentOs } from \"../device/detectIntentPlatform\";\nimport { detectIntentPlatform } from \"../device/detectIntentPlatform\";\nimport type { CompletionResult, FlowEvent, SnapConsentHandoffPublicProps } from \"../flowTypes\";\nimport { createIntent, generateQr, getAgreement, initiateTxn } from \"../http/endpoints\";\nimport type { AgreementEnvelope } from \"../http/types\";\nimport { normalizeTxnStatusPayload } from \"../http/normalizeStatus\";\nimport type { TxnStatusResponse } from \"../http/types\";\nimport { pollTxnUntilTerminal } from \"../http/pollTxn\";\nimport { buildSelectablePurposes } from \"../purposeSelection\";\nimport { resolveSnapConsentTheme, themeToCssProperties } from \"../theme\";\nimport { agreementTextHtml, coerceForcedIntentOs } from \"../uiHelpers\";\nimport { FlowErrorBoundary } from \"./FlowErrorBoundary\";\nimport { PoweredBySnapKyc } from \"./PoweredBySnapKyc\";\nimport { TxnSuccessPanel } from \"./TxnSuccessPanel\";\n\nconst defaultQrSize = 376;\n\nfunction emitEvt(onFlowEvent: SnapConsentHandoffPublicProps[\"onFlowEvent\"], evt: FlowEvent) {\n try {\n onFlowEvent?.(evt);\n // eslint-disable-next-line no-empty\n } catch {\n //\n }\n}\n\nexport function SnapConsentHandoffFlow(props: SnapConsentHandoffPublicProps) {\n const {\n integrationToken,\n rpContext,\n agreementId: _agreementIdProp,\n acceptLanguage,\n handoffMode,\n qrRequestBody,\n pollIntervalMs = 1500,\n pollDeadlineMs = 120_000,\n onFlowEvent,\n onSuccess,\n onError,\n onRequestClose,\n displayMode = \"modal\",\n title,\n userAgent,\n theme: themePartial,\n } = props;\n\n const themeCss = useMemo(() => themeToCssProperties(resolveSnapConsentTheme(themePartial)), [themePartial]);\n\n const forcedOs = coerceForcedIntentOs(props);\n\n const flowAbortRef = useRef<AbortController>(new AbortController());\n useEffect(() => {\n flowAbortRef.current.abort();\n flowAbortRef.current = new AbortController();\n\n return () => {\n flowAbortRef.current.abort();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- host remount rotates controller on auth changes\n }, [integrationToken, handoffMode]);\n\n const qrObjectUrlRef = useRef<string | null>(null);\n const sheetRef = useRef<HTMLDivElement>(null);\n\n /** Revoke object URLs on exit */\n useEffect(() => {\n return () => {\n if (qrObjectUrlRef.current) URL.revokeObjectURL(qrObjectUrlRef.current);\n qrObjectUrlRef.current = null;\n };\n }, []);\n\n const signal = (): AbortSignal => flowAbortRef.current.signal;\n\n const [fatalError, setFatalError] = useState<string | null>(null);\n const [agreementEnvelope, setAgreementEnvelope] = useState<AgreementEnvelope | null>(null);\n const [loadingAgreement, setLoadingAgreement] = useState(true);\n const [busyConsent, setBusyConsent] = useState(false);\n\n const [txnIdDisplay, setTxnIdDisplay] = useState<string | null>(null);\n const [intentUrl, setIntentUrl] = useState<string | null>(null);\n\n /** When intent flow cannot infer OS */\n const [intentNeedsPick, setIntentNeedsPick] = useState(false);\n\n const [qrObjectUrl, setQrObjectUrl] = useState<string | null>(null);\n\n /** status lines */\n const [busyPolling, setBusyPolling] = useState(false);\n\n const [completed, setCompleted] = useState<CompletionResult | null>(null);\n\n /** When host omits `onRequestClose`, hide the UI after user dismisses (Done / Cancel / close). */\n const [flowDismissed, setFlowDismissed] = useState(false);\n\n useEffect(() => {\n setFlowDismissed(false);\n }, [integrationToken, handoffMode]);\n\n const selectable = useMemo(() => {\n if (!agreementEnvelope) return [];\n return buildSelectablePurposes(agreementEnvelope.data);\n }, [agreementEnvelope]);\n\n const [selectedPurposesMap, setSelectedPurposesMap] = useState<Record<string, boolean>>({});\n\n useEffect(() => {\n setSelectedPurposesMap((prev) => {\n const next: Record<string, boolean> = {};\n for (const row of selectable) {\n next[row.id] = prev[row.id] ?? false;\n }\n return next;\n });\n }, [selectable]);\n\n const hydrateAgreementHtml = useCallback(\n (data: AgreementEnvelope[\"data\"]) => {\n const html = agreementTextHtml(data, acceptLanguage);\n if (!html) return null;\n return DOMPurify.sanitize(html, { ALLOWED_TAGS: [\"br\"], ALLOWED_ATTR: [] });\n },\n [acceptLanguage],\n );\n\n const agreementHtml = useMemo(() => {\n if (!agreementEnvelope) return null;\n return hydrateAgreementHtml(agreementEnvelope.data);\n }, [agreementEnvelope, hydrateAgreementHtml]);\n\n const revokeQrIfAny = () => {\n if (qrObjectUrlRef.current) URL.revokeObjectURL(qrObjectUrlRef.current);\n qrObjectUrlRef.current = null;\n setQrObjectUrl(null);\n };\n\n const finishWithSuccess = useCallback(\n (raw: TxnStatusResponse, txnIdHint?: string) => {\n const normalized = normalizeTxnStatusPayload(raw);\n\n revokeQrIfAny();\n setIntentUrl(null);\n setIntentNeedsPick(false);\n setTxnIdDisplay(null);\n setBusyPolling(false);\n setBusyConsent(false);\n\n const completion: CompletionResult = {\n txn_id: normalized.txn_id || txnIdHint,\n status: normalized.status,\n raw: normalized,\n };\n\n setCompleted(completion);\n emitEvt(onFlowEvent, { phase: \"completed\", txnId: completion.txn_id });\n\n // Let the success UI paint before host onSuccess handlers (often dispose the modal).\n queueMicrotask(() => {\n onSuccess?.(completion);\n });\n },\n [onFlowEvent, onSuccess],\n );\n\n useEffect(() => {\n if (!completed) return;\n sheetRef.current?.scrollTo({ top: 0, behavior: \"smooth\" });\n }, [completed]);\n\n /** Initial agreement bootstrap */\n useEffect(() => {\n emitEvt(onFlowEvent, { phase: \"agreement-loading\" });\n let cancelled = false;\n\n async function bootstrap() {\n try {\n setLoadingAgreement(true);\n setFatalError(null);\n const env = await getAgreement({\n integrationToken,\n signal: signal(),\n acceptLanguage,\n });\n if (cancelled) return;\n if (env.error) throw new Error(env.error_message ?? env.message ?? \"Agreement fetch error\");\n setAgreementEnvelope(env);\n emitEvt(onFlowEvent, { phase: \"agreement-ready\" });\n } catch (e: unknown) {\n if ((e as DOMException)?.name === \"AbortError\") return;\n const msg = e instanceof Error ? e.message : String(e);\n setFatalError(msg);\n emitEvt(onFlowEvent, { phase: \"failed\", error: e });\n onError?.(e);\n } finally {\n if (!cancelled) setLoadingAgreement(false);\n }\n }\n\n void bootstrap();\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [integrationToken, acceptLanguage]);\n\n async function finalizeIntentAndPoll(currentTxnId: string, platform: IntentOs): Promise<void> {\n revokeQrIfAny();\n emitEvt(onFlowEvent, {\n phase: \"handoff-loading\",\n txnId: currentTxnId,\n meta: { kind: \"ambiguous-choice\", chosen: platform },\n });\n try {\n setIntentNeedsPick(false);\n setFatalError(null);\n\n const res = await createIntent({\n integrationToken,\n txnId: currentTxnId,\n platform,\n signal: signal(),\n });\n\n setIntentUrl(res.intent_url);\n\n emitEvt(onFlowEvent, {\n phase: \"handoff-ready\",\n txnId: currentTxnId,\n meta: { kind: \"ambiguous-choice\", chosen: platform },\n });\n\n emitEvt(onFlowEvent, { phase: \"polling\", txnId: currentTxnId });\n setBusyPolling(true);\n const raw = await pollTxnUntilTerminal({\n integrationToken,\n txnId: currentTxnId,\n signal: signal(),\n pollIntervalMs,\n deadlineMs: pollDeadlineMs,\n });\n finishWithSuccess(raw, currentTxnId);\n } catch (e: unknown) {\n setBusyPolling(false);\n if ((e as DOMException)?.name === \"AbortError\") return;\n const msg = e instanceof Error ? e.message : String(e);\n setFatalError(msg);\n emitEvt(onFlowEvent, { phase: \"failed\", txnId: currentTxnId, error: e });\n onError?.(e);\n }\n }\n\n async function runQrHandoff(currentTxnId: string): Promise<void> {\n emitEvt(onFlowEvent, { phase: \"handoff-loading\", txnId: currentTxnId });\n revokeQrIfAny();\n const blob = await generateQr({\n integrationToken,\n txnId: currentTxnId,\n size: qrRequestBody?.size ?? defaultQrSize,\n signal: signal(),\n });\n const url = URL.createObjectURL(blob);\n qrObjectUrlRef.current = url;\n setQrObjectUrl(url);\n emitEvt(onFlowEvent, { phase: \"handoff-ready\", txnId: currentTxnId });\n }\n\n async function runIntentHandoff(currentTxnId: string, platform: IntentOs): Promise<void> {\n emitEvt(onFlowEvent, {\n phase: \"handoff-loading\",\n txnId: currentTxnId,\n meta: forcedOs ? { kind: \"forced\", platform } : { kind: \"resolved\", platform },\n });\n\n const res = await createIntent({\n integrationToken,\n txnId: currentTxnId,\n platform,\n signal: signal(),\n });\n\n setIntentUrl(res.intent_url);\n\n emitEvt(onFlowEvent, {\n phase: \"handoff-ready\",\n txnId: currentTxnId,\n meta: forcedOs ? { kind: \"forced\", platform } : { kind: \"resolved\", platform },\n });\n }\n\n /** Primary consent acknowledgement */\n const handleContinueConsent = async () => {\n if (!agreementEnvelope) return;\n\n emitEvt(onFlowEvent, { phase: \"txn-initiating\" });\n revokeQrIfAny();\n setIntentUrl(null);\n setIntentNeedsPick(false);\n setCompleted(null);\n\n try {\n setBusyConsent(true);\n setFatalError(null);\n\n const purposeIds = selectable.filter((item) => selectedPurposesMap[item.id]).map((item) => item.id);\n\n if (!purposeIds.length) throw new Error(\"Please select at least one purpose.\");\n\n const txn = await initiateTxn({\n integrationToken,\n body: {\n purpose_ids: purposeIds,\n rp_context: {\n ref_id: rpContext.reference_id,\n },\n },\n signal: signal(),\n });\n\n setTxnIdDisplay(txn.txn_id);\n emitEvt(onFlowEvent, { phase: \"txn-created\", txnId: txn.txn_id });\n\n if (handoffMode === \"qr\") {\n await runQrHandoff(txn.txn_id);\n emitEvt(onFlowEvent, { phase: \"polling\", txnId: txn.txn_id });\n setBusyPolling(true);\n try {\n const raw = await pollTxnUntilTerminal({\n integrationToken,\n txnId: txn.txn_id,\n signal: signal(),\n pollIntervalMs,\n deadlineMs: pollDeadlineMs,\n });\n finishWithSuccess(raw, txn.txn_id);\n } catch (pollErr: unknown) {\n setBusyPolling(false);\n throw pollErr;\n }\n } else {\n if (forcedOs) {\n setIntentNeedsPick(false);\n await runIntentHandoff(txn.txn_id, forcedOs);\n\n emitEvt(onFlowEvent, { phase: \"polling\", txnId: txn.txn_id });\n setBusyPolling(true);\n try {\n const raw = await pollTxnUntilTerminal({\n integrationToken,\n txnId: txn.txn_id,\n signal: signal(),\n pollIntervalMs,\n deadlineMs: pollDeadlineMs,\n });\n finishWithSuccess(raw, txn.txn_id);\n } catch (pollErr: unknown) {\n setBusyPolling(false);\n throw pollErr;\n }\n } else {\n const inferred = detectIntentPlatform(userAgent);\n if (inferred.kind === \"resolved\") {\n setIntentNeedsPick(false);\n\n emitEvt(onFlowEvent, {\n phase: \"txn-created\",\n txnId: txn.txn_id,\n meta: { kind: \"resolved\", platform: inferred.platform },\n });\n\n await runIntentHandoff(txn.txn_id, inferred.platform);\n\n emitEvt(onFlowEvent, { phase: \"polling\", txnId: txn.txn_id });\n setBusyPolling(true);\n try {\n const raw = await pollTxnUntilTerminal({\n integrationToken,\n txnId: txn.txn_id,\n signal: signal(),\n pollIntervalMs,\n deadlineMs: pollDeadlineMs,\n });\n finishWithSuccess(raw, txn.txn_id);\n } catch (pollErr: unknown) {\n setBusyPolling(false);\n throw pollErr;\n }\n } else {\n emitEvt(onFlowEvent, {\n phase: \"txn-created\",\n txnId: txn.txn_id,\n meta: { kind: \"ambiguous-choice\" },\n });\n setIntentNeedsPick(true);\n }\n }\n }\n\n setBusyConsent(false);\n } catch (e: unknown) {\n setBusyConsent(false);\n setBusyPolling(false);\n if ((e as DOMException)?.name === \"AbortError\") return;\n const msg = e instanceof Error ? e.message : String(e);\n setFatalError(msg);\n emitEvt(onFlowEvent, { phase: \"failed\", error: e });\n onError?.(e);\n }\n };\n\n const handlePickIntent = (os: IntentOs) => async () => {\n if (!txnIdDisplay) return;\n await finalizeIntentAndPoll(txnIdDisplay, os);\n };\n\n /** Copy deeplink clipboard */\n const handleCopyIntent = async () => {\n try {\n if (!intentUrl) return;\n await navigator.clipboard.writeText(intentUrl);\n // eslint-disable-next-line no-empty\n } catch {\n //\n }\n };\n\n /** Close / Cancel / Done — aborts in-flight work and notifies host. */\n const handleClosePressed = () => {\n emitEvt(onFlowEvent, { phase: \"cancelled\" });\n flowAbortRef.current.abort();\n const close = onRequestClose;\n queueMicrotask(() => {\n close?.();\n if (close === undefined) {\n setFlowDismissed(true);\n }\n });\n };\n\n /** Render */\n const shellClass = displayMode === \"modal\" ? \"snap-consent-handoff_overlay\" : \"snap-consent-handoff_inline\";\n const headingFallback = agreementEnvelope?.data.name ?? \"Consent\";\n\n if (flowDismissed) {\n return null;\n }\n\n return (\n <div className=\"snap-consent-handoff\" style={themeCss}>\n <div className={shellClass} data-testid=\"snap-consent-handoff-shell\">\n <div className=\"snap-consent-handoff_body\">\n <div\n ref={sheetRef}\n className=\"snap-consent-handoff_sheet\"\n role=\"dialog\"\n aria-modal={displayMode === \"modal\"}\n >\n <header className=\"snap-consent-handoff_hdr\">\n <h2 className=\"snap-consent-handoff_title\">{title ?? headingFallback}</h2>\n {displayMode === \"modal\" ? (\n <button\n type=\"button\"\n className=\"snap-consent-handoff_btnIcon\"\n aria-label=\"Close\"\n data-testid=\"snap-consent-handoff-close\"\n onClick={handleClosePressed}\n >\n ×\n </button>\n ) : null}\n </header>\n\n {completed ? (\n <div className=\"snap-consent-handoff_done\" data-testid=\"snap-consent-handoff-done\">\n <FlowErrorBoundary>\n <TxnSuccessPanel status={normalizeTxnStatusPayload(completed.raw)} />\n </FlowErrorBoundary>\n\n <div className=\"snap-consent-handoff_actions\">\n <button\n type=\"button\"\n className=\"snap-consent-handoff_btnPrimary\"\n data-testid=\"snap-consent-handoff-done-button\"\n onClick={handleClosePressed}\n >\n Done\n </button>\n </div>\n </div>\n ) : null}\n\n {!completed && fatalError ? <div className=\"snap-consent-handoff_err\">{fatalError}</div> : null}\n\n {!completed && loadingAgreement ? <div aria-busy>Loading agreement…</div> : null}\n\n {!completed && agreementEnvelope ? (\n <div aria-live=\"polite\">\n {agreementHtml ? (\n // eslint-disable-next-line react/no-danger -- sanitized via DOMPurify\n <article className=\"snap-consent-handoff_notice\" dangerouslySetInnerHTML={{ __html: agreementHtml }} />\n ) : null}\n\n {!txnIdDisplay ? (\n <section>\n <h3 className=\"snap-consent-handoff_headingSm\">Consent Required</h3>\n <div className=\"snap-consent-handoff_list\">\n {selectable.map((row) => {\n const rowDisabled = busyConsent || busyPolling || loadingAgreement;\n return (\n <label\n key={row.id}\n className={\n [\n \"snap-consent-handoff_row\",\n selectedPurposesMap[row.id] ? \"snap-consent-handoff_row--selected\" : \"\",\n rowDisabled ? \"snap-consent-handoff_row--disabled\" : \"\",\n ]\n .filter(Boolean)\n .join(\" \")\n }\n htmlFor={`purpose-${row.id}`}\n >\n <input\n id={`purpose-${row.id}`}\n type=\"checkbox\"\n checked={Boolean(selectedPurposesMap[row.id])}\n disabled={busyConsent || busyPolling || loadingAgreement}\n onChange={(e) =>\n setSelectedPurposesMap((prev) => ({\n ...prev,\n [row.id]: e.target.checked,\n }))\n }\n />\n <div style={{ fontWeight: 600 }}>{row.label}</div>\n </label>\n );\n })}\n </div>\n\n <div className=\"snap-consent-handoff_actions snap-consent-handoff_actions--split\">\n <button\n type=\"button\"\n className=\"snap-consent-handoff_btnSecondary\"\n data-testid=\"snap-consent-handoff-cancel\"\n disabled={busyConsent || busyPolling || loadingAgreement}\n onClick={handleClosePressed}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"snap-consent-handoff_btnPrimary\"\n data-testid=\"snap-consent-handoff-submit\"\n disabled={busyConsent || busyPolling || loadingAgreement}\n onClick={() => void handleContinueConsent()}\n >\n I Agree\n </button>\n </div>\n </section>\n ) : null}\n\n {txnIdDisplay ? (\n <section style={{ marginTop: \"14px\" }} data-testid=\"snap-consent-handoff-active-txn\">\n {handoffMode === \"intent\" ? (\n <>\n {intentNeedsPick ? (\n <div className=\"snap-consent-handoff_intents\" role=\"group\" aria-label=\"Choose OS\">\n <p className=\"snap-consent-handoff_muted\">\n Automatic platform detection couldn’t confidently choose Android vs iOS. Pick yours:\n </p>\n <button\n type=\"button\"\n className=\"snap-consent-handoff_btnPrimary\"\n onClick={() => void handlePickIntent(\"android\")()}\n disabled={busyConsent || busyPolling}\n >\n Continue with Android\n </button>\n <button\n type=\"button\"\n className=\"snap-consent-handoff_btnPrimary\"\n onClick={() => void handlePickIntent(\"ios\")()}\n disabled={busyConsent || busyPolling}\n >\n Continue with iPhone / iPad\n </button>\n </div>\n ) : intentUrl ? (\n <div>\n <textarea readOnly value={intentUrl} className=\"snap-consent-handoff_codeBox\" />\n <div className=\"snap-consent-handoff_actions\">\n <button type=\"button\" className=\"snap-consent-handoff_btnSecondary\" onClick={() => void handleCopyIntent()}>\n Copy deeplink\n </button>\n {/* eslint-disable-next-line react/jsx-no-target-blank -- external deeplink */}\n <a className=\"snap-consent-handoff_btnSecondary\" href={intentUrl} style={{ textDecoration: \"none\" }}>\n Open app\n </a>\n </div>\n <p className=\"snap-consent-handoff_muted\" style={{ fontSize: \"12px\" }}>\n Some in-app browsers block custom-url schemes — use Safari/Chrome where possible.\n </p>\n\n {(busyConsent || busyPolling) && intentUrl ? (\n <div className=\"snap-consent-handoff_notice\" aria-live=\"polite\">\n {busyPolling ? \"Polling transaction status...\" : \"\"}\n </div>\n ) : null}\n </div>\n ) : busyConsent ? (\n <div>Preparing app link...</div>\n ) : busyPolling ? (\n <div>Waiting on device handshake...</div>\n ) : null}\n </>\n ) : null}\n\n {handoffMode === \"qr\" ? (\n qrObjectUrl ? (\n <figure className=\"snap-consent-handoff_qr\" data-testid=\"snap-consent-handoff-qr\">\n <img alt=\"QR code\" src={qrObjectUrl} />\n <figcaption className=\"snap-consent-handoff_muted\">\n Scan with your authorised app to proceed.{busyPolling ? \" Listening for confirmation...\" : null}\n </figcaption>\n </figure>\n ) : busyConsent ? (\n <div>Generating QR...</div>\n ) : busyPolling ? (\n <div>Waiting for scanned confirmation...</div>\n ) : null\n ) : null}\n </section>\n ) : null}\n </div>\n ) : null}\n </div>\n <PoweredBySnapKyc />\n </div>\n </div>\n </div>\n );\n}\n","export type IntentOs = \"android\" | \"ios\";\n\nexport type IntentDetection =\n | { kind: \"resolved\"; platform: IntentOs }\n | { kind: \"ambiguous\"; reason?: string };\n\n/**\n * Lightweight UA heuristic for requesting android vs ios deeplinks from the backend.\n */\nexport function detectIntentPlatform(userAgent?: string): IntentDetection {\n const uaRaw = userAgent ?? (typeof navigator !== \"undefined\" ? navigator.userAgent : \"\");\n const ua = uaRaw.toLowerCase();\n\n if (!ua) return { kind: \"ambiguous\", reason: \"missing-user-agent\" };\n\n const isAndroid = /android/.test(ua);\n const touchPoints =\n typeof navigator !== \"undefined\" ? Number(navigator.maxTouchPoints ?? 0) : 0;\n const isIOSDevice = /iphone|ipad|ipod/.test(ua) || (ua.includes(\"macintosh\") && touchPoints > 1);\n\n if (isAndroid && !isIOSDevice) return { kind: \"resolved\", platform: \"android\" };\n if (!isAndroid && isIOSDevice) return { kind: \"resolved\", platform: \"ios\" };\n\n return { kind: \"ambiguous\", reason: \"ambiguous-or-non-mobile\" };\n}\n","/**\n * API origin bundled with the SDK. Replace at publish-time (staging/prod) via your build pipeline\n * or bump this constant per release artefact — hosts cannot override `baseUrl` at runtime.\n */\nexport const API_ORIGIN = \"https://staging-api.snapkyc.com\";\n\nexport const paths = {\n agreement: () => `${API_ORIGIN}/api/integrations/agreement`,\n txnInitiate: () => `${API_ORIGIN}/api/integrations/transactions/initiate`,\n generateQr: () => `${API_ORIGIN}/api/integrations/generate-qr`,\n generateIntent: (platform: \"android\" | \"ios\") =>\n `${API_ORIGIN}/api/integrations/generate-intent?platform=${platform}`,\n txnStatus: (txnId: string) =>\n `${API_ORIGIN}/api/integrations/transactions/${encodeURIComponent(txnId)}/status`,\n};\n","export type ApiEnvelope<T> = {\n request_id: string;\n status_code: number;\n message: string;\n data: T | null;\n error: boolean;\n error_message: unknown;\n};\n\nexport function unwrapEnvelope<T>(envelope: ApiEnvelope<T>, fallbackMessage = \"API error\"): T {\n if (envelope.error || envelope.data == null) {\n const detail =\n typeof envelope.error_message === \"string\"\n ? envelope.error_message\n : envelope.error_message != null\n ? JSON.stringify(envelope.error_message)\n : envelope.message;\n throw new Error(detail || fallbackMessage);\n }\n return envelope.data;\n}\n","export function authorizationHeaders(integrationToken: string): Record<string, string> {\n return {\n Authorization: `Token ${integrationToken}`,\n };\n}\n","import { authorizationHeaders } from \"./auth\";\nimport { SnapSdkHttpError as HttpErr } from \"./errors\";\n\nasync function assertOk(res: Response, url: string): Promise<void> {\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n const err = new HttpErr(url, res.status, `HTTP ${res.status} calling ${url}`, text);\n throw err;\n }\n}\n\nexport async function fetchJson<T>(options: {\n url: string;\n integrationToken: string;\n method?: \"GET\" | \"POST\";\n body?: unknown;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n}): Promise<T> {\n const { url, integrationToken, method = \"GET\", body, signal, headers = {} } = options;\n\n const res = await fetch(url, {\n method,\n signal,\n headers: {\n ...authorizationHeaders(integrationToken),\n Accept: \"application/json\",\n ...(body !== undefined ? { \"Content-Type\": \"application/json\" } : {}),\n ...headers,\n },\n body: body === undefined ? undefined : JSON.stringify(body),\n }).catch((e: unknown) => {\n throw e;\n });\n\n await assertOk(res, url);\n\n return (await res.json()) as T;\n}\n\nexport async function fetchBlob(options: {\n url: string;\n integrationToken: string;\n method?: \"POST\";\n body?: unknown;\n signal?: AbortSignal;\n}): Promise<Blob> {\n const { url, integrationToken, method = \"POST\", body, signal } = options;\n\n const res = await fetch(url, {\n method,\n signal,\n headers: {\n ...authorizationHeaders(integrationToken),\n Accept: \"image/png,*/*\",\n ...(body !== undefined ? { \"Content-Type\": \"application/json\" } : {}),\n },\n body: body === undefined ? undefined : JSON.stringify(body),\n }).catch((e: unknown) => {\n throw e;\n });\n\n await assertOk(res, url);\n\n return await res.blob();\n}\n\nexport { SnapSdkHttpError } from \"./errors\";\n","import { paths } from \"../config\";\nimport { unwrapEnvelope, type ApiEnvelope } from \"./envelope\";\nimport { normalizeTxnStatusPayload } from \"./normalizeStatus\";\nimport { fetchBlob, fetchJson } from \"./client\";\nimport type {\n AgreementEnvelope,\n InitiateTxnBody,\n InitiateTxnData,\n InitiateTxnResponse,\n IntentResponseBody,\n TxnStatusData,\n TxnStatusResponse,\n} from \"./types\";\n\nexport async function getAgreement(options: {\n integrationToken: string;\n signal?: AbortSignal;\n acceptLanguage?: string;\n}): Promise<AgreementEnvelope> {\n return fetchJson<AgreementEnvelope>({\n url: paths.agreement(),\n integrationToken: options.integrationToken,\n method: \"GET\",\n signal: options.signal,\n headers: options.acceptLanguage\n ? {\n \"Accept-Language\": options.acceptLanguage,\n }\n : {},\n });\n}\n\nexport async function initiateTxn(options: {\n integrationToken: string;\n body: InitiateTxnBody;\n signal?: AbortSignal;\n}): Promise<InitiateTxnResponse> {\n const envelope = await fetchJson<ApiEnvelope<InitiateTxnData>>({\n url: paths.txnInitiate(),\n integrationToken: options.integrationToken,\n method: \"POST\",\n body: options.body,\n signal: options.signal,\n });\n return unwrapEnvelope(envelope, \"Transaction initiate failed\");\n}\n\nexport async function generateQr(options: {\n integrationToken: string;\n txnId: string;\n size?: number;\n signal?: AbortSignal;\n}): Promise<Blob> {\n return fetchBlob({\n url: paths.generateQr(),\n integrationToken: options.integrationToken,\n body: {\n txn_id: options.txnId,\n size: options.size ?? 376,\n },\n signal: options.signal,\n });\n}\n\nexport async function createIntent(options: {\n integrationToken: string;\n txnId: string;\n platform: \"android\" | \"ios\";\n signal?: AbortSignal;\n}): Promise<IntentResponseBody> {\n const envelope = await fetchJson<ApiEnvelope<IntentResponseBody>>({\n url: paths.generateIntent(options.platform),\n integrationToken: options.integrationToken,\n method: \"POST\",\n body: { txn_id: options.txnId },\n signal: options.signal,\n });\n return unwrapEnvelope(envelope, \"Intent generation failed\");\n}\n\nexport async function pollTxnStatus(options: {\n integrationToken: string;\n txnId: string;\n signal?: AbortSignal;\n}): Promise<TxnStatusResponse> {\n const envelope = await fetchJson<ApiEnvelope<TxnStatusData>>({\n url: paths.txnStatus(options.txnId),\n integrationToken: options.integrationToken,\n method: \"GET\",\n signal: options.signal,\n });\n return normalizeTxnStatusPayload(unwrapEnvelope(envelope, \"Transaction status fetch failed\"));\n}\n","import { hasDisplayableDemographics } from \"../demographicDisplay\";\nimport { pollTxnStatus } from \"./endpoints\";\nimport type { TxnStatusResponse } from \"./types\";\n\nconst successStatusesLower = new Set([\"success\", \"completed\", \"complete\"]);\n\nconst pendingHintsLower = new Set([\n \"pending\",\n \"in_progress\",\n \"processing\",\n \"initiated\",\n \"waiting\",\n \"started\",\n]);\n\nconst failureStatusesLower = new Set([\"failed\", \"failure\", \"error\", \"rejected\", \"expired\"]);\n\n/** After SUCCESS, keep polling briefly so late-arriving demographic_data can be captured. */\nconst DEMOGRAPHIC_WAIT_AFTER_SUCCESS_MS = 15_000;\n\nfunction normalizeStatus(raw: unknown): string {\n return typeof raw === \"string\" ? raw.trim().toLowerCase() : \"\";\n}\n\n/** Anything that is neither a known success nor a known failure is treated as pending and keeps polling until timeout. */\nexport function classifyTxnStatus(raw: unknown): \"success\" | \"failure\" | \"pending\" {\n const s = normalizeStatus(raw);\n if (!s) return \"pending\";\n if (successStatusesLower.has(s)) return \"success\";\n if (failureStatusesLower.has(s)) return \"failure\";\n if (pendingHintsLower.has(s)) return \"pending\";\n return \"pending\";\n}\n\nasync function delay(ms: number, signal: AbortSignal): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n if (signal.aborted) {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n return;\n }\n const timer = globalThis.setTimeout(() => resolve(), ms);\n signal.addEventListener(\n \"abort\",\n () => {\n globalThis.clearTimeout(timer);\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n },\n { once: true },\n );\n });\n}\n\nexport async function pollTxnUntilTerminal(options: {\n integrationToken: string;\n txnId: string;\n signal: AbortSignal;\n pollIntervalMs: number;\n deadlineMs: number;\n}): Promise<TxnStatusResponse> {\n const start = Date.now();\n let successAt: number | null = null;\n let lastSuccess: TxnStatusResponse | null = null;\n\n while (true) {\n if (options.signal.aborted) {\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n\n if (Date.now() - start > options.deadlineMs) {\n if (lastSuccess) return lastSuccess;\n throw new Error(`Txn polling timed out after ${options.deadlineMs}ms`);\n }\n\n const latest = await pollTxnStatus({\n integrationToken: options.integrationToken,\n txnId: options.txnId,\n signal: options.signal,\n });\n\n const bucket = classifyTxnStatus(latest.status);\n\n if (bucket === \"success\") {\n lastSuccess = latest;\n if (successAt == null) successAt = Date.now();\n\n if (hasDisplayableDemographics(latest)) return latest;\n\n if (Date.now() - successAt >= DEMOGRAPHIC_WAIT_AFTER_SUCCESS_MS) return latest;\n } else {\n successAt = null;\n lastSuccess = null;\n\n if (bucket === \"failure\") {\n throw new Error(`Txn failed with terminal status '${String(latest.status)}'`);\n }\n }\n\n await delay(options.pollIntervalMs, options.signal);\n }\n}\n","import type { AgreementEnvelope } from \"./http/types\";\nimport type { SelectablePurpose } from \"./flowTypes\";\n\n/** Purposes selectable for `POST …/transactions/initiate` (`purpose_ids`). */\nexport function buildSelectablePurposes(data: AgreementEnvelope[\"data\"]): SelectablePurpose[] {\n return (data.purposes ?? []).map((purpose) => ({\n id: purpose.id,\n label: purpose.description?.en ?? purpose.name,\n }));\n}\n","import type { IntentOs } from \"./device/detectIntentPlatform\";\nimport type { AgreementEnvelope } from \"./http/types\";\n\nexport function agreementTextHtml(\n data: AgreementEnvelope[\"data\"],\n acceptLanguage?: string,\n): string | null {\n const texts = data.agreement_text ?? {};\n const preferredLang = acceptLanguage?.split(\",\")[0]?.trim();\n const key =\n preferredLang && texts[preferredLang]\n ? preferredLang\n : texts.en\n ? \"en\"\n : Object.keys(texts)[0];\n\n const raw = key ? texts[key] : \"\";\n const text = typeof raw === \"string\" ? raw.trim() : \"\";\n if (!text) return null;\n\n // Treat as plain-ish text; callers should still sanitize HTML with DOMPurify.\n const escaped = text\n .replaceAll(\"&\", \"&\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\");\n\n return escaped.replace(/\\n/g, \"<br />\");\n}\n\nexport function coerceForcedIntentOs(props: {\n _dangerouslyForceIntentPlatform?: IntentOs;\n dangerousForceIntentPlatform?: IntentOs;\n intentPlatformOverride?: IntentOs;\n}): IntentOs | undefined {\n return props._dangerouslyForceIntentPlatform ?? props.dangerousForceIntentPlatform ?? props.intentPlatformOverride;\n}\n","import { Component, type ErrorInfo, type ReactNode } from \"react\";\n\ntype Props = {\n children: ReactNode;\n fallback?: ReactNode;\n};\n\ntype State = {\n error: Error | null;\n};\n\nexport class FlowErrorBoundary extends Component<Props, State> {\n state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo): void {\n // eslint-disable-next-line no-console\n console.error(\"[snap-consent-handoff] render error\", error, info.componentStack);\n }\n\n render(): ReactNode {\n if (this.state.error) {\n return (\n this.props.fallback ?? (\n <div className=\"snap-consent-handoff_err\" role=\"alert\">\n Something went wrong displaying the verification result. Please check the browser console or use the\n data returned in <code>onSuccess</code>.\n </div>\n )\n );\n }\n\n return this.props.children;\n }\n}\n","import snapkycLogo from \"../assets/snapkycog.svg\";\n\nexport function PoweredBySnapKyc() {\n return (\n <footer className=\"snap-consent-handoff_powered\" data-testid=\"snap-consent-handoff-powered\">\n <span className=\"snap-consent-handoff_poweredLabel\">Powered by</span>\n <img className=\"snap-consent-handoff_poweredLogo\" src={snapkycLogo} alt=\"snapkyc\" />\n </footer>\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\n\nimport {\n type DemographicAccordionSection,\n demographicAccordionSections,\n extractDemographicData,\n formatDisplayValue,\n formatPurposeLabel,\n residentImageDataUrl,\n} from \"../demographicDisplay\";\nimport { normalizeTxnStatusPayload } from \"../http/normalizeStatus\";\nimport type { TxnStatusResponse } from \"../http/types\";\n\nfunction SuccessShieldIcon() {\n return (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden>\n <path\n d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"m9 12 2 2 4-4\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction SmallCheckIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden>\n <path\n d=\"M3.5 8.2 6.3 11l6.2-6.2\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction SectionListIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden>\n <path d=\"M8 6h13M8 12h13M8 18h13\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n <path\n d=\"M3.5 6l1 1-1 1M3.5 12l1 1-1 1M3.5 18l1 1-1 1\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction SectionUserIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden>\n <path\n d=\"M12 11a3 3 0 1 0-3-3 3 3 0 0 0 3 3zm0 2c-3.3 0-6 1.6-6 3.5V19h12v-2.5C18 14.6 15.3 13 12 13z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n}\n\nfunction AccordionChevron({ open }: { open: boolean }) {\n return (\n <span\n className={\n open\n ? \"snap-consent-handoff_accordionChevron snap-consent-handoff_accordionChevron--open\"\n : \"snap-consent-handoff_accordionChevron\"\n }\n aria-hidden\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 9l6 6 6-6\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </span>\n );\n}\n\nexport function TxnSuccessPanel({ status }: { status: TxnStatusResponse | null | undefined }) {\n const normalized = useMemo(() => normalizeTxnStatusPayload(status), [status]);\n\n const demographics = useMemo(() => extractDemographicData(normalized), [normalized]);\n const photoUrl = demographics ? residentImageDataUrl(demographics) : null;\n const photoOmitted = Boolean(\n demographics &&\n typeof demographics.resident_image === \"string\" &&\n demographics.resident_image.trim().length > 0 &&\n !photoUrl,\n );\n\n const accordionSections = useMemo(() => {\n if (!demographics) return [];\n return demographicAccordionSections(demographics, {\n includePhoto: Boolean(photoUrl || photoOmitted),\n });\n }, [demographics, photoUrl, photoOmitted]);\n\n const defaultOpenId = useMemo(() => {\n const personal = accordionSections.find((s) => s.id === \"personal\");\n return personal?.id ?? accordionSections[0]?.id ?? \"\";\n }, [accordionSections]);\n\n const [openAccordionId, setOpenAccordionId] = useState(defaultOpenId);\n\n useEffect(() => {\n setOpenAccordionId(defaultOpenId);\n }, [defaultOpenId]);\n\n const purposes = Array.isArray(normalized.purposes) ? normalized.purposes : [];\n\n const hasSummaryPayload = Boolean(normalized.txn_id || normalized.status);\n\n if (!hasSummaryPayload) {\n return (\n <p className=\"snap-consent-handoff_muted\" style={{ marginTop: \"12px\" }}>\n Verification completed, but no status payload was available to display.\n </p>\n );\n }\n\n const showDemographicsBlock =\n demographics && (accordionSections.length > 0 || photoOmitted);\n\n function toggleAccordion(id: string) {\n setOpenAccordionId((prev) => (prev === id ? \"\" : id));\n }\n\n return (\n <div className=\"snap-consent-handoff_successBody\" data-testid=\"snap-consent-handoff-success-body\">\n <div className=\"snap-consent-handoff_successHero\">\n <div className=\"snap-consent-handoff_successBadge\">\n <SuccessShieldIcon />\n </div>\n <div className=\"snap-consent-handoff_successHeroText\">\n <h2 className=\"snap-consent-handoff_successTitle\">Verification successful</h2>\n <p className=\"snap-consent-handoff_successSubtitle\">Identity has been verified successfully.</p>\n </div>\n </div>\n\n <section className=\"snap-consent-handoff_statusStrip\" aria-label=\"Transaction summary\">\n <div className=\"snap-consent-handoff_statusStripCol\">\n <p className=\"snap-consent-handoff_statusLabel\">Status</p>\n <p className=\"snap-consent-handoff_statusValue\">\n <span className=\"snap-consent-handoff_statusCheck\" aria-hidden>\n <SmallCheckIcon />\n </span>\n {formatDisplayValue(normalized.status)}\n </p>\n </div>\n <div className=\"snap-consent-handoff_statusStripCol snap-consent-handoff_statusStripCol--end\">\n <p className=\"snap-consent-handoff_statusLabel snap-consent-handoff_statusLabel--neutral\">Completed at</p>\n <p className=\"snap-consent-handoff_statusMeta\">{formatDisplayValue(normalized.created_at)}</p>\n </div>\n </section>\n\n {purposes.length > 0 ? (\n <section className=\"snap-consent-handoff_purposeCard\" data-testid=\"snap-consent-handoff-purposes\">\n <h3 className=\"snap-consent-handoff_successSectionTitle\">\n <span className=\"snap-consent-handoff_successSectionIcon\" aria-hidden>\n <SectionListIcon />\n </span>\n Confirmed purposes\n </h3>\n <ul className=\"snap-consent-handoff_purposeGrid\">\n {purposes.map((purpose, index) => (\n <li key={purpose?.id ?? `purpose-${index}`} className=\"snap-consent-handoff_purposeGridItem\">\n <span className=\"snap-consent-handoff_purposeCheck\" aria-hidden>\n <SmallCheckIcon />\n </span>\n <span>{formatPurposeLabel(purpose?.name)}</span>\n </li>\n ))}\n </ul>\n </section>\n ) : null}\n\n {showDemographicsBlock ? (\n <section className=\"snap-consent-handoff_demographics\" data-testid=\"snap-consent-handoff-demographics\">\n <h3 className=\"snap-consent-handoff_successSectionTitle\">\n <span className=\"snap-consent-handoff_successSectionIcon\" aria-hidden>\n <SectionUserIcon />\n </span>\n Demographic data\n </h3>\n\n <div className=\"snap-consent-handoff_accordionList\">\n {accordionSections.map((section) => (\n <DemographicAccordion\n key={section.id}\n section={section}\n photoUrl={section.includePhoto ? photoUrl : null}\n photoOmitted={section.includePhoto ? photoOmitted : false}\n expanded={openAccordionId === section.id}\n onToggle={() => toggleAccordion(section.id)}\n />\n ))}\n </div>\n </section>\n ) : (\n <p className=\"snap-consent-handoff_muted snap-consent-handoff_successNoDemo\">\n No demographic details were returned for this transaction.\n </p>\n )}\n </div>\n );\n}\n\nfunction DemographicAccordion({\n section,\n photoUrl,\n photoOmitted,\n expanded,\n onToggle,\n}: {\n section: DemographicAccordionSection;\n photoUrl: string | null;\n photoOmitted: boolean;\n expanded: boolean;\n onToggle: () => void;\n}) {\n const panelId = `snap-demo-accordion-${section.id}`;\n const headerId = `snap-demo-accordion-h-${section.id}`;\n\n return (\n <div className=\"snap-consent-handoff_accordion\">\n <button\n type=\"button\"\n id={headerId}\n className=\"snap-consent-handoff_accordionHeader\"\n aria-expanded={expanded}\n aria-controls={panelId}\n onClick={onToggle}\n >\n <span className=\"snap-consent-handoff_accordionTitle\">{section.title}</span>\n <AccordionChevron open={expanded} />\n </button>\n <div\n id={panelId}\n role=\"region\"\n aria-labelledby={headerId}\n className={\n expanded\n ? \"snap-consent-handoff_accordionPanel snap-consent-handoff_accordionPanel--open\"\n : \"snap-consent-handoff_accordionPanel\"\n }\n >\n {photoOmitted ? (\n <p className=\"snap-consent-handoff_muted snap-consent-handoff_accordionNote\">\n Photo omitted (too large to preview in the browser).\n </p>\n ) : null}\n <div\n className={\n photoUrl\n ? \"snap-consent-handoff_accordionBody snap-consent-handoff_accordionBody--withPhoto\"\n : \"snap-consent-handoff_accordionBody\"\n }\n >\n {photoUrl ? (\n <div className=\"snap-consent-handoff_accordionPhoto\">\n <img src={photoUrl} alt=\"Resident\" loading=\"lazy\" decoding=\"async\" />\n </div>\n ) : null}\n {section.fields.length > 0 ? (\n <dl className=\"snap-consent-handoff_successFields\">\n {section.fields.map((row) => (\n <div key={row.key} className=\"snap-consent-handoff_successField\">\n <dt>{row.label}</dt>\n <dd>{row.value}</dd>\n </div>\n ))}\n </dl>\n ) : photoUrl || photoOmitted ? null : (\n <p className=\"snap-consent-handoff_muted\">No fields in this category.</p>\n )}\n </div>\n </div>\n </div>\n );\n}\n","import { StrictMode } from \"react\";\nimport { createRoot } from \"react-dom/client\";\n\nimport type { SnapConsentHandoffPublicProps } from \"../flowTypes\";\n\nimport { SnapConsentHandoffFlow } from \"./SnapConsentHandoffFlow\";\n\nexport type OpenSnapConsentHandoffOptions = Omit<\n SnapConsentHandoffPublicProps,\n \"displayMode\" | \"onRequestClose\"\n> &\n Partial<Pick<SnapConsentHandoffPublicProps, \"displayMode\">> & {\n /**\n * Render in StrictMode — mostly useful during development.\n * Default false to avoid duplicated effects/timeouts surprises in overlays.\n */\n strict?: boolean;\n };\n\n/**\n * Opens a modal consent + handoff flow mounted on `document.body`.\n *\n * Important: callers should keep the returned `{ dispose }` and invoke it when navigating away so\n * polling aborts cleanly and blob/object URLs revoke via component unmount.\n */\nexport function openSnapConsentHandoffFlow(options: OpenSnapConsentHandoffOptions): {\n dispose(): void;\n} {\n if (typeof document === \"undefined\") {\n throw new Error(\"openSnapConsentHandoffFlow requires a browser environment\");\n }\n\n const { strict = false, displayMode = \"modal\", ...flowProps } = options;\n\n const mount = document.createElement(\"div\");\n mount.setAttribute(\"data-snap-consent-handoff-host\", \"\");\n\n const root = createRoot(mount);\n document.body.appendChild(mount);\n\n let disposed = false;\n\n function dispose(): void {\n if (disposed) return;\n disposed = true;\n try {\n root.unmount();\n } finally {\n mount.remove();\n }\n }\n\n const element = (\n <SnapConsentHandoffFlow {...flowProps} displayMode={displayMode} onRequestClose={() => dispose()} />\n );\n\n try {\n root.render(strict ? <StrictMode>{element}</StrictMode> : element);\n } catch (e: unknown) {\n dispose();\n throw e instanceof Error ? e : new Error(String(e));\n }\n\n return { dispose };\n}\n\n/**\n * Deprecated alias kept for docs that referenced a QR-specific opener name.\n */\nexport const openSnapConsentQrFlow = openSnapConsentHandoffFlow;\n"],"mappings":"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","names":["useEffect","useMemo","useState","jsx","jsxs","jsx","jsxs","jsx","jsxs","useMemo","useEffect","useState","jsx"]}
|