diff --git a/Bitkit.xcodeproj/project.pbxproj b/Bitkit.xcodeproj/project.pbxproj
index ac05ca57..cac379d6 100644
--- a/Bitkit.xcodeproj/project.pbxproj
+++ b/Bitkit.xcodeproj/project.pbxproj
@@ -14,7 +14,6 @@
961058EA2C35793000E1F1D8 /* LnPeer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9637E6DE2C32ED7B004A92FC /* LnPeer.swift */; };
961058EB2C35793000E1F1D8 /* WalletNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9637E6DC2C32EAA8004A92FC /* WalletNetwork.swift */; };
961058EE2C35798C00E1F1D8 /* LDKNode in Frameworks */ = {isa = PBXBuildFile; productRef = 961058ED2C35798C00E1F1D8 /* LDKNode */; };
- 961058F02C35799400E1F1D8 /* BitcoinDevKit in Frameworks */ = {isa = PBXBuildFile; productRef = 961058EF2C35799400E1F1D8 /* BitcoinDevKit */; };
961301882C50202A00878183 /* MigrationsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961301872C50202A00878183 /* MigrationsService.swift */; };
9613018C2C5022D700878183 /* SQLite in Frameworks */ = {isa = PBXBuildFile; productRef = 9613018B2C5022D700878183 /* SQLite */; };
9613018E2C50288900878183 /* LdkMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9613018D2C50288900878183 /* LdkMigration.swift */; };
@@ -25,7 +24,6 @@
962B92252C5A4F5D00B21057 /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 962B92242C5A4F5D00B21057 /* ViewModel.swift */; };
9637E6D32C32CE79004A92FC /* Env.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9637E6D22C32CE79004A92FC /* Env.swift */; };
9637E6D52C32D811004A92FC /* OnChainService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9637E6D42C32D811004A92FC /* OnChainService.swift */; };
- 9637E6D82C32D8A7004A92FC /* BitcoinDevKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9637E6D72C32D8A7004A92FC /* BitcoinDevKit */; };
9637E6DA2C32E573004A92FC /* OnChainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9637E6D92C32E573004A92FC /* OnChainViewModel.swift */; };
9637E6DD2C32EAA8004A92FC /* WalletNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9637E6DC2C32EAA8004A92FC /* WalletNetwork.swift */; };
9637E6DF2C32ED7B004A92FC /* LnPeer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9637E6DE2C32ED7B004A92FC /* LnPeer.swift */; };
@@ -47,6 +45,8 @@
966DE6722C512C1E00A7B0EF /* seed.bin in Resources */ = {isa = PBXBuildFile; fileRef = 966DE6712C512C1E00A7B0EF /* seed.bin */; };
966DE6742C512C9300A7B0EF /* HexBytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 966DE6732C512C9300A7B0EF /* HexBytes.swift */; };
966DE6752C512FD100A7B0EF /* HexBytes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 966DE6732C512C9300A7B0EF /* HexBytes.swift */; };
+ 968A68082C6B6D1F00D4C7CD /* BitcoinDevKit in Frameworks */ = {isa = PBXBuildFile; productRef = 968A68072C6B6D1F00D4C7CD /* BitcoinDevKit */; };
+ 968A680F2C6BA5EC00D4C7CD /* BitcoinDevKit in Frameworks */ = {isa = PBXBuildFile; productRef = 968A680E2C6BA5EC00D4C7CD /* BitcoinDevKit */; };
96B129FD2C2EC05D00DD07B0 /* LDKNode in Frameworks */ = {isa = PBXBuildFile; productRef = 96B129FC2C2EC05D00DD07B0 /* LDKNode */; };
96B12A002C2EC37B00DD07B0 /* LightningViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B129FF2C2EC37B00DD07B0 /* LightningViewModel.swift */; };
96B12A032C2EC65000DD07B0 /* LightningService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B12A022C2EC65000DD07B0 /* LightningService.swift */; };
@@ -150,7 +150,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 961058F02C35799400E1F1D8 /* BitcoinDevKit in Frameworks */,
961058EE2C35798C00E1F1D8 /* LDKNode in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -159,9 +158,10 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 968A68082C6B6D1F00D4C7CD /* BitcoinDevKit in Frameworks */,
9613018C2C5022D700878183 /* SQLite in Frameworks */,
- 9637E6D82C32D8A7004A92FC /* BitcoinDevKit in Frameworks */,
966DE6702C51210000A7B0EF /* LightningDevKit in Frameworks */,
+ 968A680F2C6BA5EC00D4C7CD /* BitcoinDevKit in Frameworks */,
96B129FD2C2EC05D00DD07B0 /* LDKNode in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -389,7 +389,6 @@
name = BitkitNotification;
packageProductDependencies = (
961058ED2C35798C00E1F1D8 /* LDKNode */,
- 961058EF2C35799400E1F1D8 /* BitcoinDevKit */,
);
productName = BitkitNotification;
productReference = 961058DC2C355B5500E1F1D8 /* BitkitNotification.appex */;
@@ -412,9 +411,10 @@
name = Bitkit;
packageProductDependencies = (
96B129FC2C2EC05D00DD07B0 /* LDKNode */,
- 9637E6D72C32D8A7004A92FC /* BitcoinDevKit */,
9613018B2C5022D700878183 /* SQLite */,
966DE66F2C51210000A7B0EF /* LightningDevKit */,
+ 968A68072C6B6D1F00D4C7CD /* BitcoinDevKit */,
+ 968A680E2C6BA5EC00D4C7CD /* BitcoinDevKit */,
);
productName = Bitkit;
productReference = 96FE1F612C2DE6AA006D0C8B /* Bitkit.app */;
@@ -493,9 +493,9 @@
mainGroup = 96FE1F582C2DE6AA006D0C8B;
packageReferences = (
96B129FB2C2EC05D00DD07B0 /* XCRemoteSwiftPackageReference "ldk-node" */,
- 9637E6D62C32D8A7004A92FC /* XCRemoteSwiftPackageReference "bdk-swift" */,
961301892C50215500878183 /* XCRemoteSwiftPackageReference "SQLite.swift" */,
966DE66E2C51210000A7B0EF /* XCRemoteSwiftPackageReference "ldk-swift" */,
+ 968A680D2C6BA5EC00D4C7CD /* XCRemoteSwiftPackageReference "bdk-swift" */,
);
productRefGroup = 96FE1F622C2DE6AA006D0C8B /* Products */;
projectDirPath = "";
@@ -1042,20 +1042,20 @@
minimumVersion = 0.15.3;
};
};
- 9637E6D62C32D8A7004A92FC /* XCRemoteSwiftPackageReference "bdk-swift" */ = {
+ 966DE66E2C51210000A7B0EF /* XCRemoteSwiftPackageReference "ldk-swift" */ = {
isa = XCRemoteSwiftPackageReference;
- repositoryURL = "https://github.com/bitcoindevkit/bdk-swift";
+ repositoryURL = "https://github.com/lightningdevkit/ldk-swift/";
requirement = {
kind = upToNextMajorVersion;
- minimumVersion = 0.31.1;
+ minimumVersion = 0.0.123;
};
};
- 966DE66E2C51210000A7B0EF /* XCRemoteSwiftPackageReference "ldk-swift" */ = {
+ 968A680D2C6BA5EC00D4C7CD /* XCRemoteSwiftPackageReference "bdk-swift" */ = {
isa = XCRemoteSwiftPackageReference;
- repositoryURL = "https://github.com/lightningdevkit/ldk-swift/";
+ repositoryURL = "https://github.com/bitcoindevkit/bdk-swift";
requirement = {
- kind = upToNextMajorVersion;
- minimumVersion = 0.0.123;
+ kind = exactVersion;
+ version = "1.0.0-alpha.11";
};
};
96B129FB2C2EC05D00DD07B0 /* XCRemoteSwiftPackageReference "ldk-node" */ = {
@@ -1074,26 +1074,25 @@
package = 96B129FB2C2EC05D00DD07B0 /* XCRemoteSwiftPackageReference "ldk-node" */;
productName = LDKNode;
};
- 961058EF2C35799400E1F1D8 /* BitcoinDevKit */ = {
- isa = XCSwiftPackageProductDependency;
- package = 9637E6D62C32D8A7004A92FC /* XCRemoteSwiftPackageReference "bdk-swift" */;
- productName = BitcoinDevKit;
- };
9613018B2C5022D700878183 /* SQLite */ = {
isa = XCSwiftPackageProductDependency;
package = 961301892C50215500878183 /* XCRemoteSwiftPackageReference "SQLite.swift" */;
productName = SQLite;
};
- 9637E6D72C32D8A7004A92FC /* BitcoinDevKit */ = {
- isa = XCSwiftPackageProductDependency;
- package = 9637E6D62C32D8A7004A92FC /* XCRemoteSwiftPackageReference "bdk-swift" */;
- productName = BitcoinDevKit;
- };
966DE66F2C51210000A7B0EF /* LightningDevKit */ = {
isa = XCSwiftPackageProductDependency;
package = 966DE66E2C51210000A7B0EF /* XCRemoteSwiftPackageReference "ldk-swift" */;
productName = LightningDevKit;
};
+ 968A68072C6B6D1F00D4C7CD /* BitcoinDevKit */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = BitcoinDevKit;
+ };
+ 968A680E2C6BA5EC00D4C7CD /* BitcoinDevKit */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = 968A680D2C6BA5EC00D4C7CD /* XCRemoteSwiftPackageReference "bdk-swift" */;
+ productName = BitcoinDevKit;
+ };
96B129FC2C2EC05D00DD07B0 /* LDKNode */ = {
isa = XCSwiftPackageProductDependency;
package = 96B129FB2C2EC05D00DD07B0 /* XCRemoteSwiftPackageReference "ldk-node" */;
diff --git a/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
index 0a255e6b..313aedfe 100644
--- a/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -1,13 +1,13 @@
{
- "originHash" : "b03b44bd686d6a1f548992eefdc3c205f03696d1af255697a0c62fecb4ff0cca",
+ "originHash" : "3f0f9872ecfe9595f1ab9fcef16e75c938d36c73b6b4f98e5c13be4ca1ca1706",
"pins" : [
{
"identity" : "bdk-swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/bitcoindevkit/bdk-swift",
"state" : {
- "revision" : "f2398109ebd8759322f601d9938779f3cdf99a12",
- "version" : "0.31.1"
+ "revision" : "41392827e12a455685a2af8e6a0ae1d9e3549be5",
+ "version" : "1.0.0-alpha.11"
}
},
{
diff --git a/Bitkit.xcodeproj/project.xcworkspace/xcuserdata/jason.xcuserdatad/UserInterfaceState.xcuserstate b/Bitkit.xcodeproj/project.xcworkspace/xcuserdata/jason.xcuserdatad/UserInterfaceState.xcuserstate
index 34d487fb..f9932d4e 100644
Binary files a/Bitkit.xcodeproj/project.xcworkspace/xcuserdata/jason.xcuserdatad/UserInterfaceState.xcuserstate and b/Bitkit.xcodeproj/project.xcworkspace/xcuserdata/jason.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/Bitkit.xcodeproj/xcuserdata/jason.xcuserdatad/xcschemes/xcschememanagement.plist b/Bitkit.xcodeproj/xcuserdata/jason.xcuserdatad/xcschemes/xcschememanagement.plist
index fbe57dc5..e7890640 100644
--- a/Bitkit.xcodeproj/xcuserdata/jason.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/Bitkit.xcodeproj/xcuserdata/jason.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -19,22 +19,43 @@
isShown
orderHint
- 3
+ 4
SQLite (Playground) 2.xcscheme
isShown
orderHint
- 4
+ 5
- SQLite (Playground).xcscheme
+ SQLite (Playground) 3.xcscheme
isShown
orderHint
2
+ SQLite (Playground) 4.xcscheme
+
+ isShown
+
+ orderHint
+ 6
+
+ SQLite (Playground) 5.xcscheme
+
+ isShown
+
+ orderHint
+ 7
+
+ SQLite (Playground).xcscheme
+
+ isShown
+
+ orderHint
+ 3
+
SuppressBuildableAutocreation
diff --git a/Bitkit/Constants/Env.swift b/Bitkit/Constants/Env.swift
index e1e7ae57..4d6fdd48 100644
--- a/Bitkit/Constants/Env.swift
+++ b/Bitkit/Constants/Env.swift
@@ -32,6 +32,7 @@ struct Env {
static let network: WalletNetwork = .regtest
static let defaultWalletWordCount: WordCount = .words12
static let onchainWalletStopGap = UInt64(20)
+ static let esploraParallelRequests = UInt64(5)
static var esploraServerUrl: String {
switch network {
case .regtest:
@@ -107,7 +108,7 @@ struct Env {
switch network {
case .regtest:
return [
- .init(nodeId: "02b61365f14c5070465e014485fa91cee5a131cf2a4b7cb37309fcd1cc53975238", address: "192.168.0.106:9735")
+// .init(nodeId: "02b61365f14c5070465e014485fa91cee5a131cf2a4b7cb37309fcd1cc53975238", address: "192.168.0.106:9735")
]
case .bitcoin:
return []
diff --git a/Bitkit/Services/LightningService.swift b/Bitkit/Services/LightningService.swift
index 3b985056..830d24ed 100644
--- a/Bitkit/Services/LightningService.swift
+++ b/Bitkit/Services/LightningService.swift
@@ -93,6 +93,7 @@ class LightningService {
Logger.debug("Stopping node...")
try await ServiceQueue.background(.ldk) {
try node.stop()
+ self.node = nil
}
Logger.info("Node stopped")
}
diff --git a/Bitkit/Services/OnChainService.swift b/Bitkit/Services/OnChainService.swift
index c5a82173..16e229dd 100644
--- a/Bitkit/Services/OnChainService.swift
+++ b/Bitkit/Services/OnChainService.swift
@@ -11,17 +11,10 @@ import BitcoinDevKit
class OnChainService {
private var wallet: Wallet?
var currentWalletIndex: Int = 0
+ private var hasSynced = false
- private var blockchainConfig: BlockchainConfig {
- let esploraConfig = EsploraConfig(
- baseUrl: Env.esploraServerUrl,
- proxy: nil,
- concurrency: nil,
- stopGap: Env.onchainWalletStopGap,
- timeout: nil
- )
-
- return BlockchainConfig.esplora(config: esploraConfig)
+ private var esploraClient: EsploraClient {
+ EsploraClient(url: Env.esploraServerUrl)
}
static var shared = OnChainService()
@@ -53,22 +46,19 @@ class OnChainService {
keychain: .internal,
network: Env.network.bdkNetwork
)
-
- //TODO save to keychain
-
+
Logger.debug("Creating onchain wallet...")
let bdkStorage = Env.bdkStorage(walletIndex: walletIndex)
try FileManager.default.createDirectory(at: bdkStorage, withIntermediateDirectories: true, attributes: nil)
-
- let dbConfig = DatabaseConfig.sqlite(config: .init(path: bdkStorage.appendingPathComponent("db.sqlite").path))
-
+ let sqlitePath = bdkStorage.appendingPathComponent("db.sqlite").path
+
try await ServiceQueue.background(.bdk) {
self.wallet = try Wallet(
descriptor: descriptor,
changeDescriptor: changeDescriptor,
- network: Env.network.bdkNetwork,
- databaseConfig: dbConfig
+ persistenceBackendPath: sqlitePath,
+ network: Env.network.bdkNetwork
)
}
@@ -107,30 +97,59 @@ class OnChainService {
}
return try await ServiceQueue.background(.bdk) {
- let addressInfo = try wallet.getAddress(addressIndex: .new)
+ let addressInfo = try wallet.revealNextAddress(keychain: .external)
return addressInfo.address.asString()
}
}
- func sync() async throws {
+ /// Partial sync. Collects all revealed script pubkeys from the wallet keychain.
+ func syncWithRevealedSpks() async throws {
guard let wallet else {
throw AppError(serviceError: .onchainWalletNotInitialized)
}
Logger.debug("Syncing BDK...")
+
+ try await ServiceQueue.background(.bdk) {
+ let request = wallet.startSyncWithRevealedSpks()
+ let update = try self.esploraClient.sync(syncRequest: request, parallelRequests: 5)
+ try wallet.applyUpdate(update: update)
+
+ //TODO: persist wallet??
+ }
- let blockchain = try Blockchain(config: blockchainConfig)
+ hasSynced = true
+ Logger.info("BDK synced")
+ }
+
+ /// Required on restore or manually from settings. Performs a full scan of the wallet.
+ func fullScan() async throws {
+ guard let wallet else {
+ throw AppError(serviceError: .onchainWalletNotInitialized)
+ }
+
+ Logger.debug("Full on chain scan...")
+
try await ServiceQueue.background(.bdk) {
- try wallet.sync(blockchain: blockchain, progress: nil)
+ let request = wallet.startFullScan()
+ let update = try self.esploraClient.fullScan(
+ fullScanRequest: request,
+ stopGap: Env.onchainWalletStopGap,
+ parallelRequests: Env.esploraParallelRequests
+ )
+ try wallet.applyUpdate(update: update)
+ //TODO: persist wallet once BDK is updated to beta release
}
- Logger.info("BDK synced")
+ hasSynced = true
+
+ Logger.info("Full scan complete")
}
}
//MARK: UI Helpers (Published via OnChainViewModel)
extension OnChainService {
//TODO catch errors?
- var balance: Balance? { try? wallet?.getBalance() }
+ var balance: Balance? { hasSynced ? wallet?.getBalance() : nil }
}
diff --git a/Bitkit/Services/ServiceQueue.swift b/Bitkit/Services/ServiceQueue.swift
index ee372623..02a3c7fa 100644
--- a/Bitkit/Services/ServiceQueue.swift
+++ b/Bitkit/Services/ServiceQueue.swift
@@ -32,8 +32,9 @@ class ServiceQueue {
}
}
- static func background(_ service: ServiceTypes, _ blocking: @escaping () throws -> T) async throws -> T {
- try await withCheckedThrowingContinuation { continuation in
+ static func background(_ service: ServiceTypes, _ blocking: @escaping () throws -> T, functionName: String = #function) async throws -> T {
+ let startTime = CFAbsoluteTimeGetCurrent()
+ let result = try await withCheckedThrowingContinuation { continuation in
service.queue.async {
do {
let res = try blocking()
@@ -45,5 +46,10 @@ class ServiceQueue {
}
}
}
+
+ let timeElapsed = Double(round(100 * (CFAbsoluteTimeGetCurrent() - startTime)) / 100)
+ Logger.performance("\(functionName) took \(timeElapsed) seconds on \(service) queue")
+
+ return result
}
}
diff --git a/Bitkit/Utilities/Errors.swift b/Bitkit/Utilities/Errors.swift
index 92edec0b..e0076150 100644
--- a/Bitkit/Utilities/Errors.swift
+++ b/Bitkit/Utilities/Errors.swift
@@ -49,11 +49,6 @@ struct AppError: LocalizedError {
return
}
- if let bdkError = error as? BdkError {
- self.init(bdkError: bdkError)
- return
- }
-
self.init(message: "Error", debugMessage: error.localizedDescription)
}
@@ -90,15 +85,15 @@ struct AppError: LocalizedError {
Logger.error("\(message) [\(debugMessage ?? "")]", context: "service error")
}
- private init(bdkError: BdkError) {
- message = "Bdk error"
+ private init(bdkError: Error) {
+ message = "Onchain wallet error"
debugMessage = bdkError.localizedDescription
//TODO support all message types in switch case
-// switch bdkError as BdkError {
-// case .Bip32(message: let bdkMessage):
-// message = "BIP32 error"
-// debugMessage = bdkMessage
-// }
+ //CalculateFeeError
+ //CannotConnectError
+ //DescriptorError
+ //EsploraError
+ //PersistenceError
Logger.error("\(message) [\(debugMessage ?? "")]", context: "BdkError")
}
diff --git a/Bitkit/Utilities/Logger.swift b/Bitkit/Utilities/Logger.swift
index 5b0dd57a..a32647b9 100644
--- a/Bitkit/Utilities/Logger.swift
+++ b/Bitkit/Utilities/Logger.swift
@@ -31,6 +31,10 @@ class Logger {
handle("🧪🧪🧪: \(message)", context: context, file: file, function: function, line: line)
}
+ static func performance(_ message: Any, context: String = "", file: String = #file, function: String = #function, line: Int = #line) {
+ handle("PERF: \(message)", context: context, file: file, function: function, line: line)
+ }
+
private static func handle(_ message: Any, context: String = "", file: String = #file, function: String = #function, line: Int = #line) {
let fileName = URL(fileURLWithPath: file).lastPathComponent
let line = "\(message) \(context == "" ? "" : "- \(context) ")[\(fileName): \(function) line: \(line)]"
diff --git a/Bitkit/Utilities/StartupHandler.swift b/Bitkit/Utilities/StartupHandler.swift
index 77b15f40..e084b734 100644
--- a/Bitkit/Utilities/StartupHandler.swift
+++ b/Bitkit/Utilities/StartupHandler.swift
@@ -37,7 +37,7 @@ class StartupHandler {
/// - Returns: The generated mnemonic
static func createNewWallet(bip39Passphrase: String?, walletIndex: Int = 0) throws -> String {
let mnemonic = Mnemonic(wordCount: Env.defaultWalletWordCount).asString()
-
+
try Keychain.saveString(key: .bip39Mnemonic(index: walletIndex), str: mnemonic)
if let bip39Passphrase {
try Keychain.saveString(key: .bip39Passphrase(index: walletIndex), str: bip39Passphrase)
diff --git a/Bitkit/ViewModels/OnChainViewModel.swift b/Bitkit/ViewModels/OnChainViewModel.swift
index 0a817717..c59a0d30 100644
--- a/Bitkit/ViewModels/OnChainViewModel.swift
+++ b/Bitkit/ViewModels/OnChainViewModel.swift
@@ -41,11 +41,15 @@ class OnChainViewModel: ObservableObject {
address = try await OnChainService.shared.getAddress()
}
- func sync() async throws {
+ func sync(full: Bool = false) async throws {
isSyncing = true
syncState()
do {
- try await OnChainService.shared.sync()
+ if full {
+ try await OnChainService.shared.fullScan()
+ } else {
+ try await OnChainService.shared.syncWithRevealedSpks()
+ }
isSyncing = false
syncState()
} catch {
diff --git a/Bitkit/Views/Onboarding/WelcomeView.swift b/Bitkit/Views/Onboarding/WelcomeView.swift
index c31e437f..e72f6c1e 100644
--- a/Bitkit/Views/Onboarding/WelcomeView.swift
+++ b/Bitkit/Views/Onboarding/WelcomeView.swift
@@ -7,16 +7,20 @@
import SwiftUI
-struct WelcomeView: View {
+struct RestoreView: View {
@StateObject var viewModel = ViewModel.shared
- @State var bip39Passphrase: String?
+
+ @State var bip39Mnemonic = "play toss explain entire until buddy sign promote prepare artist crystal auction"
+ @State var bip39Passphrase: String? = nil
var body: some View {
VStack {
- Text("Welcome")
+ Text("Restore Wallet")
.font(.largeTitle)
- Form {
+ Form() {
+ TextField("BIP39 Mnemonic", text: $bip39Mnemonic)
+
TextField("BIP39 Passphrase", text: Binding(
get: { bip39Passphrase ?? "" },
set: { bip39Passphrase = $0.isEmpty ? nil : $0 }
@@ -24,6 +28,44 @@ struct WelcomeView: View {
}
HStack {
+ Button("Restore Wallet") {
+ do {
+ _ = try StartupHandler.restoreWallet(mnemonic: bip39Mnemonic, bip39Passphrase: bip39Passphrase)
+ //TODO: handle full sync here before revealing the UI so balances are pre populated
+ viewModel.setWalletExistsState()
+ } catch {
+ //TODO: show a error to user
+ Logger.error(error)
+ }
+ }
+ .padding()
+ }
+ .padding()
+ }
+ }
+}
+
+struct WelcomeView: View {
+ @StateObject var viewModel = ViewModel.shared
+ @State var bip39Passphrase: String?
+
+ @State var showRestore = false
+
+ var body: some View {
+ VStack {
+ Text("Welcome")
+ .font(.largeTitle)
+
+ Form {
+ Section("Optional passphrase") {
+ TextField("BIP39 Passphrase", text: Binding(
+ get: { bip39Passphrase ?? "" },
+ set: { bip39Passphrase = $0.isEmpty ? nil : $0 }
+ ))
+ }
+ }
+
+ VStack {
Button("Create Wallet") {
do {
_ = try StartupHandler.createNewWallet(bip39Passphrase: bip39Passphrase)
@@ -35,13 +77,16 @@ struct WelcomeView: View {
}
.padding()
-// Button("Restore Wallet") {
-// //TODO
-// }
-// .padding()
+ Button("Restore Wallet") {
+ showRestore = true
+ }
+ .padding()
}
.padding()
}
+ .sheet(isPresented: $showRestore) {
+ RestoreView()
+ }
}
}
diff --git a/Bitkit/Views/Wallets/HomeView.swift b/Bitkit/Views/Wallets/HomeView.swift
index 40cde2a5..a1cb64e5 100644
--- a/Bitkit/Views/Wallets/HomeView.swift
+++ b/Bitkit/Views/Wallets/HomeView.swift
@@ -37,7 +37,8 @@ struct HomeView: View {
}
if let onchainBalance = onChainViewModel.balance {
- Text("On Chain \(onchainBalance.total)")
+ Text("On Chain Pending \(onchainBalance.immature.toSat())")
+ Text("On Chain Total \(onchainBalance.total.toSat())")
}
}
@@ -158,7 +159,7 @@ struct HomeView: View {
.refreshable {
do {
try await withThrowingTaskGroup(of: Void.self) { group in
- group.addTask { try await onChainViewModel.sync() }
+ group.addTask { try await onChainViewModel.sync(full: true) }
group.addTask { try await lnViewModel.sync() }
try await group.waitForAll()
}