Skip to content

Commit

Permalink
do xpubs too
Browse files Browse the repository at this point in the history
  • Loading branch information
reez committed Nov 10, 2024
1 parent 3a91a13 commit 67a70a9
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 17 deletions.
51 changes: 51 additions & 0 deletions BDKSwiftExampleWallet/Service/BDK Service/BDKService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,52 @@ private class BDKService {
self.wallet = wallet
}

func createWallet(xpub: String?) throws {
let documentsDirectoryURL = URL.documentsDirectory
let walletDataDirectoryURL = documentsDirectoryURL.appendingPathComponent("wallet_data")

if FileManager.default.fileExists(atPath: walletDataDirectoryURL.path) {
try FileManager.default.removeItem(at: walletDataDirectoryURL)
} else {
}

let baseUrl =
try keyClient.getEsploraURL() ?? Constants.Config.EsploraServerURLNetwork.Signet.mutiny

guard let xpubString = xpub, !xpubString.isEmpty else {
throw WalletError.walletNotFound
}

let descriptorString = "tr(\(xpubString)/0/*)"
let changeDescriptorString = "tr(\(xpubString)/1/*)"
let descriptor = try Descriptor(descriptor: descriptorString, network: network)
let changeDescriptor = try Descriptor(descriptor: changeDescriptorString, network: network)

let backupInfo = BackupInfo(
mnemonic: "",
descriptor: descriptor.toStringWithSecret(),
changeDescriptor: changeDescriptor.toStringWithSecret()
)

try keyClient.saveBackupInfo(backupInfo)
try keyClient.saveNetwork(self.network.description)
try keyClient.saveEsploraURL(baseUrl)

try FileManager.default.ensureDirectoryExists(at: walletDataDirectoryURL)
try FileManager.default.removeOldFlatFileIfNeeded(at: documentsDirectoryURL)
let persistenceBackendPath = walletDataDirectoryURL.appendingPathComponent("wallet.sqlite")
.path
let connection = try Connection(path: persistenceBackendPath)
self.connection = connection
let wallet = try Wallet(
descriptor: descriptor,
changeDescriptor: changeDescriptor,
network: network,
connection: connection
)
self.wallet = wallet
}

private func loadWallet(descriptor: Descriptor, changeDescriptor: Descriptor) throws {
let documentsDirectoryURL = URL.documentsDirectory
let walletDataDirectoryURL = documentsDirectoryURL.appendingPathComponent("wallet_data")
Expand Down Expand Up @@ -362,6 +408,7 @@ struct BDKClient {
let deleteWallet: () throws -> Void
let createWalletFromSeed: (String?) throws -> Void
let createWalletFromDescriptor: (String?) throws -> Void
let createWalletFromXPub: (String?) throws -> Void
let getBalance: () throws -> Balance
let transactions: () throws -> [CanonicalTx]
let listUnspent: () throws -> [LocalOutput]
Expand Down Expand Up @@ -390,6 +437,9 @@ extension BDKClient {
createWalletFromDescriptor: { descriptor in
try BDKService.shared.createWallet(descriptor: descriptor)
},
createWalletFromXPub: { xpub in
try BDKService.shared.createWallet(xpub: xpub)
},
getBalance: { try BDKService.shared.getBalance() },
transactions: { try BDKService.shared.transactions() },
listUnspent: { try BDKService.shared.listUnspent() },
Expand Down Expand Up @@ -440,6 +490,7 @@ extension BDKClient {
deleteWallet: {},
createWalletFromSeed: { _ in },
createWalletFromDescriptor: { _ in },
createWalletFromXPub: { _ in },
getBalance: { .mock },
transactions: {
return [
Expand Down
25 changes: 13 additions & 12 deletions BDKSwiftExampleWallet/View Model/OnboardingViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ import SwiftUI
class OnboardingViewModel: ObservableObject {
let bdkClient: BDKClient

@AppStorage("isOnboarding") var isOnboarding: Bool?
@Published var createWithPersistError: CreateWithPersistError?
var isDescriptor: Bool {
words.hasPrefix("tr(") || words.hasPrefix("wpkh(") || words.hasPrefix("wsh(")
|| words.hasPrefix("sh(")
}

@AppStorage("isOnboarding") var isOnboarding: Bool?
@Published var createWithPersistError: CreateWithPersistError?
var isXPub: Bool {
words.hasPrefix("xpub") || words.hasPrefix("tpub")
}
@Published var networkColor = Color.gray
@Published var onboardingViewError: AppError?
@Published var selectedNetwork: Network = .signet {
Expand All @@ -36,12 +38,14 @@ class OnboardingViewModel: ObservableObject {
bdkClient.updateEsploraURL(selectedURL)
}
}
@Published var words: String = "" {
didSet {
updateWordArray()
@Published var words: String = ""
var wordArray: [String] {
if words.hasPrefix("xpub") || words.hasPrefix("tpub") {
return []
}
let trimmedWords = words.trimmingCharacters(in: .whitespacesAndNewlines)
return trimmedWords.components(separatedBy: " ")
}
@Published var wordArray: [String] = []
var availableURLs: [String] {
switch selectedNetwork {
case .bitcoin:
Expand Down Expand Up @@ -79,6 +83,8 @@ class OnboardingViewModel: ObservableObject {
do {
if isDescriptor {
try bdkClient.createWalletFromDescriptor(words)
} else if isXPub {
try bdkClient.createWalletFromXPub(words)
} else {
try bdkClient.createWalletFromSeed(words)
}
Expand All @@ -95,9 +101,4 @@ class OnboardingViewModel: ObservableObject {
}
}
}

private func updateWordArray() {
let trimmedWords = words.trimmingCharacters(in: .whitespacesAndNewlines)
wordArray = trimmedWords.split(separator: " ").map { String($0) }
}
}
10 changes: 5 additions & 5 deletions BDKSwiftExampleWallet/View/OnboardingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct OnboardingView: View {
HStack {
Spacer()
Button {
if viewModel.wordArray.isEmpty {
if viewModel.words.isEmpty {
if let clipboardContent = UIPasteboard.general.string {
viewModel.words = clipboardContent
}
Expand All @@ -36,13 +36,13 @@ struct OnboardingView: View {
}
} label: {
Image(
systemName: viewModel.wordArray.isEmpty
systemName: viewModel.words.isEmpty
? "arrow.down.square" : "clear"
)
.contentTransition(.symbolEffect(.replace))
}
.tint(
viewModel.wordArray.isEmpty ? .secondary : .primary
viewModel.words.isEmpty ? .secondary : .primary
)
.font(.title)
.padding()
Expand Down Expand Up @@ -108,8 +108,8 @@ struct OnboardingView: View {
.pickerStyle(.automatic)
.tint(.primary)

if viewModel.wordArray != [] {
if viewModel.isDescriptor {
if !viewModel.words.isEmpty {
if viewModel.isDescriptor || viewModel.isXPub {
Text(viewModel.words)
.font(.system(.caption, design: .monospaced))
.lineLimit(1)
Expand Down

0 comments on commit 67a70a9

Please sign in to comment.