Skip to content

Conversation

@zhouxl
Copy link
Collaborator

@zhouxl zhouxl commented Dec 5, 2025

Related Issue

Summary of Changes

Need Regression Testing

  • Yes
  • No

Risk Assessment

  • Low
  • Medium
  • High

Additional Notes

Screenshots (if applicable)

@zhouxl zhouxl linked an issue Dec 5, 2025 that may be closed by this pull request
@github-actions
Copy link

github-actions bot commented Dec 5, 2025

PR Summary

Implemented a comprehensive native bridge for the onboarding workflow in iOS, enabling React Native to interact with native iOS functionality. Added new TurboModule methods for seed phrase generation, account registration, wallet initialization, notification permissions, and screen security. Introduced NativeScreenName enum for routing to native screens from React Native. Updated the root view coordinator to dynamically switch between React Native and native SideContainerView based on profile state. Extended EOA wallet accounts to include parent info and modified asyncCreateWalletAddressFromServer to return transaction IDs for tracking registration.

Changes

File Summary
FRW.xcodeproj/project.pbxproj Added build file references for NativeScreenName.swift and TurboModule+Onboard.swift to the Xcode project configuration for both targets.
FRW/Foundation/Bridge/BridgeModels.swift Renamed AccountTypeType enum cases from eoa/coa to full/hardware to better reflect account types in the bridge models.
FRW/Foundation/Bridge/NativeScreenName.swift New file. Defines NativeScreenName enum with cases for various native screens: deviceBackup, recoveryPhraseRestore, keyStoreRestore, privateKeyRestore, googleDriveRestore, multiRestore, backupOptions, and icloudRestore.
FRW/Foundation/Bridge/RCTNativeFRWBridge.mm Added Objective-C bridge methods for: getCurrentUserUid, launchNativeScreen, getDeviceId, notification permissions, screen security, seed phrase generation, account registration, wallet initialization, Firebase sign-in, mnemonic saving, recoverable profiles, profile switching, and QR code sharing.
FRW/Foundation/Bridge/RNBridgeError.swift Added new error cases: mnemonicGenerationFailed, mnemonicSaveFailed, keyGenerationFailed, invalidMnemonic, accountCreationFailed, and walletInitializationFailed.
FRW/Foundation/Bridge/TurboModule+Onboard.swift New file. Implements onboarding-related TurboModule methods: generateSeedPhrase creates HD wallet and returns mnemonic with account key, registerSecureTypeAccount registers user, initSecureEnclaveWallet initializes wallet, signInWithCustomToken for Firebase auth, saveMnemonic for restore login, plus notification permission and device ID methods.
FRW/Foundation/Bridge/TurboModuleSwift.swift Added getCurrentUserUid to return activated user ID, getRecoverableProfiles and switchToProfile for profile management, shareQRCode stub, and launchNativeScreen which routes to native restore/backup screens based on NativeScreenName enum values.
FRW/Modules/MultiBackup/View/BackupListView.swift Changed Router.pop() calls to Router.popToRoot() in the back button handler and backup warning confirmation to ensure proper navigation stack cleanup.
FRW/Modules/Profile/ProfileViewModel.swift Added .receive(on: DispatchQueue.main) to the ThemeManager.shared.$style subscription to ensure UI updates occur on the main thread.
FRW/Modules/ReactNative/ReactNativeViewController.swift Added profileSelection and getStarted routes. Added route property for direct route assignment. Changed surfaceView top constraint from safe area to view top anchor to allow RN content behind status bar. Added viewWillAppear to hide navigation bar.
FRW/Modules/Wallet/AccountSwitch/AccountSwitchViewModel.swift Changed createNewAccountAction to route to RouteMap.ReactNative.profileSelection instead of the native registration flow.
FRW/Modules/Wallet/WalletAccount/WalletAccount+FlowWalletKit.swift Updated toWalletAccount to create WalletAccount.ParentInfo from parentAddress parameter, including emoji lookup from WalletUser, and assign it to the wallet account's parent property.
FRW/Services/Manager/Transaction/TransactionHolder.swift Added .receive(on: DispatchQueue.main) to the transaction status subscription to ensure notification posting occurs on the main thread.
FRW/Services/Manager/UserManager.swift Added RNRegisterInfo dictionary to map transaction IDs to user IDs for bridge callbacks. Updated register method to store the mapping when asyncCreateWalletAddressFromServer returns a transaction ID.
FRW/Services/Manager/Wallet/WalletManager.swift Changed asyncCreateWalletAddressFromServer from Void return to async -> String?, returning the transaction ID on success or nil on failure. Removed internal Task wrapper.
FRW/Services/Router/Coordinator.swift Refactored showRootView to dynamically switch between ReactNativeViewController (for empty profiles showing getStarted route) and SideContainerView (for existing profiles). Added profile subscription, root state tracking, and animated transitions.
FRW/Services/Router/RouteMap+React.swift Added profileSelection and getStarted cases to RouteMap.ReactNative. Implemented routing logic to present/push ReactNativeViewController with appropriate initial props or route configuration.
main.jsbundle Updated React Native JavaScript bundle with new onboarding workflow changes.

