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/private key import copy #591

Merged
merged 48 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
d577753
feat: keystore first
zhouxl Aug 23, 2024
ab01b61
Merge branch 'feature/2.1.12' into feature/2.1.12-multiplekey
zhouxl Sep 10, 2024
c310ea9
feat: reconstruct with FlowWalletKit
zhouxl Sep 10, 2024
fa4b7da
feat: update Flow Wallet SDK
zhouxl Sep 13, 2024
8518965
Merge branch 'feature/2.1.12-multiplekey' into feature/2.1.13
zhouxl Sep 26, 2024
df72ca8
feat: update import key store logic
zhouxl Sep 26, 2024
45f4b4e
feat: update logic of import key
zhouxl Sep 27, 2024
ca5eaa2
feat: seed phrase import
zhouxl Sep 27, 2024
b84c1db
feat: udpate app version
zhouxl Sep 27, 2024
efdebe6
feat: change flowdiver to flowscan and open with inapp browser
zhouxl Sep 27, 2024
0bc7eeb
feat: update import UI
zhouxl Sep 27, 2024
e1c856f
fix: update foreground color of copy on receive page
zhouxl Sep 27, 2024
801c9db
feat: change flowdiver to flowscan
zhouxl Sep 27, 2024
5108e0d
feat: import by seed phrase with name
zhouxl Sep 27, 2024
43a2782
Merge branch 'develop' into feat/private-key-import
zhouxl Nov 11, 2024
4b6b064
feat: format code
zhouxl Nov 11, 2024
39322c0
feat: update close icon
zhouxl Nov 11, 2024
6df0bf0
feat: udpate close icon
zhouxl Nov 11, 2024
c168eab
Merge branch 'develop' into feat/private-key-import
zhouxl Nov 12, 2024
99cc1af
feat: swiftformat
zhouxl Nov 12, 2024
243d1ad
feat: format
zhouxl Nov 12, 2024
c797a10
code format 2
zhouxl Nov 12, 2024
581c280
feat: update key
zhouxl Nov 26, 2024
c37a568
Merge branch 'develop' into feat/private-key-import-copy
zhouxl Nov 26, 2024
7595b22
feat: remove some comments
zhouxl Nov 26, 2024
86da39d
feat: format code
zhouxl Nov 26, 2024
97b5c89
feat: update xproj config
zhouxl Nov 26, 2024
d6bfb57
fix: private key [#594]
zhouxl Nov 27, 2024
ebb4e86
feat: add toast if error[#594]
zhouxl Nov 29, 2024
2fe156c
feat: handle error of invaildKeyStoreJSON
zhouxl Dec 2, 2024
38ab964
feat: restore
zhouxl Dec 2, 2024
73b49f9
feat: add tag final for class
zhouxl Dec 4, 2024
6e8fa55
Merge branch 'develop' into feat/private-key-import-copy
zhouxl Dec 5, 2024
93112aa
feat: update version
zhouxl Dec 5, 2024
74534ab
fix: store all info of seed phrase
zhouxl Dec 5, 2024
9207849
feat: event track for ft/nft transaction
zhouxl Dec 5, 2024
b0893a1
feat: update cadence from `getDelegatesInfoArray` to `getDelegatesInf…
zhouxl Dec 5, 2024
c55f355
feat: UI for keychain list
zhouxl Dec 5, 2024
12cd507
feat: keychainview Item add delete and copy button
zhouxl Dec 6, 2024
da3148a
feat: update UI
zhouxl Dec 6, 2024
ef87a57
feat: update logic about private key
zhouxl Dec 8, 2024
0afbe11
feat: update to WalletManager.decryptionChaChaPoly
zhouxl Dec 8, 2024
258a1b5
fix: remove `.key.` on key of keychain list
zhouxl Dec 8, 2024
d4f84be
fix: decode failed
zhouxl Dec 9, 2024
1547154
fix: udpate user with id and public key
zhouxl Dec 9, 2024
71db0e2
feat: remove dev tool
zhouxl Dec 9, 2024
e005efa
feat: rename method
zhouxl Dec 9, 2024
a7f20e8
Merge branch 'develop' into feat/private-key-import-copy
zhouxl Dec 9, 2024
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
217 changes: 157 additions & 60 deletions FRW.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
{
"identity" : "flow-swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/outblock/flow-swift",
"location" : "https://github.com/outblock/flow-swift.git",
"state" : {
"revision" : "50b60826c4ce18adaa151946d11d468ac1fc98dd",
"version" : "0.3.9"
Expand All @@ -141,7 +141,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/Outblock/Flow-Wallet-Kit",
"state" : {
"revision" : "d1f877f15bf1574bf64d75631f0187197a665b53"
"branch" : "master",
"revision" : "ff1688af156e51ef4257a818ab906301a241508d"
}
},
{
Expand Down Expand Up @@ -654,6 +655,15 @@
"version" : "3.1.0"
}
},
{
"identity" : "wallet-core",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Outblock/wallet-core",
"state" : {
"branch" : "master",
"revision" : "24497b1e6f34f171ad421dae8699758bda09e78d"
}
},
{
"identity" : "wallet-mobile-sdk",
"kind" : "remoteSourceControl",
Expand Down
2 changes: 1 addition & 1 deletion FRW/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class AppDelegate: NSObject, UIApplicationDelegate {
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
_ = LocalEnvManager.shared

SecureEnclaveMigration.start()
FirebaseApp.configure()

Analytics.setAnalyticsCollectionEnabled(true)
Expand Down
2 changes: 1 addition & 1 deletion FRW/App/Env/Dev/EnvDefine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import Foundation

let AppGroupName = "group.com.flowfoundation.wallet.dev"
let AppBundleName = "com.flowfoundation.wallet.dev"
let isDevModel = true

let FirstFavNFTImageURL = "FirstFavNFTImageURL"

func groupUserDefaults() -> UserDefaults? {
Expand Down
1 change: 1 addition & 0 deletions FRW/App/Env/Prod/EnvDefine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Foundation

let AppGroupName = "group.com.flowfoundation.wallet"
let AppBundleName = "com.flowfoundation.wallet"
let isDevModel = false
let FirstFavNFTImageURL = "FirstFavNFTImageURL"

Expand Down
2 changes: 1 addition & 1 deletion FRW/App/Env/Prod/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>2.2.11</string>
<string>2.3.0</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
Expand Down
15 changes: 15 additions & 0 deletions FRW/Foundation/Base/FlowLog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ extension FlowLog {
}
}

// MARK: - FlowLog.Prefix

extension FlowLog {
enum Prefix {
case cadence
case netword
case ui
case walletconnect

case main
case evm
case linked
}
}

// MARK: Levels

extension FlowLog {
Expand Down
11 changes: 11 additions & 0 deletions FRW/Foundation/Model/AddressBookInfoModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ struct Contact: Codable, Identifiable {
case flow
case evm
case link

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

let address, avatar, contactName: String?
Expand Down
31 changes: 2 additions & 29 deletions FRW/Modules/Browser/Handler/JSMessageHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ extension JSMessageHandler {
}

guard let processingAuthzTransaction = processingAuthzTransaction,
let data = try? JSONEncoder().encode(processingAuthzTransaction) else {
let data = try? JSONEncoder().encode(processingAuthzTransaction)
else {
log.error("no processingAuthzTransaction")
return
}
Expand All @@ -103,24 +104,6 @@ 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 @@ -129,16 +112,6 @@ 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
3 changes: 2 additions & 1 deletion FRW/Modules/Login/ChooseAccountView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ struct ChooseAccountView: RouteableView {
var listView: some View {
ScrollView(.vertical, showsIndicators: false) {
LazyVStack(spacing: 12) {
ForEach(vm.items, id: \.username) { item in
ForEach(0 ..< vm.items.count, id: \.self) { index in
let item = vm.items[index]
Button {
vm.restoreAccountAction(item: item)
} label: {
Expand Down
193 changes: 193 additions & 0 deletions FRW/Modules/Login/ImportAccountsView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
//
// ImportAccountsView.swift
// FRW
//
// Created by cat on 2024/8/19.
//

import Flow
import SwiftUI
import SwiftUIX

// MARK: - ImportAccountsViewModel

class ImportAccountsViewModel: ObservableObject {
// MARK: Lifecycle

init(list: [Flow.Account], onSelectAddress: @escaping (Flow.Account) -> Void) {
self.list = list
self.onSelectAddress = onSelectAddress
}

// MARK: Internal

var list: [Flow.Account] = []
var onSelectAddress: (Flow.Account) -> Void
}

// MARK: - ImportAccountsView

struct ImportAccountsView: RouteableView, PresentActionDelegate {
// MARK: Lifecycle

init(viewModel: ImportAccountsViewModel) {
_viewModel = StateObject(wrappedValue: viewModel)
}

// MARK: Internal

var changeHeight: (() -> Void)?

@StateObject
var viewModel: ImportAccountsViewModel

var title: String {
""
}

var body: some View {
VStack(spacing: 0) {
ZStack(alignment: .topTrailing) {
HStack(alignment: .center) {
Spacer()
Text(headerTitle)
.font(.inter(size: 24, weight: .bold))
.foregroundStyle(
viewModel.list.isEmpty ? Color.Theme.Accent.orange : Color
.Theme.Accent.green
)
Spacer()
}

Button {
onClose()
} label: {
Image("icon_close_circle_gray")
.resizable()
.frame(width: 24, height: 24)
.padding(4)
.offset(y: -6)
}
}
.frame(height: 40)
.padding(.top, 18)

Text("choose_account_import".localized)
.font(.inter(size: 14))
.multilineTextAlignment(.center)
.foregroundStyle(Color.Theme.Text.black3)
.padding(.top, 20)
.visibility(viewModel.list.isEmpty ? .gone : .visible)

ScrollView(showsIndicators: false) {
VStack {
ForEach(viewModel.list.indices, id: \.self) { index in
let account = viewModel.list[index]
let isSelected = (account.address.hex == selectedAccount?.address.hex)
ImportAccountsView
.Item(account: account, isSelected: isSelected) { itemAccount in
self.selectedAccount = itemAccount
}
}
}
}
.padding(.top, 28)
.visibility(viewModel.list.isEmpty ? .gone : .visible)

Spacer()
Text("import_no_account_found".localized)
.font(.inter(size: 14))
.multilineTextAlignment(.center)
.foregroundStyle(Color.Theme.Text.black)
.padding(.horizontal, 27)
.visibility(viewModel.list.isEmpty ? .visible : .gone)

Spacer()

Button {
if let account = selectedAccount {
onClose()
viewModel.onSelectAddress(account)
}
} label: {
Text(buttonTitle())
.font(.inter(size: 16, weight: .semibold))
.frame(maxWidth: .infinity)
.frame(height: 54)
.foregroundColor(Color.LL.frontColor)
.background(selectedAccount == nil ? Color.LL.disable : Color.LL.rebackground)
.cornerRadius(16)
}
.disabled(selectedAccount == nil)
.padding(.bottom, 42)
}
.padding(.horizontal, 18)
.backgroundFill(.Theme.Background.bg2)
.cornerRadius([.topLeading, .topTrailing], 16)
.applyRouteable(self)
.ignoresSafeArea()
}

var headerTitle: String {
if viewModel.list.isEmpty {
return "no_account_found".localized
}
return "x_account_found_title".localized("\(viewModel.list.count)")
}

func onClose() {
Router.dismiss()
}

// MARK: Private

@State
private var selectedAccount: Flow.Account?

private func buttonTitle() -> String {
if selectedAccount == nil {
return "import_btn_text".localized.uppercasedFirstLetter()
}
return "import_x_wallet".localized("1")
}
}

// MARK: ImportAccountsView.Item

extension ImportAccountsView {
struct Item: View {
let account: Flow.Account
var isSelected: Bool = false
var onClick: (Flow.Account) -> Void

var body: some View {
HStack {
Text(account.address.hex)
.font(.inter(size: 14, weight: isSelected ? .semibold : .regular))
.truncationMode(.middle)
.lineLimit(1)
.foregroundStyle(Color.Theme.Text.black)

Spacer()

Image(isSelected ? "icon_check_rounde_1" : "icon_check_rounde_0")
.resizable()
.frame(width: 16, height: 16)
}
.padding(.horizontal, 24)
.frame(height: 56)
.contentShape(Rectangle())
.background(isSelected ? Color.Theme.Background.pureWhite : .clear)
.onTapGesture {
onClick(account)
}
.cornerRadius(16)
}
}
}

#Preview {
ImportAccountsView(viewModel: ImportAccountsViewModel(list: [], onSelectAddress: { _ in

}))
}
Loading