Skip to content

Commit

Permalink
feat: add network
Browse files Browse the repository at this point in the history
  • Loading branch information
reez authored Jan 29, 2024
1 parent 24a94c8 commit 2e3aaae
Show file tree
Hide file tree
Showing 9 changed files with 423 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,27 @@
import BitcoinDevKit
import Foundation

extension Network {
var description: String {
switch self {
case .bitcoin: return "bitcoin"
case .testnet: return "testnet"
case .signet: return "signet"
case .regtest: return "regtest"
}
}

init?(stringValue: String) {
switch stringValue {
case "bitcoin": self = .bitcoin
case "testnet": self = .testnet
case "signet": self = .signet
case "regtest": self = .regtest
default: return nil
}
}
}

#if DEBUG
let mockKeyClientNetwork = Network.regtest
#endif
21 changes: 21 additions & 0 deletions BDKSwiftExampleWallet/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@
},
"Are you sure you want to delete the seed?" : {

},
"Bitcoin" : {

},
"Bitcoin Wallet" : {
"localizations" : {
Expand All @@ -156,6 +159,9 @@
}
}
}
},
"Choose your Network." : {

},
"confirmed" : {
"localizations" : {
Expand Down Expand Up @@ -216,6 +222,9 @@
}
}
}
},
"Esplora Server" : {

},
"Fee" : {
"localizations" : {
Expand All @@ -236,6 +245,9 @@
}
}
}
},
"Network" : {

},
"Next" : {
"localizations" : {
Expand Down Expand Up @@ -279,6 +291,9 @@
}
}
}
},
"Regtest" : {

},
"sat/vb" : {
"localizations" : {
Expand Down Expand Up @@ -320,6 +335,9 @@
}
}
}
},
"Signet" : {

},
"Syncing" : {
"extractionState" : "manual",
Expand All @@ -331,6 +349,9 @@
}
}
}
},
"Testnet" : {

},
"To" : {
"localizations" : {
Expand Down
41 changes: 31 additions & 10 deletions BDKSwiftExampleWallet/Service/BDK Service/BDKService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,33 @@ import BitcoinDevKit
import Foundation

private class BDKService {
static var shared: BDKService = BDKService()
private var balance: Balance?
private var blockchainConfig: BlockchainConfig?
var network: Network = .signet
var network: Network
private var wallet: Wallet?
private let keyService: KeyClient

class var shared: BDKService {
struct Singleton {
static let instance = BDKService()
}
return Singleton.instance
}
init(
keyService: KeyClient = .live
) {
let storedNetworkString = try! keyService.getNetwork() ?? Network.testnet.description
let storedEsploraURL =
try! keyService.getEsploraURL()
?? Constants.Config.EsploraServerURLNetwork.Testnet.mempoolspace

self.network = Network(stringValue: storedNetworkString) ?? .testnet
self.keyService = keyService

init(keyService: KeyClient = .live) {
let esploraConfig = EsploraConfig(
baseUrl: Constants.Config.EsploraServerURLNetwork.Signet.mutiny,
baseUrl: storedEsploraURL,
proxy: nil,
concurrency: nil,
stopGap: UInt64(20),
timeout: nil
)
let blockchainConfig = BlockchainConfig.esplora(config: esploraConfig)
self.blockchainConfig = blockchainConfig
self.keyService = keyService
}

func getAddress() throws -> String {
Expand All @@ -56,6 +59,20 @@ private class BDKService {
}

func createWallet(words: String?) throws {

let baseUrl =
try! keyService.getEsploraURL()
?? Constants.Config.EsploraServerURLNetwork.Testnet.mempoolspace
let esploraConfig = EsploraConfig(
baseUrl: baseUrl,
proxy: nil,
concurrency: nil,
stopGap: UInt64(20),
timeout: nil
)
let blockchainConfig = BlockchainConfig.esplora(config: esploraConfig)
self.blockchainConfig = blockchainConfig

var words12: String
if let words = words, !words.isEmpty {
words12 = words
Expand Down Expand Up @@ -85,6 +102,8 @@ private class BDKService {
changeDescriptor: changeDescriptor.asStringPrivate()
)
try keyService.saveBackupInfo(backupInfo)
try keyService.saveNetwork(self.network.description)
try keyService.saveEsploraURL(baseUrl)
let wallet = try Wallet(
descriptor: descriptor,
changeDescriptor: changeDescriptor,
Expand Down Expand Up @@ -119,6 +138,8 @@ private class BDKService {
UserDefaults.standard.removePersistentDomain(forName: bundleID)
}
try self.keyService.deleteBackupInfo()
try self.keyService.deleteEsplora()
try self.keyService.deleteNetwork()
}

func send(address: String, amount: UInt64, feeRate: Float?) throws {
Expand Down
63 changes: 60 additions & 3 deletions BDKSwiftExampleWallet/Service/Key Service/KeyService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,78 @@ private struct KeyService {
}
}

extension KeyService {
func saveNetwork(network: String) throws {
keychain[string: "SelectedNetwork"] = network
}

func getNetwork() throws -> String? {
return keychain[string: "SelectedNetwork"]
}

func deleteNetwork() throws {
try keychain.remove("SelectedNetwork")
}

func saveEsploraURL(url: String) throws {
keychain[string: "SelectedEsploraURL"] = url
}

func getEsploraURL() throws -> String? {
return keychain[string: "SelectedEsploraURL"]
}

func deleteEsploraURL() throws {
try keychain.remove("SelectedEsploraURL")
}
}

struct KeyClient {
let saveBackupInfo: (BackupInfo) throws -> Void
let getBackupInfo: () throws -> BackupInfo
let deleteBackupInfo: () throws -> Void

let saveNetwork: (String) throws -> Void
let getNetwork: () throws -> String?
let saveEsploraURL: (String) throws -> Void
let getEsploraURL: () throws -> String?
let deleteNetwork: () throws -> Void
let deleteEsplora: () throws -> Void

private init(
saveBackupInfo: @escaping (BackupInfo) throws -> Void,
getBackupInfo: @escaping () throws -> BackupInfo,
deleteBackupInfo: @escaping () throws -> Void
deleteBackupInfo: @escaping () throws -> Void,
saveNetwork: @escaping (String) throws -> Void,
getNetwork: @escaping () throws -> String?,
saveEsploraURL: @escaping (String) throws -> Void,
getEsploraURL: @escaping () throws -> String?,
deleteNetwork: @escaping () throws -> Void,
deleteEsplora: @escaping () throws -> Void
) {
self.saveBackupInfo = saveBackupInfo
self.getBackupInfo = getBackupInfo
self.deleteBackupInfo = deleteBackupInfo
self.saveNetwork = saveNetwork
self.getNetwork = getNetwork
self.saveEsploraURL = saveEsploraURL
self.getEsploraURL = getEsploraURL
self.deleteNetwork = deleteNetwork
self.deleteEsplora = deleteEsplora
}
}

extension KeyClient {
static let live = Self(
saveBackupInfo: { backupInfo in try KeyService().saveBackupInfo(backupInfo: backupInfo) },
getBackupInfo: { try KeyService().getBackupInfo() },
deleteBackupInfo: { try KeyService().deleteBackupInfo() }
deleteBackupInfo: { try KeyService().deleteBackupInfo() },
saveNetwork: { network in try KeyService().saveNetwork(network: network) },
getNetwork: { try KeyService().getNetwork() },
saveEsploraURL: { url in try KeyService().saveEsploraURL(url: url) },
getEsploraURL: { try KeyService().getEsploraURL() },
deleteNetwork: { try KeyService().deleteNetwork() },
deleteEsplora: { try KeyService().deleteEsploraURL() }
)
}

Expand Down Expand Up @@ -94,7 +145,13 @@ extension KeyClient {
)
return backupInfo
},
deleteBackupInfo: { try KeyService().deleteBackupInfo() }
deleteBackupInfo: { try KeyService().deleteBackupInfo() },
saveNetwork: { _ in },
getNetwork: { nil },
saveEsploraURL: { _ in },
getEsploraURL: { nil },
deleteNetwork: {},
deleteEsplora: {}
)
}
#endif
52 changes: 51 additions & 1 deletion BDKSwiftExampleWallet/Utilities/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,67 @@
//

import Foundation
import SwiftUI

struct Constants {
struct Config {
struct EsploraServerURLNetwork {
struct Bitcoin {
private static let blockstream = "https://blockstream.info/api"
private static let kuutamo = "https://esplora.kuutamo.cloud"
private static let mempoolspace = "https://mempool.space/api"
static let allValues = [
blockstream,
kuutamo,
mempoolspace,
]
}
struct Regtest {
private static let local = "http://127.0.0.1:3002"
static let allValues = [
local
]
}
struct Signet {
static let bdk = "http://signet.bitcoindevkit.net:3003/"
static let mutiny = "https://mutinynet.com/api"
static let allValues = [
bdk,
mutiny,
]
}
struct Testnet {
static let blockstream = "http://blockstream.info/testnet/api/"
static let mempool = "https://mempool.space/testnet/api/"
static let kuutamo = "https://esplora.testnet.kuutamo.cloud"
static let mempoolspace = "https://mempool.space/testnet/api/"
static let allValues = [
blockstream,
kuutamo,
mempoolspace,
]
}
}
}
enum BitcoinNetworkColor {
case bitcoin
case regtest
case signet
case testnet

var color: Color {
switch self {
case .regtest:
return Color.green
case .signet:
return Color.yellow
case .bitcoin:
// Supposed to be `Color.black`
// ... but I'm just going to make it `Color.orange`
// ... since `Color.black` might not work well for both light+dark mode
// ... and `Color.orange` just makes more sense to me
return Color.orange
case .testnet:
return Color.red
}
}
}
Expand Down
Loading

0 comments on commit 2e3aaae

Please sign in to comment.