autogenerated by presubmit.ai

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 Pull request needs attention.

Review Summary

Commits Considered (2)
  • 00e8933: feat: launchNativeScreen
  • d7800bc: feat: create bridge launchNativeScreen
Files Processed (4)
  • FRW.xcodeproj/project.pbxproj (13 hunks)
  • FRW/Foundation/Bridge/NativeScreenName.swift (1 hunk)
  • FRW/Foundation/Bridge/RCTNativeFRWBridge.mm (1 hunk)
  • FRW/Foundation/Bridge/TurboModuleSwift.swift (1 hunk)
Actionable Comments (1)
  • FRW/Foundation/Bridge/TurboModuleSwift.swift [385-385]

    possible bug: "Possible typo in method name."

Skipped Comments (2)
  • FRW/Foundation/Bridge/TurboModuleSwift.swift [368-370]

    readability: "Variable shadowing may cause confusion in error logging."

  • FRW/Foundation/Bridge/TurboModuleSwift.swift [376-376]

    performance: "Unnecessary object instantiation for some code paths."

case .keyStoreRestore:
restoreModel.restoreWithKeyStore()
case .privateKeyRestore:
restoreModel.resteroWithPrivateKey()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There appears to be a typo in the method name resteroWithPrivateKey(). It should likely be restoreWithPrivateKey(). Please verify this is the correct method name in RestoreWalletViewModel.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Review Summary

Commits Considered (1)
  • 411f0d3: Merge branch 'dev' into 310/972-ios-create-native-bridge-for-onboarding-workflow
Files Processed (3)
  • FRW.xcodeproj/project.pbxproj (13 hunks)
  • FRW/Foundation/Bridge/NativeScreenName.swift (1 hunk)
  • FRW/Foundation/Bridge/TurboModuleSwift.swift (1 hunk)
Actionable Comments (0)
Skipped Comments (2)
  • FRW/Foundation/Bridge/TurboModuleSwift.swift [369-369]

    readability: "Misleading variable shadowing in error log message."

  • FRW/Foundation/Bridge/TurboModuleSwift.swift [376-376]

    performance: "Unnecessary object instantiation for some screen types."

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 Pull request needs attention.

Review Summary

Commits Considered (1)
Files Processed (15)
  • FRW.xcodeproj/project.pbxproj (9 hunks)
  • FRW/Foundation/Bridge/BridgeModels.swift (1 hunk)
  • FRW/Foundation/Bridge/NativeScreenName.swift (1 hunk)
  • FRW/Foundation/Bridge/RCTNativeFRWBridge.mm (1 hunk)
  • FRW/Foundation/Bridge/RNBridgeError.swift (1 hunk)
  • FRW/Foundation/Bridge/TurboModule+Onboard.swift (1 hunk)
  • FRW/Foundation/Bridge/TurboModuleSwift.swift (2 hunks)
  • FRW/Modules/MultiBackup/View/BackupListView.swift (2 hunks)
  • FRW/Modules/ReactNative/ReactNativeViewController.swift (3 hunks)
  • FRW/Modules/Wallet/AccountSwitch/AccountSwitchViewModel.swift (1 hunk)
  • FRW/Modules/Wallet/SideMenu/SideContainerView.swift (1 hunk)
  • FRW/Services/Manager/UserManager.swift (3 hunks)
  • FRW/Services/Manager/Wallet/WalletManager.swift (1 hunk)
  • FRW/Services/Router/RouteMap+React.swift (2 hunks)
  • main.jsbundle (0 hunks)
