From 1609d24a81629949d2c7da597c255eb137e0de02 Mon Sep 17 00:00:00 2001 From: dtroupe Date: Fri, 27 Mar 2026 12:33:58 -0700 Subject: [PATCH 1/2] sync financekit --- example/screens/SyncFinanceKitScreen.tsx | 243 +++++++++++++++++- ios/src/ReactNativePlaidLinkSdkModule.swift | 73 ++++++ src/ReactNativePlaidLinkSdk.types.ts | 198 ++++++++------ src/ReactNativePlaidLinkSdkModule.ts | 14 +- .../ReactNativePlaidLinkSdkModule.ts | 2 +- .../createPlaidHeadlessSession.test.ts | 6 +- src/__tests__/createPlaidLayerSession.test.ts | 14 +- src/__tests__/createPlaidLinkSession.test.ts | 14 +- src/__tests__/listener-lifecycle.test.ts | 8 +- src/__tests__/types.test.ts | 90 ++++++- src/index.ts | 40 ++- 11 files changed, 577 insertions(+), 125 deletions(-) diff --git a/example/screens/SyncFinanceKitScreen.tsx b/example/screens/SyncFinanceKitScreen.tsx index d03c57b8..c23b917e 100644 --- a/example/screens/SyncFinanceKitScreen.tsx +++ b/example/screens/SyncFinanceKitScreen.tsx @@ -1,11 +1,246 @@ -import { SafeAreaView, Text, Button } from "react-native"; +import { useState } from "react"; +import { + Button, + SafeAreaView, + ScrollView, + Text, + View, + Switch, + ActivityIndicator, + Platform, + StyleSheet, +} from "react-native"; +import { + syncFinanceKit, + FinanceKitSyncBehavior, +} from "react-native-plaid-link-sdk"; +import ReactNativePlaidLinkSdk from "react-native-plaid-link-sdk"; +import { + ErrorView, + SdkVersionView, + TokenInputView, +} from "../components/components"; import { styles } from "../styles/common"; +import { isValidToken } from "../utils/validation"; + +type Props = { onBack: () => void }; + +export function SyncFinanceKitScreen({ onBack }: Props) { + const [token, setToken] = useState(""); + const [isSyncing, setIsSyncing] = useState(false); + const [requestAuthorizationIfNeeded, setRequestAuthorizationIfNeeded] = + useState(true); + const [syncBehavior] = useState( + FinanceKitSyncBehavior.SIMULATED + ); + const [errorMessage, setErrorMessage] = useState(null); + const [statusMessage, setStatusMessage] = useState(null); + const [statusIsError, setStatusIsError] = useState(false); + + const handleSync = async () => { + if (!token.trim()) { + setErrorMessage("Please enter a link token"); + return; + } + + if (!isValidToken(token)) { + setErrorMessage("Invalid token format"); + return; + } + + if (Platform.OS !== "ios") { + setErrorMessage("FinanceKit is only available on iOS"); + return; + } + + setIsSyncing(true); + setErrorMessage(null); + setStatusMessage(null); + + try { + await syncFinanceKit({ + token: token.trim(), + requestAuthorizationIfNeeded, + syncBehavior, + }); + setStatusMessage("Sync completed successfully"); + setStatusIsError(false); + setIsSyncing(false); + } catch (e: any) { + const message = e.message ?? "Sync failed"; + setStatusMessage(message); + setStatusIsError(true); + setIsSyncing(false); + } + }; + + const canSync = isValidToken(token) && !isSyncing && Platform.OS === "ios"; -export function SyncFinanceKitScreen({ onBack }: { onBack: () => void }) { return ( -