Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 20 additions & 26 deletions FRW.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1632,6 +1632,8 @@
4E9059302B1792F10029FC66 /* SyncAddDeviceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E90592E2B1792F10029FC66 /* SyncAddDeviceView.swift */; };
4E9182622EB89C63008FD73A /* AdaptiveHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E9182612EB89C63008FD73A /* AdaptiveHostingController.swift */; };
4E9182632EB89C63008FD73A /* AdaptiveHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E9182612EB89C63008FD73A /* AdaptiveHostingController.swift */; };
4E93A3822F339D7F00C9ED7B /* BridgeModels+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E93A3812F339D7D00C9ED7B /* BridgeModels+Extension.swift */; };
4E93A3832F339D7F00C9ED7B /* BridgeModels+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E93A3812F339D7D00C9ED7B /* BridgeModels+Extension.swift */; };
4E947C922BBEB2E300E87A85 /* web3swift in Frameworks */ = {isa = PBXBuildFile; productRef = 4E947C912BBEB2E300E87A85 /* web3swift */; };
4E952F4A2EE2B59F00175DAA /* NativeScreenName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E952F492EE2B59F00175DAA /* NativeScreenName.swift */; };
4E952F4B2EE2B59F00175DAA /* NativeScreenName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E952F492EE2B59F00175DAA /* NativeScreenName.swift */; };
Expand Down Expand Up @@ -1785,6 +1787,8 @@
4EBDF2C92BFB9F3700E56968 /* SelectCollectionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EBDF2C72BFB9F3700E56968 /* SelectCollectionViewModel.swift */; };
4EBE49262AA1B732000FFFFE /* AppUpdateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EBE49252AA1B732000FFFFE /* AppUpdateManager.swift */; };
4EBE49272AA1B732000FFFFE /* AppUpdateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EBE49252AA1B732000FFFFE /* AppUpdateManager.swift */; };
4EC1269E2F39E06700D2467B /* TurboModule+CoaToEoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EC1269D2F39E06700D2467B /* TurboModule+CoaToEoa.swift */; };
4EC1269F2F39E06700D2467B /* TurboModule+CoaToEoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EC1269D2F39E06700D2467B /* TurboModule+CoaToEoa.swift */; };
4EC212F22C45E7F5008469F1 /* MoveAccountsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EC212F12C45E7F5008469F1 /* MoveAccountsView.swift */; };
4EC212F32C45E7F5008469F1 /* MoveAccountsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EC212F12C45E7F5008469F1 /* MoveAccountsView.swift */; };
4EC26FCA2BFCAF5C001330DF /* EVMAssetProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EC26FC92BFCAF5C001330DF /* EVMAssetProvider.swift */; };
Expand Down Expand Up @@ -3236,6 +3240,7 @@
4E8E3F882D8306C7000916A6 /* SearchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBar.swift; sourceTree = "<group>"; };
4E90592E2B1792F10029FC66 /* SyncAddDeviceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncAddDeviceView.swift; sourceTree = "<group>"; };
4E9182612EB89C63008FD73A /* AdaptiveHostingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdaptiveHostingController.swift; sourceTree = "<group>"; };
4E93A3812F339D7D00C9ED7B /* BridgeModels+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BridgeModels+Extension.swift"; sourceTree = "<group>"; };
4E952F492EE2B59F00175DAA /* NativeScreenName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeScreenName.swift; sourceTree = "<group>"; };
4E95322E2CD2082F00AAECD1 /* AddCustomTokenView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddCustomTokenView.swift; sourceTree = "<group>"; };
4E9532312CD2089C00AAECD1 /* AddCustomTokenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddCustomTokenViewModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3318,6 +3323,7 @@
4EBDF2C42BFB9E9400E56968 /* SelectCollectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectCollectionView.swift; sourceTree = "<group>"; };
4EBDF2C72BFB9F3700E56968 /* SelectCollectionViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectCollectionViewModel.swift; sourceTree = "<group>"; };
4EBE49252AA1B732000FFFFE /* AppUpdateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUpdateManager.swift; sourceTree = "<group>"; };
4EC1269D2F39E06700D2467B /* TurboModule+CoaToEoa.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TurboModule+CoaToEoa.swift"; sourceTree = "<group>"; };
4EC212F12C45E7F5008469F1 /* MoveAccountsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveAccountsView.swift; sourceTree = "<group>"; };
4EC26FC92BFCAF5C001330DF /* EVMAssetProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EVMAssetProvider.swift; sourceTree = "<group>"; };
4EC26FCF2BFE315A001330DF /* MoveSingleNFTView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveSingleNFTView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4818,7 +4824,9 @@
4E33F7D42E42423F00B3D62F /* RNTokenModel.swift */,
4EECEB202E323F29008E21B6 /* RNEncoder.swift */,
1575765D2E322E6A00D7D8C4 /* BridgeModels.swift */,
4E93A3812F339D7D00C9ED7B /* BridgeModels+Extension.swift */,
15A87E902E26D9E100F0E550 /* TurboModuleSwift.swift */,
4EC1269D2F39E06700D2467B /* TurboModule+CoaToEoa.swift */,
4EC758402EEAC16F00B9012E /* TurboModule+Onboard.swift */,
15A87E8D2E26D9CF00F0E550 /* RCTNativeFRWBridge.mm */,
1594792C2E282F7000F2B7A6 /* RCTNativeFRWBridge.h */,
Expand Down Expand Up @@ -8103,14 +8111,10 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FRW-dev/Pods-FRW-dev-resources-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FRW-dev/Pods-FRW-dev-resources-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FRW-dev/Pods-FRW-dev-resources.sh\"\n";
Expand Down Expand Up @@ -8163,14 +8167,10 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FRW/Pods-FRW-resources-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FRW/Pods-FRW-resources-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FRW/Pods-FRW-resources.sh\"\n";
Expand All @@ -8184,14 +8184,10 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FRWTests/Pods-FRWTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FRWTests/Pods-FRWTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FRWTests/Pods-FRWTests-frameworks.sh\"\n";
Expand Down Expand Up @@ -8223,14 +8219,10 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FRWTests/Pods-FRWTests-resources-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FRWTests/Pods-FRWTests-resources-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FRWTests/Pods-FRWTests-resources.sh\"\n";
Expand Down Expand Up @@ -8306,14 +8298,10 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FRW-dev/Pods-FRW-dev-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FRW-dev/Pods-FRW-dev-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FRW-dev/Pods-FRW-dev-frameworks.sh\"\n";
Expand Down Expand Up @@ -8368,14 +8356,10 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FRW/Pods-FRW-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FRW/Pods-FRW-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FRW/Pods-FRW-frameworks.sh\"\n";
Expand Down Expand Up @@ -8998,6 +8982,7 @@
4EA0D0A72A7A5AED004C6A19 /* FRWAPI+ChildAccount.swift in Sources */,
4EC279FE2EEFA35800F5DC71 /* DocumentPicker.swift in Sources */,
57312EC62CFD2833009A344A /* Threading.swift in Sources */,
4E93A3832F339D7F00C9ED7B /* BridgeModels+Extension.swift in Sources */,
4E03BE1A2C731F3500EF04DC /* ViewsInLoginModule.swift in Sources */,
1596A8D42E1AD76200E85303 /* ReactNativeViewController.swift in Sources */,
154E31572DA56A1D008A495F /* WalletManager+Getter.swift in Sources */,
Expand Down Expand Up @@ -9114,6 +9099,7 @@
6A06CB0728AA25F400C81BE1 /* NFTUIKitListDataSource.swift in Sources */,
6AAD4E6A28BC6E9900AEAB1F /* TransactionModels.swift in Sources */,
4E411DBF2CB91C3A005AD540 /* MoveComponentView.swift in Sources */,
4EC1269E2F39E06700D2467B /* TurboModule+CoaToEoa.swift in Sources */,
159DEC9328C67DB900493E9F /* NFTDetailPageViewModel.swift in Sources */,
4E5885452A6FDF00007CACCC /* SPQRMaskView.swift in Sources */,
4EFBE5D12BC7D4AA0012968A /* ConfettiManager.swift in Sources */,
Expand Down Expand Up @@ -10101,6 +10087,7 @@
15C58B6F2868A4EE00BD4FC6 /* VBaseButtonState.swift in Sources */,
4EC279FD2EEFA35800F5DC71 /* DocumentPicker.swift in Sources */,
57312EC52CFD2833009A344A /* Threading.swift in Sources */,
4E93A3822F339D7F00C9ED7B /* BridgeModels+Extension.swift in Sources */,
4E03BE192C731F3500EF04DC /* ViewsInLoginModule.swift in Sources */,
1596A8D12E1AD76200E85303 /* ReactNativeViewController.swift in Sources */,
154E31562DA56A1D008A495F /* WalletManager+Getter.swift in Sources */,
Expand Down Expand Up @@ -10217,6 +10204,7 @@
159DEC9228C67DB900493E9F /* NFTDetailPageViewModel.swift in Sources */,
15C58BA52868A4EE00BD4FC6 /* TabBar.swift in Sources */,
4E411DC02CB91C3A005AD540 /* MoveComponentView.swift in Sources */,
4EC1269F2F39E06700D2467B /* TurboModule+CoaToEoa.swift in Sources */,
4E5885442A6FDF00007CACCC /* SPQRMaskView.swift in Sources */,
15C58BA62868A4EE00BD4FC6 /* Logger.swift in Sources */,
4EFBE5D02BC7D4AA0012968A /* ConfettiManager.swift in Sources */,
Expand Down Expand Up @@ -10980,7 +10968,10 @@
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "$(inherited) ";
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
Expand Down Expand Up @@ -11045,7 +11036,10 @@
MARKETING_VERSION = 3.1.2;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
OTHER_LDFLAGS = "$(inherited) ";
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
Expand Down
36 changes: 36 additions & 0 deletions FRW/Foundation/Bridge/BridgeModels+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// BridgeModels+Extension.swift
// FRW
//
// Created by cat on 2/4/26.
//