Actionable Comments (1)
  • FRW/Foundation/Bridge/TurboModule+Onboard.swift [107-110]

    possible issue: "Unused parameters in saveMnemonic method."

Skipped Comments (7)
  • FRW/Foundation/Bridge/TurboModule+Onboard.swift [52-52]

    best practice: "Debug print statements should be removed or use proper logging."

  • FRW/Foundation/Bridge/TurboModule+Onboard.swift [107-107]

    security: "Debug print statement in sensitive mnemonic handling method."

  • FRW/Foundation/Bridge/TurboModuleSwift.swift [370-372]

    readability: "Variable shadowing causes confusing error message."

  • FRW/Services/Manager/UserManager.swift [82-82]

    possible issue: "Dictionary may grow indefinitely without cleanup."

  • FRW/Modules/Wallet/AccountSwitch/AccountSwitchViewModel.swift [37-39]

    maintainability: "Commented-out code should be removed."

  • FRW/Modules/Wallet/SideMenu/SideContainerView.swift [40-44]

    maintainability: "Empty HStack used as a workaround for onAppear."

  • FRW/Foundation/Bridge/TurboModule+Onboard.swift [21-24]

    best practice: "UI feedback mixed with error throwing logic."

Comment on lines 107 to 110
static func saveMnemonic(mnemonic: String, customToken: String, txId: String, username: String) async throws {
print("TurboModuleSwift: saveMnemonic called")
try await UserManager.shared.restoreLogin(withMnemonic: mnemonic)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameters customToken, txId, and username are declared but never used in the method body. Either remove these unused parameters or implement the logic that requires them.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Review Summary

Commits Considered (2)
  • 14913e4: feat: update React Native topAnchor
  • 74f733c: feat: push onboarding
Files Processed (2)
  • FRW/Modules/ReactNative/ReactNativeViewController.swift (4 hunks)
  • FRW/Services/Router/RouteMap+React.swift (2 hunks)
Actionable Comments (0)
Skipped Comments (2)
  • FRW/Modules/ReactNative/ReactNativeViewController.swift [178-178]

    possible issue: "Default route fallback may be inappropriate for new onboarding routes."

  • FRW/Services/Router/RouteMap+React.swift [29-32]

    maintainability: "Inconsistent initialization pattern between route cases."

@zhouxl zhouxl marked this pull request as ready for review December 16, 2025 09:52
@zhouxl zhouxl requested a review from a team as a code owner December 16, 2025 09:52
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 Pull request needs attention.

Review Summary

Commits Considered (1)
  • ee5a37b: Merge branch 'dev' into 310/972-ios-create-native-bridge-for-onboarding-workflow
Files Processed (3)
  • FRW.xcodeproj/project.pbxproj (9 hunks)
  • FRW/Services/Manager/UserManager.swift (3 hunks)
  • FRW/Services/Manager/Wallet/WalletManager.swift (1 hunk)
Actionable Comments (1)
  • FRW/Services/Manager/UserManager.swift [83-83]

    possible bug: "Dictionary may have thread-safety issues when accessed from multiple threads."

Skipped Comments (3)
  • FRW/Services/Manager/UserManager.swift [83-83]

    best practice: "Variable name does not follow Swift naming conventions."

  • FRW/Services/Manager/UserManager.swift [218-218]

    possible issue: "No error handling when wallet address creation fails."

  • FRW/Services/Manager/UserManager.swift [227-229]

    maintainability: "Dictionary entries are never cleaned up, potentially causing memory growth."

}

// It is only used when the bridge is called on page of onboard
var RNRegisterInfo:[String: String] = [:]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dictionary RNRegisterInfo is declared as a var without any synchronization mechanism. If this dictionary is accessed from multiple threads (e.g., from React Native bridge calls and native code), it could lead to race conditions and data corruption. Consider using a thread-safe approach such as a concurrent queue, NSLock, or an actor.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Review Summary

