Skip to content

Commit 54266d4

Browse files
committed
refactor walletclient
1 parent c255bcb commit 54266d4

7 files changed

Lines changed: 110 additions & 110 deletions

File tree

LDKNodeMonday/App/LDKNodeMondayApp.swift

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,43 +12,61 @@ struct LDKNodeMondayApp: App {
1212

1313
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
1414

15-
@State private var walletClient = WalletClient(appMode: .live)
15+
@State private var walletClient: WalletClient? = nil
1616
@State private var navigationPath = NavigationPath()
1717

18-
init() {
19-
AppDelegate.shared.walletClient = walletClient
20-
}
18+
init() {}
2119

2220
var body: some Scene {
2321
WindowGroup {
24-
NavigationStack(path: $navigationPath) {
25-
switch walletClient.appState {
26-
case .onboarding:
27-
OnboardingView(
28-
viewModel: .init(
29-
walletClient: $walletClient
30-
)
31-
)
32-
case .wallet:
33-
BitcoinView(
34-
viewModel: .init(
35-
walletClient: $walletClient,
36-
priceClient: .live,
37-
lightningClient: walletClient.lightningClient
38-
),
39-
sendNavigationPath: $navigationPath
40-
)
41-
case .error:
42-
ErrorView(error: walletClient.appError)
43-
default:
22+
Group {
23+
if let walletClient = walletClient {
24+
NavigationStack(path: $navigationPath) {
25+
switch walletClient.appState {
26+
case .onboarding:
27+
OnboardingView(
28+
viewModel: .init(
29+
walletClient: .constant(walletClient)
30+
)
31+
)
32+
case .wallet:
33+
BitcoinView(
34+
viewModel: .init(
35+
walletClient: .constant(walletClient),
36+
priceClient: .live,
37+
lightningClient: walletClient.lightningClient
38+
),
39+
sendNavigationPath: $navigationPath
40+
)
41+
case .error:
42+
ErrorView(error: walletClient.appError)
43+
default:
44+
LoadingView()
45+
}
46+
}
47+
.onChange(of: walletClient.appState) { oldValue, newValue in
48+
navigationPath = NavigationPath()
49+
}
50+
.task {
51+
await walletClient.start()
52+
}
53+
} else {
4454
LoadingView()
4555
}
4656
}
47-
.onChange(of: walletClient.appState) { oldValue, newValue in
48-
navigationPath = NavigationPath()
49-
}
5057
.task {
51-
await walletClient.start()
58+
if walletClient == nil {
59+
do {
60+
let client = try await WalletClient.create(appMode: .live)
61+
walletClient = client
62+
AppDelegate.shared.walletClient = client
63+
} catch {
64+
let errorClient = WalletClient.mock
65+
errorClient.appState = .error
66+
errorClient.appError = error
67+
walletClient = errorClient
68+
}
69+
}
5270
}
5371
}
5472
}

LDKNodeMonday/App/WalletClient.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,24 @@ public class WalletClient {
2020
public var appState = AppState.loading
2121
public var appError: Error?
2222

23-
public init(appMode: AppMode) {
23+
private init(appMode: AppMode, keyClient: KeyClient, lightningClient: LightningNodeClient) {
2424
self.appMode = appMode
25+
self.keyClient = keyClient
26+
self.lightningClient = lightningClient
27+
}
28+
29+
public static func create(appMode: AppMode) async throws -> WalletClient {
2530
switch appMode {
2631
case .live:
27-
self.keyClient = .live
28-
self.lightningClient = .live
32+
try await LightningNodeService.initializeShared()
33+
return WalletClient(appMode: .live, keyClient: .live, lightningClient: .live)
2934
case .mock:
30-
self.keyClient = .mock
31-
self.lightningClient = .mock
35+
return WalletClient(appMode: .mock, keyClient: .mock, lightningClient: .mock)
3236
}
3337
}
3438

39+
public static let mock = WalletClient(appMode: .mock, keyClient: .mock, lightningClient: .mock)
40+
3541
func createWallet(seedPhrase: String, network: Network, server: EsploraServer) async {
3642
do {
3743
let backupInfo = BackupInfo(

LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift

Lines changed: 48 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class LightningNodeService {
1818
lock.lock()
1919
defer { lock.unlock() }
2020
if _shared == nil {
21-
_shared = LightningNodeService()
21+
fatalError("LightningNodeService.shared must be set using createAndSetShared() before use.")
2222
}
2323
return _shared!
2424
}
@@ -34,100 +34,69 @@ class LightningNodeService {
3434
var network: Network
3535
var server: EsploraServer
3636

37-
init(
38-
keyService: KeyClient = .live
39-
) {
37+
private init(ldkNode: Node, keyService: KeyClient, network: Network, server: EsploraServer) {
38+
self.ldkNode = ldkNode
39+
self.keyService = keyService
40+
self.network = network
41+
self.server = server
42+
}
43+
4044

41-
if let backupInfo = try? KeyClient.live.getBackupInfo() {
42-
guard let network = Network(stringValue: backupInfo.networkString) else {
43-
// This should never happen, but if it does:
44-
fatalError("Configuration error: No Network found in BackupInfo")
45+
static func create(keyService: KeyClient = .live) async throws -> LightningNodeService {
46+
let backupInfo = try? KeyClient.live.getBackupInfo()
47+
let network: Network
48+
let server: EsploraServer
49+
if let backupInfo {
50+
guard let n = Network(stringValue: backupInfo.networkString) else {
51+
throw NSError(domain: "LightningNodeService", code: 1, userInfo: [NSLocalizedDescriptionKey: "No Network found in BackupInfo"])
4552
}
46-
self.network = network
47-
48-
guard
49-
let server =
50-
EsploraServer(URLString: backupInfo.serverURL)
51-
?? availableServers(network: network).first
52-
else {
53-
// This should never happen, but if it does:
54-
fatalError("Configuration error: No Esplora servers available for \(network)")
53+
network = n
54+
guard let s = EsploraServer(URLString: backupInfo.serverURL) ?? availableServers(network: n).first else {
55+
throw NSError(domain: "LightningNodeService", code: 2, userInfo: [NSLocalizedDescriptionKey: "No Esplora servers available for \(network)"])
5556
}
56-
self.server = server
57+
server = s
5758
} else {
58-
self.network = .signet
59-
self.server = .mutiny_signet
59+
network = .signet
60+
server = .mutiny_signet
6061
}
6162

62-
self.keyService = keyService
63-
6463
let documentsPath = FileManager.default.getDocumentsDirectoryPath()
6564
let networkPath = URL(fileURLWithPath: documentsPath)
6665
.appendingPathComponent(network.description)
6766
.path
6867
let logPath = networkPath + "/logs"
69-
70-
try? FileManager.default.createDirectory(
71-
atPath: logPath,
72-
withIntermediateDirectories: true
73-
)
74-
75-
// This is what `Config` looks like now, need to find out where `logDirPath` and `logLevel` are now
76-
77-
// public struct Config {
78-
// public var storageDirPath: String
79-
// public var network: Network
80-
// public var listeningAddresses: [SocketAddress]?
81-
// public var nodeAlias: NodeAlias?
82-
// public var trustedPeers0conf: [PublicKey]
83-
// public var probingLiquidityLimitMultiplier: UInt64
84-
// public var anchorChannelsConfig: AnchorChannelsConfig?
85-
// public var sendingParameters: SendingParameters?
68+
try? FileManager.default.createDirectory(atPath: logPath, withIntermediateDirectories: true)
8669

8770
var config = defaultConfig()
8871
config.storageDirPath = networkPath
89-
// config.logDirPath = logPath
90-
config.network = self.network
91-
config.trustedPeers0conf = [
92-
Constants.Config.LiquiditySourceLsps2.Signet.megalith.nodeId
93-
]
94-
// config.logLevel = .trace
95-
72+
config.network = network
73+
config.trustedPeers0conf = [Constants.Config.LiquiditySourceLsps2.Signet.megalith.nodeId]
9674
let anchor_cfg = AnchorChannelsConfig(
97-
trustedPeersNoReserve: [
98-
Constants.Config.LiquiditySourceLsps2.Signet.megalith.nodeId
99-
],
75+
trustedPeersNoReserve: [Constants.Config.LiquiditySourceLsps2.Signet.megalith.nodeId],
10076
perChannelReserveSats: UInt64(0)
10177
)
10278
config.anchorChannelsConfig = .some(anchor_cfg)
103-
10479

10580
let nodeBuilder = Builder.fromConfig(config: config)
106-
nodeBuilder.setChainSourceEsplora(serverUrl: self.server.url, config: nil)
107-
108-
switch self.network {
81+
nodeBuilder.setChainSourceEsplora(serverUrl: server.url, config: nil)
82+
var networkColor = Color.black
83+
switch network {
10984
case .bitcoin:
110-
nodeBuilder.setGossipSourceRgs(
111-
rgsServerUrl: Constants.Config.RGSServerURLNetwork.bitcoin
112-
)
113-
self.networkColor = Constants.BitcoinNetworkColor.bitcoin.color
85+
nodeBuilder.setGossipSourceRgs(rgsServerUrl: Constants.Config.RGSServerURLNetwork.bitcoin)
86+
networkColor = Constants.BitcoinNetworkColor.bitcoin.color
11487
case .testnet:
115-
nodeBuilder.setGossipSourceRgs(
116-
rgsServerUrl: Constants.Config.RGSServerURLNetwork.testnet
117-
)
118-
self.networkColor = Constants.BitcoinNetworkColor.testnet.color
88+
nodeBuilder.setGossipSourceRgs(rgsServerUrl: Constants.Config.RGSServerURLNetwork.testnet)
89+
networkColor = Constants.BitcoinNetworkColor.testnet.color
11990
case .signet:
120-
nodeBuilder.setGossipSourceRgs(
121-
rgsServerUrl: Constants.Config.RGSServerURLNetwork.signet
122-
)
91+
nodeBuilder.setGossipSourceRgs(rgsServerUrl: Constants.Config.RGSServerURLNetwork.signet)
12392
nodeBuilder.setLiquiditySourceLsps2(
12493
nodeId: Constants.Config.LiquiditySourceLsps2.Signet.megalith.nodeId,
12594
address: Constants.Config.LiquiditySourceLsps2.Signet.megalith.address,
12695
token: Constants.Config.LiquiditySourceLsps2.Signet.megalith.token
12796
)
128-
self.networkColor = Constants.BitcoinNetworkColor.signet.color
97+
networkColor = Constants.BitcoinNetworkColor.signet.color
12998
case .regtest:
130-
self.networkColor = Constants.BitcoinNetworkColor.regtest.color
99+
networkColor = Constants.BitcoinNetworkColor.regtest.color
131100
}
132101

133102
let mnemonic: String
@@ -137,8 +106,8 @@ class LightningNodeService {
137106
let newMnemonic = generateEntropyMnemonic()
138107
let backupInfo = BackupInfo(
139108
mnemonic: newMnemonic,
140-
networkString: self.network.description,
141-
serverURL: self.server.url
109+
networkString: network.description,
110+
serverURL: server.url
142111
)
143112
try? keyService.saveBackupInfo(backupInfo)
144113
mnemonic = newMnemonic
@@ -149,16 +118,22 @@ class LightningNodeService {
149118
let newMnemonic = generateEntropyMnemonic()
150119
let backupInfo = BackupInfo(
151120
mnemonic: newMnemonic,
152-
networkString: self.network.description,
153-
serverURL: self.server.url
121+
networkString: network.description,
122+
serverURL: server.url
154123
)
155124
try? keyService.saveBackupInfo(backupInfo)
156125
mnemonic = newMnemonic
157126
}
158127
nodeBuilder.setEntropyBip39Mnemonic(mnemonic: mnemonic, passphrase: nil)
128+
let ldkNode = try await nodeBuilder.build()
129+
let service = LightningNodeService(ldkNode: ldkNode, keyService: keyService, network: network, server: server)
130+
service.networkColor = networkColor
131+
return service
132+
}
159133

160-
let ldkNode = try! nodeBuilder.build() // Handle error instead of "!"
161-
self.ldkNode = ldkNode
134+
static func initializeShared(keyService: KeyClient = .live) async throws {
135+
let service = try await create(keyService: keyService)
136+
LightningNodeService.shared = service
162137
}
163138

164139
func start() async throws {
@@ -415,6 +390,7 @@ public struct LightningNodeClient {
415390
}
416391

417392
extension LightningNodeClient {
393+
/// NOTE: LightningNodeService.shared must be set via createAndSetShared() before using .live
418394
static let live = Self(
419395
start: { try await LightningNodeService.shared.start() },
420396
stop: { try LightningNodeService.shared.stop() },

LDKNodeMonday/View/Home/BitcoinView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,11 +340,11 @@ extension DisplayBalanceType {
340340
#Preview {
341341
BitcoinView(
342342
viewModel: .init(
343-
walletClient: .constant(WalletClient(appMode: AppMode.mock)),
343+
walletClient: .constant(WalletClient.mock),
344344
priceClient: .mock,
345345
lightningClient: .mock
346346
),
347-
sendNavigationPath: .constant(.init())
347+
sendNavigationPath: .constant(NavigationPath())
348348
)
349349
}
350350
#endif

LDKNodeMonday/View/Home/NetworkSettingsView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,6 @@ struct NetworkSettingsView: View {
169169

170170
#if DEBUG
171171
#Preview {
172-
NetworkSettingsView(walletClient: .constant(WalletClient(appMode: AppMode.mock)))
172+
NetworkSettingsView(walletClient: .constant(WalletClient.mock))
173173
}
174174
#endif

LDKNodeMonday/View/Home/OnboardingView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ struct OnboardingView: View {
138138
#Preview {
139139
OnboardingView(
140140
viewModel: .init(
141-
walletClient: .constant(WalletClient(appMode: AppMode.mock))
141+
walletClient: .constant(WalletClient.mock)
142142
)
143143
)
144144
}

LDKNodeMonday/View/Settings/SettingsView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ struct SettingsView: View {
203203
#Preview {
204204
SettingsView(
205205
viewModel: .init(
206-
walletClient: .constant(WalletClient(appMode: AppMode.mock)),
206+
walletClient: .constant(WalletClient.mock),
207207
lightningClient: .mock
208208
)
209209

0 commit comments

Comments
 (0)