-
Notifications
You must be signed in to change notification settings - Fork 2
✨ app: implement persona web sdk #683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: lifi
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,41 +11,72 @@ import queryClient, { type EmbeddingContext } from "./queryClient"; | |
| import reportError from "./reportError"; | ||
| import { getKYCTokens } from "./server"; | ||
|
|
||
| import type * as PersonaWeb from "persona"; | ||
|
|
||
| export const environment = (__DEV__ || process.env.EXPO_PUBLIC_ENV === "e2e" ? "sandbox" : "production") as Environment; | ||
|
|
||
| export async function startKYC() { | ||
| const { otl: oneTimeLink, inquiryId, sessionToken } = await getKYCTokens("basic", await getRedirectURI()); | ||
|
|
||
| if (Platform.OS === "web") { | ||
| if (await sdk.isInMiniApp()) { | ||
| await sdk.actions.openUrl(oneTimeLink); | ||
| return; | ||
| } | ||
| const embeddingContext = queryClient.getQueryData<EmbeddingContext>(["embedding-context"]); | ||
| if (embeddingContext && !embeddingContext.endsWith("-web")) { | ||
| window.location.replace(oneTimeLink); | ||
| return; | ||
| } | ||
| window.open(oneTimeLink, "_blank", "noopener,noreferrer"); // cspell:ignore noopener noreferrer | ||
| return; | ||
| } | ||
| export const startKYC = ( | ||
| Platform.OS === "web" | ||
| ? () => { | ||
| let activeClient: InstanceType<typeof PersonaWeb.Client> | undefined; | ||
|
|
||
| const { Inquiry } = await import("react-native-persona"); | ||
| Inquiry.fromInquiry(inquiryId) | ||
| .sessionToken(sessionToken) | ||
| .onCanceled(() => { | ||
| queryClient.invalidateQueries({ queryKey: ["kyc", "status"] }).catch(reportError); | ||
| router.replace("/(main)/(home)"); | ||
| }) | ||
| .onComplete(() => { | ||
| queryClient.invalidateQueries({ queryKey: ["kyc", "status"] }).catch(reportError); | ||
| queryClient.setQueryData(["card-upgrade"], 1); | ||
| router.replace("/(main)/(home)"); | ||
| }) | ||
| .onError((error) => reportError(error)) | ||
| .build() | ||
| .start(); | ||
| } | ||
| return async () => { | ||
| const [{ Client }, { inquiryId, sessionToken }] = await Promise.all([ | ||
| import("persona"), | ||
| getKYCTokens("basic", await getRedirectURI()), | ||
| ]); | ||
|
|
||
| activeClient?.destroy(); | ||
|
|
||
| activeClient = new Client({ | ||
| inquiryId, | ||
| sessionToken, | ||
| environment: environment as "production" | "sandbox", // TODO deprecated - use environmentId instead | ||
| // environmentId: "", | ||
| onReady: () => activeClient?.open(), | ||
| onComplete: () => { | ||
| activeClient?.destroy(); | ||
| activeClient = undefined; | ||
| queryClient.invalidateQueries({ queryKey: ["kyc", "status"] }).catch(reportError); | ||
| queryClient.setQueryData(["card-upgrade"], 1); // TODO probably not needed unless the user is upgrading their card | ||
| router.replace("/(main)/(home)"); | ||
| }, | ||
| onCancel: () => { | ||
| activeClient?.destroy(); | ||
| activeClient = undefined; | ||
| queryClient.invalidateQueries({ queryKey: ["kyc", "status"] }).catch(reportError); | ||
| router.replace("/(main)/(home)"); | ||
| }, | ||
| onError: (error) => { | ||
| activeClient?.destroy(); | ||
| activeClient = undefined; | ||
| reportError(error); | ||
| }, | ||
| }); | ||
| }; | ||
|
Comment on lines
+18
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 KYC flow broken for Farcaster mini apps and embedded web contexts The refactored Click to expandPrevious BehaviorThe old implementation at if (Platform.OS === "web") {
if (await sdk.isInMiniApp()) {
await sdk.actions.openUrl(oneTimeLink); // Mini app specific handling
return;
}
const embeddingContext = queryClient.getQueryData<EmbeddingContext>(["embedding-context"]);
if (embeddingContext && !embeddingContext.endsWith("-web")) {
window.location.replace(oneTimeLink); // Embedded context handling
return;
}
window.open(oneTimeLink, "_blank", "noopener,noreferrer");
}New BehaviorThe new implementation uses the Persona Web SDK's Impact
Users in these contexts will likely experience a broken KYC flow where the Persona modal fails to open or displays incorrectly. Was this helpful? React with 👍 or 👎 to provide feedback. |
||
| } | ||
| : () => { | ||
| // eslint-disable-next-line unicorn/consistent-function-scoping | ||
| return async () => { | ||
| const { inquiryId, sessionToken } = await getKYCTokens("basic", await getRedirectURI()); | ||
| const { Inquiry } = await import("react-native-persona"); | ||
| Inquiry.fromInquiry(inquiryId) | ||
| .sessionToken(sessionToken) | ||
| .onCanceled(() => { | ||
| queryClient.invalidateQueries({ queryKey: ["kyc", "status"] }).catch(reportError); | ||
| router.replace("/(main)/(home)"); | ||
| }) | ||
| .onComplete(() => { | ||
| queryClient.invalidateQueries({ queryKey: ["kyc", "status"] }).catch(reportError); | ||
| queryClient.setQueryData(["card-upgrade"], 1); | ||
| router.replace("/(main)/(home)"); | ||
|
Comment on lines
+37
to
+72
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: rg -n --type=ts --type=tsx 'startKYC\s*\(' -A 3 -B 3Repository: exactly/exa Length of output: 82 🏁 Script executed: rg -n 'startKYC\s*\(' -A 3 -B 3Repository: exactly/exa Length of output: 1494 🏁 Script executed: cat src/utils/persona.tsRepository: exactly/exa Length of output: 3642 🏁 Script executed: cat src/utils/useBeginKYC.tsRepository: exactly/exa Length of output: 1258 🏁 Script executed: cat src/components/card/Card.tsx | head -210 | tail -30Repository: exactly/exa Length of output: 848 🏁 Script executed: head -50 src/components/card/Card.tsxRepository: exactly/exa Length of output: 2010 🏁 Script executed: rg -n "card|Card" src/components/card/Card.tsx | head -5Repository: exactly/exa Length of output: 351 🏁 Script executed: rg -n "^export\s+(default\s+)?.*Card|^function Card|^const Card" src/components/card/Card.tsxRepository: exactly/exa Length of output: 90 🏁 Script executed: rg -n "from.*card/Card|import.*Card.*from.*card/Card" --type js --type tsRepository: exactly/exa Length of output: 144 🏁 Script executed: rg -n "GettingStarted|getting-started" --max-count 20Repository: exactly/exa Length of output: 973 🏁 Script executed: cat src/components/home/card-upgrade/VerifyIdentity.tsxRepository: exactly/exa Length of output: 3084 Move The shared utility unconditionally sets 🤖 Prompt for AI Agents |
||
| }) | ||
| .onError((error) => reportError(error)) | ||
| .build() | ||
| .start(); | ||
| }; | ||
| } | ||
| )(); | ||
|
|
||
| async function getRedirectURI() { | ||
| const miniappContext = (await sdk.context) as unknown as undefined | { client: { appUrl?: string } }; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Persona Web SDK npm v5 Expo React Native compatibility environment vs environmentId init options💡 Result:
persona(Web/Embedded Flow) v5 (npm i persona): useenvironmentId(anenv_...token) when constructingnew Persona.Client(...). This is the current, non-deprecated way to choose the Persona API environment. Example shown in the Embedded Flow quickstart. [1]environmentoption: this is the deprecated legacy field; it used string values like"sandbox"/"production"and is documented as “Deprecated. UseenvironmentIdinstead.” [2]Expo / React Native compatibility
is-webview=truein the URL (required for WebView flow). [4]References
[1] Persona Embedded Flow Quickstart (NPM) –
environmentIdinPersona.Clientinit: (docs.withpersona.com)[2] Persona “Parameters” docs –
environmentdeprecated, useenvironmentId: (docs.withpersona.com)[3] Persona React Native Integration Guide (native SDK usage): (docs.withpersona.com)
[4] Persona WebView integration – native SDKs recommended;
is-webview=truerequired: (docs.withpersona.com)Citations:
🏁 Script executed:
Repository: exactly/exa
Length of output: 768
🏁 Script executed:
Repository: exactly/exa
Length of output: 82
🏁 Script executed:
Repository: exactly/exa
Length of output: 82
🏁 Script executed:
Repository: exactly/exa
Length of output: 4274
🏁 Script executed:
Repository: exactly/exa
Length of output: 6081
🏁 Script executed:
Repository: exactly/exa
Length of output: 75
Update Persona v5 initialization: use
environmentIdinstead of deprecatedenvironmentfield.The codebase imports Persona v5 but initializes it using the deprecated
environmentfield ("sandbox"/"production"). Persona v5 requiresenvironmentId(anenv_...token). Updatesrc/utils/persona.tsto passenvironmentIdwhen constructingnew Persona.Client(...)to avoid compatibility failures with v5.🤖 Prompt for AI Agents