Commits Considered (1)
Files Processed (3)
  • FRW/Modules/Profile/ProfileViewModel.swift (1 hunk)
  • FRW/Services/Manager/Transaction/TransactionHolder.swift (1 hunk)
  • main.jsbundle (0 hunks)
Actionable Comments (0)
Skipped Comments (1)
  • FRW/Services/Manager/Transaction/TransactionHolder.swift [95-98]

    possible issue: "Verify that completion handler should also run on main queue."

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Review Summary

Commits Considered (1)
  • 169fbc1: feat: eoa add parent for RN
Files Processed (1)
  • FRW/Modules/Wallet/WalletAccount/WalletAccount+FlowWalletKit.swift (1 hunk)
Actionable Comments (0)
Skipped Comments (1)
  • FRW/Modules/Wallet/WalletAccount/WalletAccount+FlowWalletKit.swift [133-139]

    possible issue: "Empty string handling for optional parent address."

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Review Summary

Commits Considered (2)
  • 9e18ef4: feat: switch root between RN and SideContainerView
  • 12e0d10: feat: start with onboard for no profile
Files Processed (5)
  • FRW/Foundation/Bridge/RCTNativeFRWBridge.mm (2 hunks)
  • FRW/Foundation/Bridge/TurboModule+Onboard.swift (1 hunk)
  • FRW/Foundation/Bridge/TurboModuleSwift.swift (4 hunks)
  • FRW/Modules/ReactNative/ReactNativeViewController.swift (5 hunks)
  • FRW/Services/Router/Coordinator.swift (1 hunk)
Actionable Comments (0)
Skipped Comments (5)
  • FRW/Foundation/Bridge/TurboModuleSwift.swift [251-253]

    possible issue: "Empty method implementation will silently do nothing."

  • FRW/Foundation/Bridge/TurboModuleSwift.swift [392-394]

    possible bug: "Variable shadowing causes incorrect error message."

  • FRW/Foundation/Bridge/TurboModule+Onboard.swift [111-119]

    possible issue: "Screen security method has no actual implementation."

  • FRW/Foundation/Bridge/TurboModule+Onboard.swift [137-137]

    best practice: "Debug print statement should use proper logging."

  • FRW/Services/Router/Coordinator.swift [101-101]

    enhancement: "Animation parameter may cause visual issues during initial setup."

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Review Summary

Commits Considered (1)
  • 98f43e4: feat: add animation and setup flag
Files Processed (1)
  • FRW/Services/Router/Coordinator.swift (1 hunk)
Actionable Comments (0)
Skipped Comments (2)
  • FRW/Services/Router/Coordinator.swift [77-83]

    possible issue: "Subscription may not be properly cleaned up on coordinator reuse."

  • FRW/Services/Router/Coordinator.swift [127-131]

    enhancement: "Animation approach may cause visual artifacts during root view transition."

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 Pull request needs attention.

Review Summary

Commits Considered (1)
  • c5dd810: feat: add restore from icloud
Files Processed (2)
  • FRW/Foundation/Bridge/NativeScreenName.swift (1 hunk)
  • FRW/Foundation/Bridge/TurboModuleSwift.swift (4 hunks)
Actionable Comments (1)
  • FRW/Foundation/Bridge/TurboModuleSwift.swift [392-394]

    possible bug: "Variable shadowing causes incorrect error message."

Skipped Comments (3)
  • FRW/Foundation/Bridge/TurboModuleSwift.swift [251-253]

    possible issue: "Empty method implementation may cause silent failures."

  • FRW/Foundation/Bridge/TurboModuleSwift.swift [240-243]

    possible issue: "Method returns all profiles instead of filtering for recoverable ones."

  • FRW/Foundation/Bridge/TurboModuleSwift.swift [7-8]

    maintainability: "Unused import statement."

Comment on lines +392 to +394
guard let screen = NativeScreenName(rawValue: screen) else {
log.error("don't support route \(screen)")
HUD.error(title: "don't support route \(screen)")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message logs and displays the screen variable after it has been shadowed by the failed NativeScreenName initialization, which will always be nil at that point. The original screen: String parameter should be used in the error message instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[iOS] Create native bridge for onboarding workflow

2 participants