Skip to content
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

Feat/mixpanel copy #616

Merged
merged 10 commits into from
Dec 3, 2024
Merged
4 changes: 2 additions & 2 deletions FRW.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8531,7 +8531,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.2.10;
MARKETING_VERSION = 2.3.0;
PRODUCT_BUNDLE_IDENTIFIER = com.flowfoundation.wallet.dev;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
Expand Down Expand Up @@ -8574,7 +8574,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.2.10;
MARKETING_VERSION = 2.3.0;
PRODUCT_BUNDLE_IDENTIFIER = com.flowfoundation.wallet.dev;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
Expand Down
4 changes: 2 additions & 2 deletions FRW/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ extension AppDelegate {

private func appConfig() {
MultiAccountStorage.shared.upgradeFromOldVersionIfNeeded()

_ = CadenceManager.shared
_ = UserManager.shared
_ = WalletManager.shared
_ = BackupManager.shared
Expand All @@ -158,7 +158,7 @@ extension AppDelegate {
_ = ChildAccountManager.shared
WalletManager.shared.bindChildAccountManager()
NFTCatalogCache.cache.fetchIfNeed()
_ = CadenceManager.shared

if UserManager.shared.isLoggedIn {
DeviceManager.shared.updateDevice()
}
Expand Down
15 changes: 15 additions & 0 deletions FRW/Foundation/Model/Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,18 @@ enum EVMError: Error {
case findAddress
case transactionResult
}

// MARK: - CadenceError

enum CadenceError: Error {
case empty

// MARK: Internal

var message: String {
switch self {
case .empty:
"empty script"
}
}
}
33 changes: 31 additions & 2 deletions FRW/Modules/Browser/Handler/JSMessageHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Selina on 5/9/2022.
//

import CryptoKit
import Flow
import TrustWeb3Provider
import UIKit
Expand All @@ -31,7 +32,7 @@ class JSMessageHandler: NSObject {
private var processingServiceType: FCLServiceType?
private var processingFCLResponse: FCLResponseProtocol?
private var readyToSignEnvelope: Bool = false

private var authzResponse: FCLAuthzResponse?
private weak var processingLinkAccountViewModel: ChildAccountLinkViewModel?
}

Expand Down Expand Up @@ -102,6 +103,24 @@ extension JSMessageHandler {
data: data
)
TransactionManager.shared.newTransaction(holder: holder)
Task {
do {
let result = try await id.onceSealed()
let voucher = authzResponse?.body.voucher
EventTrack.Transaction
.flowSigned(
cadence: hashCadence(
cadence: voucher?.cadence?
.toHexEncodedString() ?? ""
),
txId: tid,
authorizers: voucher?.authorizers ?? [],
proposer: voucher?.proposalKey.address ?? "",
payer: voucher?.payer ?? "",
success: !result.isFailed
)
} catch {}
}

if let linkAccountVM = processingLinkAccountViewModel {
linkAccountVM.onTxID(id)
Expand All @@ -110,6 +129,16 @@ extension JSMessageHandler {
log.error("invalid message", context: error)
}
}

private func hashCadence(cadence: String) -> String {
guard !cadence.isEmpty else {
return ""
}
let data = Data(cadence.utf8)
let hash = SHA256.hash(data: data)
let hashString = hash.compactMap { String(format: "%02x", $0) }.joined()
return hashString
}
}

extension JSMessageHandler {
Expand Down Expand Up @@ -331,7 +360,7 @@ extension JSMessageHandler {

log.debug("handle authz")
processingFCLResponse = authzResponse

self.authzResponse = authzResponse
if readyToSignEnvelope, authzResponse.isSignEnvelope {
log.debug("will sign envelope")
signEnvelope(authzResponse, url: url)
Expand Down
2 changes: 2 additions & 0 deletions FRW/Modules/Buy/BuyProvderView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct BuyProvderView: View {
Divider()

Button {
EventTrack.General.rampClick(source: .moonpay)
Task {
await launchMoonPay()
}
Expand All @@ -37,6 +38,7 @@ struct BuyProvderView: View {

if LocalUserDefaults.shared.flowNetwork == .mainnet {
Button {
EventTrack.General.rampClick(source: .coinbase)
guard let address = WalletManager.shared.getPrimaryWalletAddress(),
let url =
URL(
Expand Down
12 changes: 4 additions & 8 deletions FRW/Modules/EVM/ViewModel/EVMEnableViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,11 @@ class EVMEnableViewModel: ObservableObject {
func onClickEnable() {
let minBalance = 0.000
let result = WalletManager.shared.activatedCoins.filter { tokenModel in

if tokenModel.isFlowCoin {
log
.debug(
"[EVM] enable check balance: \(WalletManager.shared.getBalance(byId: tokenModel.contractId)) "
)
return WalletManager.shared
.getBalance(
byId: tokenModel.contractId
).doubleValue >= minBalance
let balance = WalletManager.shared.getBalance(byId: tokenModel.contractId)
log.debug("[EVM] enable check balance: \(balance)")
return balance.doubleValue >= minBalance
}
return false
}
Expand Down
17 changes: 15 additions & 2 deletions FRW/Modules/MultiBackup/Manager/MultiBackupManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ extension MultiBackupManager {
var updatedTime: Double? = Date.now.timeIntervalSince1970
let deviceInfo: DeviceInfoRequest?
var code: String?
var backupType: MultiBackupType? = .phrase

func showDate() -> String {
guard let updatedTime = updatedTime else { return "" }
Expand Down Expand Up @@ -265,11 +266,23 @@ extension MultiBackupManager {
switch type {
case .google:
try await login(from: type)
return try await gdTarget.getCurrentDriveItems()
var list = try await gdTarget.getCurrentDriveItems()
list = list.map { item in
var model = item
model.backupType = type
return model
}
return list
case .passkey:
return []
case .icloud:
return try await iCloudTarget.getCurrentDriveItems()
var list = try await iCloudTarget.getCurrentDriveItems()
list = list.map { item in
var model = item
model.backupType = type
return model
}
return list
case .phrase:
return []
}
Expand Down
15 changes: 14 additions & 1 deletion FRW/Modules/MultiBackup/ViewModel/BackupMultiViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class BackupMultiViewModel: ObservableObject {

// MARK: - MultiBackupType

enum MultiBackupType: Int, CaseIterable {
enum MultiBackupType: Int, CaseIterable, Codable {
case google = 0
case passkey = 1
case icloud = 2
Expand Down Expand Up @@ -152,6 +152,19 @@ enum MultiBackupType: Int, CaseIterable {
return "icon.recovery"
}
}

func methodName() -> String {
switch self {
case .google:
return "google_drive"
case .passkey:
return "passkey"
case .icloud:
return "icloud"
case .phrase:
return "seed_phrase"
}
}
}

// MARK: - BackupMultiViewModel.MultiItem
Expand Down
20 changes: 19 additions & 1 deletion FRW/Modules/MultiBackup/ViewModel/BackupUploadViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ class BackupUploadViewModel: ObservableObject {
}
} catch {
buttonState = .enabled
trackCreatFailed(message: "idle:" + error.localizedDescription)
}
}
case .upload:
Expand All @@ -189,6 +190,7 @@ class BackupUploadViewModel: ObservableObject {
buttonState = .enabled
hasError = true
log.error(error)
trackCreatFailed(message: "upload:" + error.localizedDescription)
}
}
case .regist:
Expand All @@ -204,12 +206,13 @@ class BackupUploadViewModel: ObservableObject {
self.buttonState = .enabled
}
toggleProcess(process: .finish)
// onClickButton()
trackCreatSuccess()

} catch {
buttonState = .enabled
HUD.dismissLoading()
log.error(error)
trackCreatFailed(message: "register:" + error.localizedDescription)
}
}
case .finish:
Expand All @@ -233,3 +236,18 @@ class BackupUploadViewModel: ObservableObject {
}
}
}

extension BackupUploadViewModel {
private func trackSource() -> String {
return currentType.methodName()
}

func trackCreatSuccess() {
EventTrack.Backup.multiCreated(source: trackSource())
}

func trackCreatFailed(message: String) {
EventTrack.Backup
.multiCreatedFailed(source: trackSource(), reason: message)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ class RestoreMultiAccountViewModel: ObservableObject {
return
}

if let item = selectedUser.first {
let methods = selectedUser.map { $0.backupType?.methodName() ?? "" }
EventTrack.Account
.recovered(address: item.address, mechanism: "multi-backup", methods: methods)
}

// If it is the current user, do nothing and return directly.
if let userId = UserManager.shared.activatedUID, userId == selectedUserId {
if (try? WallectSecureEnclave.Store.fetchModel(by: selectedUserId)) != nil {
Expand Down Expand Up @@ -74,6 +80,7 @@ class RestoreMultiAccountViewModel: ObservableObject {
guard selectedUser.count > 1 else {
return
}

Task {
do {
HUD.loading()
Expand Down
24 changes: 23 additions & 1 deletion FRW/Modules/NFT/NFTTransferView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,19 @@ class NFTTransferViewModel: ObservableObject {
case coa
case eoa
case linked

var trackName: String {
switch self {
case .flow:
"flow"
case .coa:
"coa"
case .eoa:
"evm"
case .linked:
"child"
}
}
}

if isRequesting {
Expand Down Expand Up @@ -335,7 +348,16 @@ class NFTTransferViewModel: ObservableObject {
failedBlock()
return
}

EventTrack.Transaction
.NFTTransfer(
from: currentAddress,
to: toAddress,
identifier: nft.response.flowIdentifier ?? "",
txId: tid?.hex ?? "",
fromType: fromAccountType.trackName,
toType: toAccountType.trackName,
isMove: false
)
let model = NFTTransferModel(
nft: nft,
target: self.targetContact,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ class ProfileSecureViewModel: ObservableObject {
}

if !isEnabled {
EventTrack.General.security(type: .none)
SecurityManager.shared.disableBionic()
isBionicEnabled = false
return
}

EventTrack.General.security(type: .bionic)
zhouxl marked this conversation as resolved.
Show resolved Hide resolved
Task {
let result = await SecurityManager.shared.enableBionic()
if !result {
Expand All @@ -47,12 +48,12 @@ class ProfileSecureViewModel: ObservableObject {
HUD.error(title: "disable_pin_code_failed".localized)
return
}

EventTrack.General.security(type: .none)
HUD.success(title: "pin_code_disabled".localized)
isPinCodeEnabled = false
return
}

EventTrack.General.security(type: .pin)
Router.route(to: RouteMap.PinCode.pinCode)
}

Expand Down
7 changes: 7 additions & 0 deletions FRW/Modules/Staking/StakeAmount/StakeAmountViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,13 @@ extension StakeAmountViewModel {
"StakeAmountViewModel: provider.delegatorId is nil, will create delegator id"
)
// create delegator id to stake (only first time)
let address = WalletManager.shared.getPrimaryWalletAddress() ?? ""
EventTrack.General
.delegationCreated(
address: address,
nodeId: provider.id,
amount: inputTextNum
)
return try await FlowNetwork.createDelegatorId(
providerId: provider.id,
amount: inputTextNum
Expand Down
3 changes: 3 additions & 0 deletions FRW/Modules/TrustProvider/TrustJSMessageHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -383,8 +383,11 @@ extension TrustJSMessageHandler {
if result.isFailed {
HUD.error(title: "transaction failed")
self.cancel(id: id)
EventTrack.Transaction
.evmSigned(txId: txid.hex, success: false)
return
}
EventTrack.Transaction.evmSigned(txId: txid.hex, success: true)
let model = try await FlowNetwork.fetchEVMTransactionResult(txid: txid.hex)
DispatchQueue.main.async {
self.webVC?.webView.tw
Expand Down
Loading