Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
Fix #7809: Filecoin basic support on iOS (#7912)
Browse files Browse the repository at this point in the history
  • Loading branch information
nuo-xu committed Sep 7, 2023
1 parent e67bbb4 commit 5306d23
Show file tree
Hide file tree
Showing 60 changed files with 1,727 additions and 325 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ extension Tab: BraveWalletKeyringServiceObserver {
// check domain already has some permitted accounts for this Tab's URLOrigin
let permissionRequestManager = WalletProviderPermissionRequestsManager.shared
let allAccounts = await keyringService.allAccounts().accounts
for coin in WalletConstants.supportedCoinTypes {
for coin in WalletConstants.supportedCoinTypes(.dapps) {
let allAccountsForCoin = allAccounts.filter { $0.coin == coin }
if permissionRequestManager.hasPendingRequest(for: origin, coinType: coin) {
let pendingRequests = permissionRequestManager.pendingRequests(for: origin, coinType: coin)
Expand Down
11 changes: 8 additions & 3 deletions Sources/BraveWallet/Crypto/Accounts/AccountSelectionView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import BraveUI
/// Displays all accounts and will update the selected account to the account tapped on.
struct AccountSelectionView: View {
@ObservedObject var keyringStore: KeyringStore
var networkStore: NetworkStore
let onDismiss: () -> Void

@State private var isPresentingAddAccount: Bool = false
Expand Down Expand Up @@ -47,7 +48,10 @@ struct AccountSelectionView: View {
}
.sheet(isPresented: $isPresentingAddAccount) {
NavigationView {
AddAccountView(keyringStore: keyringStore)
AddAccountView(
keyringStore: keyringStore,
networkStore: networkStore
)
}
.navigationViewStyle(.stack)
}
Expand All @@ -60,10 +64,11 @@ struct AccountSelectionView_Previews: PreviewProvider {
AccountSelectionView(
keyringStore: {
let store = KeyringStore.previewStoreWithWalletCreated
store.addPrimaryAccount("Account 2", coin: .eth, completion: nil)
store.addPrimaryAccount("Account 3", coin: .eth, completion: nil)
store.addPrimaryAccount("Account 2", coin: .eth, chainId: BraveWallet.MainnetChainId, completion: nil)
store.addPrimaryAccount("Account 3", coin: .eth, chainId: BraveWallet.MainnetChainId, completion: nil)
return store
}(),
networkStore: .previewStore,
onDismiss: {}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ struct AccountTransactionListView: View {
if !txSummary.txHash.isEmpty {
Button(action: {
if let txNetwork = self.networkStore.allChains.first(where: { $0.chainId == txSummary.txInfo.chainId }),
let baseURL = txNetwork.blockExplorerUrls.first.map(URL.init(string:)),
let url = baseURL?.appendingPathComponent("tx/\(txSummary.txHash)") {
let url = txNetwork.txBlockExplorerLink(txHash: txSummary.txHash, for: txNetwork.coin) {
openWalletURL(url)
}
}) {
Expand Down
5 changes: 4 additions & 1 deletion Sources/BraveWallet/Crypto/Accounts/AccountsHeaderView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ struct AccountsHeaderView: View {
Color.clear
.sheet(isPresented: $isPresentingAddAccount) {
NavigationView {
AddAccountView(keyringStore: keyringStore)
AddAccountView(
keyringStore: keyringStore,
networkStore: networkStore
)
}
.navigationViewStyle(StackNavigationViewStyle())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@ struct AccountActivityView: View {
if !txSummary.txHash.isEmpty {
Button(action: {
if let txNetwork = self.networkStore.allChains.first(where: { $0.chainId == txSummary.txInfo.chainId }),
let baseURL = txNetwork.blockExplorerUrls.first.map(URL.init(string:)),
let url = baseURL?.appendingPathComponent("tx/\(txSummary.txHash)") {
let url = txNetwork.txBlockExplorerLink(txHash: txSummary.txHash, for: txNetwork.coin) {
openWalletURL(url)
}
}) {
Expand Down
43 changes: 38 additions & 5 deletions Sources/BraveWallet/Crypto/Accounts/Add/AddAccountView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,41 @@ struct AddAccountView: View {
@State private var originPassword: String = ""
@State private var failedToImport: Bool = false
@State private var selectedCoin: BraveWallet.CoinType?
@State private var filNetwork: BraveWallet.NetworkInfo
@ScaledMetric(relativeTo: .body) private var privateKeyFieldHeight: CGFloat = 140.0
@Environment(\.presentationMode) @Binding var presentationMode
@Environment(\.appRatingRequestAction) private var appRatingRequest

@ScaledMetric private var iconSize = 40.0
private let maxIconSize: CGFloat = 80.0
private var allFilNetworks: [BraveWallet.NetworkInfo]

var preSelectedCoin: BraveWallet.CoinType?
var onCreate: (() -> Void)?
var onDismiss: (() -> Void)?

init(
keyringStore: KeyringStore,
networkStore: NetworkStore,
preSelectedCoin: BraveWallet.CoinType? = nil,
onCreate: (() -> Void)? = nil,
onDismiss: (() -> Void)? = nil
) {
self.keyringStore = keyringStore
self.allFilNetworks = networkStore.allChains.filter { $0.coin == .fil }
self.preSelectedCoin = preSelectedCoin
self.onCreate = onCreate
self.onDismiss = onDismiss
_filNetwork = .init(initialValue: self.allFilNetworks.first ?? .init())
}

private func addAccount(for coin: BraveWallet.CoinType) {
let accountName = name.isEmpty ? defaultAccountName(for: coin, isPrimary: privateKey.isEmpty) : name
guard accountName.isValidAccountName else { return }

if privateKey.isEmpty {
// Add normal account
keyringStore.addPrimaryAccount(accountName, coin: coin) { success in
keyringStore.addPrimaryAccount(accountName, coin: coin, chainId: filNetwork.chainId) { success in
if success {
onCreate?()
appRatingRequest?()
Expand All @@ -56,7 +73,7 @@ struct AddAccountView: View {
if isJSONImported {
keyringStore.addSecondaryAccount(accountName, json: privateKey, password: originPassword, completion: handler)
} else {
keyringStore.addSecondaryAccount(accountName, coin: coin, privateKey: privateKey, completion: handler)
keyringStore.addSecondaryAccount(accountName, coin: coin, chainId: filNetwork.chainId, privateKey: privateKey, completion: handler)
}
}
}
Expand All @@ -74,7 +91,7 @@ struct AddAccountView: View {
}

private var showCoinSelection: Bool {
preSelectedCoin == nil && WalletConstants.supportedCoinTypes.count > 1
preSelectedCoin == nil && WalletConstants.supportedCoinTypes().count > 1
}

private var navigationTitle: String {
Expand All @@ -86,6 +103,19 @@ struct AddAccountView: View {

@ViewBuilder private var addAccountView: some View {
List {
if (selectedCoin == .fil || preSelectedCoin == .fil) && !allFilNetworks.isEmpty {
Picker(selection: $filNetwork) {
ForEach(allFilNetworks) { network in
Text(network.chainName)
.foregroundColor(Color(.secondaryBraveLabel))
.tag(network)
}
} label: {
Text(Strings.Wallet.transactionDetailsNetworkTitle)
.foregroundColor(Color(.braveLabel))
}
.listRowBackground(Color(.secondaryBraveGroupedBackground))
}
accountNameSection
if isJSONImported {
originPasswordSection
Expand Down Expand Up @@ -122,7 +152,7 @@ struct AddAccountView: View {
title: Text(Strings.Wallet.coinTypeSelectionHeader)
)
) {
ForEach(Array(WalletConstants.supportedCoinTypes)) { coin in
ForEach(WalletConstants.supportedCoinTypes().elements) { coin in
NavigationLink(
tag: coin,
selection: $selectedCoin) {
Expand Down Expand Up @@ -310,7 +340,10 @@ struct AddAccountView: View {
struct AddAccountView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
AddAccountView(keyringStore: .previewStore)
AddAccountView(
keyringStore: .previewStore,
networkStore: .previewStore
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ private struct AccountDetailsHeaderView: View {
}

#if DEBUG
struct AccountDetailsViewController_Previews: PreviewProvider {
struct AccountDetailsView_Previews: PreviewProvider {
static var previews: some View {
AccountDetailsView(
keyringStore: .previewStoreWithWalletCreated,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ struct AssetDetailView: View {
if !txSummary.txHash.isEmpty {
Button(action: {
if let txNetwork = self.networkStore.allChains.first(where: { $0.chainId == txSummary.txInfo.chainId }),
let baseURL = txNetwork.blockExplorerUrls.first.map(URL.init(string:)),
let url = baseURL?.appendingPathComponent("tx/\(txSummary.txHash)") {
let url = txNetwork.txBlockExplorerLink(txHash: txSummary.txHash, for: txNetwork.coin) {
openWalletURL(url)
}
}) {
Expand Down Expand Up @@ -211,7 +210,10 @@ struct AssetDetailView: View {
Color.clear
.sheet(isPresented: $isShowingAddAccount) {
NavigationView {
AddAccountView(keyringStore: keyringStore)
AddAccountView(
keyringStore: keyringStore,
networkStore: networkStore
)
}
.navigationViewStyle(StackNavigationViewStyle())
}
Expand Down
1 change: 1 addition & 0 deletions Sources/BraveWallet/Crypto/BuySendSwap/AccountPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct AccountPicker: View {
NavigationView {
AccountSelectionView(
keyringStore: keyringStore,
networkStore: networkStore,
onDismiss: { isPresentingPicker = false }
)
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/BraveWallet/Crypto/CryptoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ public struct CryptoView: View {
NavigationView {
AccountSelectionView(
keyringStore: keyringStore,
networkStore: store.networkStore,
onDismiss: {
dismissAction()
}
Expand Down Expand Up @@ -212,6 +213,7 @@ public struct CryptoView: View {
NavigationView {
AddAccountView(
keyringStore: keyringStore,
networkStore: store.networkStore,
preSelectedCoin: request.coinType,
onCreate: {
// request is fullfilled.
Expand Down
6 changes: 5 additions & 1 deletion Sources/BraveWallet/Crypto/NetworkSelectionView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ struct NetworkSelectionView: View {
isPresented: $store.isPresentingAddAccount
) {
NavigationView {
AddAccountView(keyringStore: keyringStore, preSelectedCoin: store.nextNetwork?.coin)
AddAccountView(
keyringStore: keyringStore,
networkStore: networkStore,
preSelectedCoin: store.nextNetwork?.coin
)
}
.navigationViewStyle(.stack)
.onDisappear {
Expand Down
12 changes: 10 additions & 2 deletions Sources/BraveWallet/Crypto/Stores/AccountActivityStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,16 @@ class AccountActivityStore: ObservableObject {
let coin = account.coin
let networksForAccountCoin = await rpcService.allNetworks(coin)
.filter { $0.chainId != BraveWallet.LocalhostChainId } // localhost not supported
let networksForAccount = networksForAccountCoin.filter { // .fil coin type has two different keyring ids
$0.supportedKeyrings.contains(account.keyringId.rawValue as NSNumber)
}

let allVisibleUserAssets = assetManager.getAllVisibleAssetsInNetworkAssets(networks: networksForAccountCoin)
struct NetworkAssets: Equatable {
let network: BraveWallet.NetworkInfo
let tokens: [BraveWallet.BlockchainToken]
let sortOrder: Int
}
let allVisibleUserAssets = assetManager.getAllVisibleAssetsInNetworkAssets(networks: networksForAccount)
let allTokens = await blockchainRegistry.allTokens(in: networksForAccountCoin).flatMap(\.tokens)
var updatedUserVisibleAssets: [AssetViewModel] = []
var updatedUserVisibleNFTs: [NFTAssetViewModel] = []
Expand Down Expand Up @@ -110,7 +118,7 @@ class AccountActivityStore: ObservableObject {
self.userVisibleAssets = updatedUserVisibleAssets
self.userVisibleNFTs = updatedUserVisibleNFTs

let keyringForAccount = await keyringService.keyringInfo(coin.keyringId)
let keyringForAccount = await keyringService.keyringInfo(account.keyringId)
typealias TokenNetworkAccounts = (token: BraveWallet.BlockchainToken, network: BraveWallet.NetworkInfo, accounts: [BraveWallet.AccountInfo])
let allTokenNetworkAccounts = allVisibleUserAssets.flatMap { networkAssets in
networkAssets.tokens.map { token in
Expand Down
11 changes: 11 additions & 0 deletions Sources/BraveWallet/Crypto/Stores/Address.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import Foundation
import BraveCore

extension String {
/// Truncates an address to only show the first 4 digits and last 4 digits
Expand Down Expand Up @@ -43,6 +44,16 @@ extension String {
return hex.count == 40 && hex.allSatisfy(\.isHexDigit)
}

/// Check if the string is a valid FIL address
var isFILAddress: Bool {
if starts(with: BraveWallet.FilecoinMainnet) || starts(with: BraveWallet.FilecoinTestnet) {// FIL address has to start with `f` or `t`
if count == 41 || count == 86 || count == 44 { // secp256k have 41 address length and BLS keys have 86 and FEVM f410 keys have 44
return true
}
}
return false
}

/// Strip prefix if it exists, ex. 'ethereum:'
var strippedETHAddress: String {
guard !isETHAddress else { return self }
Expand Down
3 changes: 2 additions & 1 deletion Sources/BraveWallet/Crypto/Stores/AssetDetailStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ class AssetDetailStore: ObservableObject {
self.isSwapSupported = await swapService.isSwapSupported(token.chainId)

// fetch accounts
let keyring = await keyringService.keyringInfo(token.coin.keyringId)
let keyringId = BraveWallet.KeyringId.keyringId(for: token.coin, on: token.chainId)
let keyring = await keyringService.keyringInfo(keyringId)
var updatedAccounts = keyring.accountInfos.map {
AccountAssetViewModel(account: $0, decimalBalance: 0.0, balance: "", fiatBalance: "")
}
Expand Down
22 changes: 10 additions & 12 deletions Sources/BraveWallet/Crypto/Stores/CryptoStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -410,13 +410,13 @@ public class CryptoStore: ObservableObject {

@MainActor
func fetchPendingTransactions() async -> [BraveWallet.TransactionInfo] {
let allKeyrings = await keyringService.keyrings(for: WalletConstants.supportedCoinTypes)
var allChainIdsForCoin: [BraveWallet.CoinType: [String]] = [:]
for coin in WalletConstants.supportedCoinTypes {
let allKeyrings = await keyringService.keyrings(for: WalletConstants.supportedCoinTypes())
var allNetworksForCoin: [BraveWallet.CoinType: [BraveWallet.NetworkInfo]] = [:]
for coin in WalletConstants.supportedCoinTypes() {
let allNetworks = await rpcService.allNetworks(coin)
allChainIdsForCoin[coin] = allNetworks.map(\.chainId)
allNetworksForCoin[coin] = allNetworks
}
return await txService.pendingTransactions(chainIdsForCoin: allChainIdsForCoin, for: allKeyrings)
return await txService.pendingTransactions(networksForCoin: allNetworksForCoin, for: allKeyrings)
}

@MainActor
Expand Down Expand Up @@ -560,13 +560,11 @@ extension CryptoStore: BraveWalletKeyringServiceObserver {
rejectAllPendingWebpageRequests()
}
public func keyringCreated(_ keyringId: BraveWallet.KeyringId) {
Task { @MainActor [weak self] in
if let newCoin = WalletConstants.supportedCoinTypes.first(where: { $0.keyringId == keyringId }) {
self?.userAssetManager.migrateUserAssets(for: newCoin, completion: {
self?.updateAssets()
})
}
}
// 1. We don't need to rely on this observer method to migrate user visible assets
// when user creates a new wallet, since in this case `CryptoStore` has not yet been initialized
// 2. We don't need to rely on this observer method to migrate user visible assets
// when user creates or imports a new account with a new keyring since any new
// supported coin type / keyring will be migrated inside `CryptoStore`'s init()
}
public func keyringRestored(_ keyringId: BraveWallet.KeyringId) {
// This observer method will only get called when user restore a wallet
Expand Down
Loading

0 comments on commit 5306d23

Please sign in to comment.