extension RNBridge {
struct TransactionDatas: Codable {
let addresses: [String]
let values: [String]
let datas: [[Int]]
}

struct Erc20Asset: Codable {
let address: String
let amount: String
}

struct Erc721Asset: Codable {
let address: String
let id: String
}

struct Erc1155Asset: Codable {
let address: String
let id: String
let amount: String
}

struct MigrationAssetsData: Codable {
let erc20: [Erc20Asset]
let erc721: [Erc721Asset]
let erc1155: [Erc1155Asset]
}
}
1 change: 1 addition & 0 deletions FRW/Foundation/Bridge/BridgeModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum RNBridge {
case onboarding = "onboarding"
case receive = "receive"
case activity = "activity"
case migration = "migration"
}

enum AccountTypeType: String, Codable {
Expand Down
27 changes: 27 additions & 0 deletions FRW/Foundation/Bridge/RCTNativeFRWBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,31 @@ - (void)getSelectedAccount:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRej

}

- (void)getMigrationAssets:(NSString *)sourceAddress
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject {
[TurboModuleSwift getMigrationAssetsWithSourceAddress:sourceAddress
completionHandler:^(NSDictionary<NSString *,id> * _Nullable result,
NSError * _Nullable error) {
if (error) {
reject(@"migration_assets_error", error.localizedDescription, error);
} else {
resolve(result);
}
}];
}

- (void)refreshCoaAfterMigration:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject {
[TurboModuleSwift refreshCoaAfterMigrationWithCompletionHandler:^(NSError * _Nullable error) {
if (error) {
reject(@"refresh_coa_after_migration_error", error.localizedDescription, error);
} else {
resolve(nil);
}
}];
}

- (NSDictionary *)getCurrency {
return [TurboModuleSwift getCurrency];
}
Expand Down Expand Up @@ -388,4 +413,6 @@ - (void)getV4RegistrationSignatures:(NSString *)mnemonic resolve:(RCTPromiseReso
}];
}



@end
91 changes: 91 additions & 0 deletions FRW/Foundation/Bridge/TurboModule+CoaToEoa.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//
// TurboModule+CoaToEoa.swift
// FRW
//
// Created by cat on 2/9/26.
//

import Foundation

// fetch balance and nft count for coa
extension TurboModuleSwift {
static func fetchAmountForCoa(address: String) async throws -> RNBridge.MigrationAssetsData? {

guard let addr = FWAddressDector.create(address: address), addr.type == .evm else {
return nil
}
let evmProvider = TokenBalanceHandler()
let tokenList = try await evmProvider.getFTBalance(address: addr)
let collectionList = try await evmProvider.getNFTCollections(address: addr)

let erc20: [RNBridge.Erc20Asset] = tokenList.compactMap { model in
guard let addr = model.getAddress(), !addr.isEmpty else {
return nil
}
guard let amount = model.balanceInFLOW, amount.count > 0, amount != "0" else {
return nil
}
return RNBridge.Erc20Asset(address: addr, amount: amount)
}

let erc721: [RNBridge.Erc721Asset] = collectionList.flatMap { model -> [RNBridge.Erc721Asset] in
let contractType = model.collection.ERCType
guard contractType == .erc721 else {
return []
}
guard let rawAddr = model.collection.evmAddress else {
return []
}
let addr = rawAddr.addHexPrefix()
guard addr.hasPrefix("0x"), let list = model.ids, !list.isEmpty else {
return []
}
let assets: [RNBridge.Erc721Asset] = list.compactMap { nftId in
let trimmed = nftId.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else {
return nil
}
return RNBridge.Erc721Asset(address: addr, id: trimmed)
}
return assets
}

let erc1155: [RNBridge.Erc1155Asset] = collectionList.flatMap { model -> [RNBridge.Erc1155Asset] in
let contractType = model.collection.ERCType
guard contractType == .erc1155 else {
return []
}
guard let rawAddr = model.collection.evmAddress else {
return []
}
let addr = rawAddr.addHexPrefix()
guard addr.hasPrefix("0x"), let list = model.ids, !list.isEmpty else {
return []
}
var orderedIds: [String] = []
var counts: [String: Int] = [:]
list.forEach { nftId in
let trimmed = nftId.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else {
return
}
if counts[trimmed] == nil {
orderedIds.append(trimmed)
counts[trimmed] = 1
} else {
counts[trimmed, default: 0] += 1
}
}
let assets: [RNBridge.Erc1155Asset] = orderedIds.compactMap { nftId -> RNBridge.Erc1155Asset? in
guard let count = counts[nftId], count > 0 else {
return nil
}
return RNBridge.Erc1155Asset(address: addr, id: nftId, amount: "\(count)")
}
return assets
}

let data = RNBridge.MigrationAssetsData(erc20: erc20, erc721: erc721, erc1155: erc1155)
return data
}
}
19 changes: 19 additions & 0 deletions FRW/Foundation/Bridge/TurboModuleSwift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,25 @@ extension TurboModuleSwift {
let result = response?.getLastRate() ?? 0
return result
}

@objc
static func getMigrationAssets(sourceAddress: String) async throws -> [String: Any] {
let model = try await TurboModuleSwift.fetchAmountForCoa(address: sourceAddress)
return try model.toDictionary()
}

@objc
static func refreshCoaAfterMigration() async throws {
async let refreshProfile: Void = ProfileManager.shared.refreshCurrentProfileAccounts()
async let refreshWallet: Void = {
do {
try await WalletManager.shared.fetchWalletDatas()
} catch {
log.warning("[Migration] Refresh wallet data failed: \(error)")
}
}()
_ = await (refreshProfile, refreshWallet)
}

@objc
static func getWalletProfiles() async throws -> [String: Any] {
Expand Down
Loading