From 16404d41898764611c0715bcfe567ebdb7a54b29 Mon Sep 17 00:00:00 2001 From: Fontaine Date: Tue, 5 Nov 2024 12:43:08 -0500 Subject: [PATCH 01/22] fix: Join Market was broken. Added a "configure JM" button. --- .../Helpers/InstallBtcCore.swift | 9 +++ FullyNoded-Server/Views/JoinMarket.swift | 74 +++++++++++++++++++ .../Views/JoinMarketTaggedReleases.swift | 8 +- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/FullyNoded-Server/Helpers/InstallBtcCore.swift b/FullyNoded-Server/Helpers/InstallBtcCore.swift index 30292e5b..eddbd976 100644 --- a/FullyNoded-Server/Helpers/InstallBtcCore.swift +++ b/FullyNoded-Server/Helpers/InstallBtcCore.swift @@ -12,6 +12,8 @@ class CreateFNDirConfigureCore { class func checkForExistingConf(completion: @escaping (Bool) -> Void) { BitcoinConf.getBitcoinConf { (conf, error) in if let existingBitcoinConf = conf { + var createBdbExists = false + // check if deprecatedrpc=create_bdb exists, if not add it. for item in existingBitcoinConf { let arr = item.split(separator: "=") if arr.count > 1 { @@ -22,6 +24,9 @@ class CreateFNDirConfigureCore { if item.hasPrefix("txindex=") { UserDefaults.standard.setValue(value, forKey: "txindex") } + if item.contains("deprecatedrpc=create_bdb") { + createBdbExists = true + } } } } @@ -51,6 +56,10 @@ class CreateFNDirConfigureCore { } var updatedBitcoinConf = existingBitcoinConf.joined(separator: "\n") + if !createBdbExists { + // For Join Market to work... + updatedBitcoinConf = "deprecatedrpc=create_bdb" + "\n" + updatedBitcoinConf + } updatedBitcoinConf = rpcauth + "\n" + updatedBitcoinConf setBitcoinConf(updatedBitcoinConf, completion: completion) } diff --git a/FullyNoded-Server/Views/JoinMarket.swift b/FullyNoded-Server/Views/JoinMarket.swift index 54239ee1..5332acd2 100644 --- a/FullyNoded-Server/Views/JoinMarket.swift +++ b/FullyNoded-Server/Views/JoinMarket.swift @@ -111,6 +111,11 @@ struct JoinMarket: View { } label: { Text("joinmarket.cfg") } + Button { + configureJm() + } label: { + Text("Configure JM") + } } .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) @@ -160,6 +165,75 @@ struct JoinMarket: View { } } + private func configureJm() { + var chain = UserDefaults.standard.object(forKey: "chain") as? String ?? "signet" + let port = UserDefaults.standard.object(forKey: "port") as? String ?? "38332" + switch chain { + case "main": chain = "mainnet" + case "regtest": chain = "testnet" + case "test": chain = "testnet" + default: + break + } + updateConf(key: "network", value: chain) + updateConf(key: "rpc_port", value: port) + updateConf(key: "rpc_wallet_file", value: "jm_wallet") + + DataManager.retrieve(entityName: "BitcoinRPCCreds") { rpcCreds in + guard let rpcCreds = rpcCreds, + let encryptedPassword = rpcCreds["password"] as? Data, + let decryptedPass = Crypto.decrypt(encryptedPassword), + let stringPass = String(data: decryptedPass, encoding: .utf8) else { + showMessage(message: "Unable to get rpc creds to congifure JM.") + return + } + + updateConf(key: "rpc_password", value: stringPass) + updateConf(key: "rpc_user", value: "FullyNoded-Server") + + BitcoinRPC.shared.command(method: "createwallet", params: ["wallet_name": "jm_wallet", "descriptors": false]) { (result, error) in + guard error == nil else { + if !error!.contains("Database already exists.") { + showMessage(message: error!) + } + isAnimating = false + return + } + + showMessage(message: "Join Market configured ✓") + isAnimating = false + } + } + } + + private func fileExists(path: String) -> Bool { + return FileManager.default.fileExists(atPath: path) + } + + private func updateConf(key: String, value: String) { + let jmConfPath = "/Users/\(NSUserName())/Library/Application Support/joinmarket/joinmarket.cfg" + guard fileExists(path: jmConfPath) else { return } + guard let conf = try? Data(contentsOf: URL(fileURLWithPath: jmConfPath)) else { + print("no jm conf") + return + } + guard let string = String(data: conf, encoding: .utf8) else { + print("cant get string") + return + } + let arr = string.split(separator: "\n") + for item in arr { + if item.hasPrefix("\(key) =") { + let newConf = string.replacingOccurrences(of: item, with: key + " = " + value) + if (try? newConf.write(to: URL(fileURLWithPath: jmConfPath), atomically: false, encoding: .utf8)) == nil { + print("failed writing to jm config") + } else { + print("wrote to joinmarket.cfg") + } + } + } + } + private func showConnectUrls() { guard let hiddenServices = TorClient.sharedInstance.hostnames() else { showMessage(message: "No hostnames.") diff --git a/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift b/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift index f6b601ad..b0b7432a 100644 --- a/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift +++ b/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift @@ -129,7 +129,13 @@ struct JoinMarketTaggedReleasesView: View { updateConf(key: "rpc_wallet_file", value: "jm_wallet") DataManager.retrieve(entityName: "BitcoinRPCCreds") { rpcCreds in - guard let rpcCreds = rpcCreds, let encryptedPassword = rpcCreds["password"] as? Data, let decryptedPass = Crypto.decrypt(encryptedPassword), let stringPass = String(data: decryptedPass, encoding: .utf8) else { return } + guard let rpcCreds = rpcCreds, + let encryptedPassword = rpcCreds["password"] as? Data, + let decryptedPass = Crypto.decrypt(encryptedPassword), + let stringPass = String(data: decryptedPass, encoding: .utf8) else { + showMessage(message: "Unable to get rpc creds to congifure JM.") + return + } updateConf(key: "rpc_password", value: stringPass) updateConf(key: "rpc_user", value: "FullyNoded-Server") From 356bc1f5e040150db8a5c8cf4e6a7163d2dfbdaf Mon Sep 17 00:00:00 2001 From: Fontaine Date: Thu, 7 Nov 2024 12:48:56 -0500 Subject: [PATCH 02/22] bitcoin: ability to update prune amount, add IBD status to UI, check for xcode and brew and prompt to install, --- .../Helpers/InstallBtcCore.swift | 87 +++++++++------- FullyNoded-Server/Views/BitcoinCore.swift | 69 +++++++------ FullyNoded-Server/Views/ContentView.swift | 98 +++++++++++-------- .../Views/TaggedReleasesView.swift | 26 +++-- 4 files changed, 170 insertions(+), 110 deletions(-) diff --git a/FullyNoded-Server/Helpers/InstallBtcCore.swift b/FullyNoded-Server/Helpers/InstallBtcCore.swift index eddbd976..b6b5fdda 100644 --- a/FullyNoded-Server/Helpers/InstallBtcCore.swift +++ b/FullyNoded-Server/Helpers/InstallBtcCore.swift @@ -9,61 +9,78 @@ import Foundation class CreateFNDirConfigureCore { - class func checkForExistingConf(completion: @escaping (Bool) -> Void) { + class func checkForExistingConf(updatedPruneValue: Int?, completion: @escaping (Bool) -> Void) { + var existingPruneValue: Int? BitcoinConf.getBitcoinConf { (conf, error) in if let existingBitcoinConf = conf { var createBdbExists = false + + func setNow() { + let rpcuser = "FullyNoded-Server" + guard let rpcAuthCreds = RPCAuth().generateCreds(username: rpcuser, password: nil) else { + completion(false) + print("unable to generate rpc auth creds.") + return + } + let rpcauth = rpcAuthCreds.rpcAuth + let data = Data(rpcAuthCreds.rpcPassword.utf8) + + guard let encryptedPass = Crypto.encrypt(data) else { + #if DEBUG + print("Unable to encrypt rpc pass.") + #endif + completion(false) + return + } + updateRpcCreds(encryptedPass: encryptedPass, rpcUser: rpcuser) { updated in + guard updated else { + #if DEBUG + print("Unable to save new password.") + #endif + completion(false) + return + } + + var updatedBitcoinConf = existingBitcoinConf.joined(separator: "\n") + if !createBdbExists { + // For Join Market to work... + updatedBitcoinConf = "deprecatedrpc=create_bdb" + "\n" + updatedBitcoinConf + if let updatedPruneValue = updatedPruneValue, let existingPruneValue = existingPruneValue { + updatedBitcoinConf = updatedBitcoinConf.replacingOccurrences(of: "prune=\(existingPruneValue)", with: "prune=\(updatedPruneValue)") + } + } + updatedBitcoinConf = rpcauth + "\n" + updatedBitcoinConf + setBitcoinConf(updatedBitcoinConf, completion: completion) + } + } // check if deprecatedrpc=create_bdb exists, if not add it. - for item in existingBitcoinConf { + for (i, item) in existingBitcoinConf.enumerated() { let arr = item.split(separator: "=") if arr.count > 1 { if let value = Int(arr[1]) { if item.hasPrefix("prune=") { - UserDefaults.standard.setValue(value, forKey: "prune") + if let updatedPruneValue = updatedPruneValue { + UserDefaults.standard.setValue(updatedPruneValue, forKey: "prune") + existingPruneValue = value + } } if item.hasPrefix("txindex=") { UserDefaults.standard.setValue(value, forKey: "txindex") } + + } else { + // deprecatedrpc=create_bdb if item.contains("deprecatedrpc=create_bdb") { createBdbExists = true } } } - } - let rpcuser = "FullyNoded-Server" - guard let rpcAuthCreds = RPCAuth().generateCreds(username: rpcuser, password: nil) else { - completion(false) - print("unable to generate rpc auth creds.") - return - } - let rpcauth = rpcAuthCreds.rpcAuth - let data = Data(rpcAuthCreds.rpcPassword.utf8) - - guard let encryptedPass = Crypto.encrypt(data) else { - #if DEBUG - print("Unable to encrypt rpc pass.") - #endif - completion(false) - return - } - updateRpcCreds(encryptedPass: encryptedPass, rpcUser: rpcuser) { updated in - guard updated else { - #if DEBUG - print("Unable to save new password.") - #endif - completion(false) - return + if i + 1 == existingBitcoinConf.count { + setNow() } - - var updatedBitcoinConf = existingBitcoinConf.joined(separator: "\n") - if !createBdbExists { - // For Join Market to work... - updatedBitcoinConf = "deprecatedrpc=create_bdb" + "\n" + updatedBitcoinConf - } - updatedBitcoinConf = rpcauth + "\n" + updatedBitcoinConf - setBitcoinConf(updatedBitcoinConf, completion: completion) } + } else { if let defaultConf = BitcoinConf.newBitcoinConf() { self.setBitcoinConf(defaultConf, completion: completion) diff --git a/FullyNoded-Server/Views/BitcoinCore.swift b/FullyNoded-Server/Views/BitcoinCore.swift index dc124ef1..d999cf85 100644 --- a/FullyNoded-Server/Views/BitcoinCore.swift +++ b/FullyNoded-Server/Views/BitcoinCore.swift @@ -36,7 +36,15 @@ struct BitcoinCore: View { } else { Text("Bitcoin Core Server") } - + if let blockchainInfo = blockchainInfo, blockchainInfo.initialblockdownload { + Label { + Text("Downloading the blockchain...") + .foregroundStyle(.secondary) + } icon: { + ProgressView() + .scaleEffect(0.5) + } + } Spacer() Button { isBitcoinCoreRunning() @@ -91,6 +99,36 @@ struct BitcoinCore: View { } } + if let blockchainInfo = blockchainInfo { + if blockchainInfo.progressString == "Fully verified" { + Label { + Text(blockchainInfo.progressString) + } icon: { + Image(systemName: "checkmark.seal.fill") + .foregroundStyle(.green) + } + //.padding([.leading]) + //.frame(maxWidth: .infinity, alignment: .leading) + } else { + Label { + Text(blockchainInfo.progressString) + } icon: { + Image(systemName: "xmark.seal") + .foregroundStyle(.orange) + } + //.padding([.leading]) + //.frame(maxWidth: .infinity, alignment: .leading) + } + Label { + Text("Blockheight: " + "\(blockchainInfo.blockheight)") + } icon: { + Image(systemName: "square.stack.3d.up") + } + //.padding([.leading]) + // .frame(maxWidth: .infinity, alignment: .leading) + + } + EmptyView() .onReceive(timerForBitcoinStatus) { _ in isBitcoinCoreRunning() @@ -99,34 +137,7 @@ struct BitcoinCore: View { .padding([.leading, .bottom]) .frame(maxWidth: .infinity, alignment: .leading) - if let blockchainInfo = blockchainInfo { - if blockchainInfo.progressString == "Fully verified" { - Label { - Text(blockchainInfo.progressString) - } icon: { - Image(systemName: "checkmark.seal.fill") - .foregroundStyle(.green) - } - .padding([.leading, .bottom]) - .frame(maxWidth: .infinity, alignment: .leading) - } else { - Label { - Text(blockchainInfo.progressString) - } icon: { - Image(systemName: "xmark.seal") - .foregroundStyle(.orange) - } - .padding([.leading, .bottom]) - .frame(maxWidth: .infinity, alignment: .leading) - } - Label { - Text("Blockheight: " + "\(blockchainInfo.blockheight)") - } icon: { - Image(systemName: "square.stack.3d.up") - } - .padding([.leading, .bottom]) - .frame(maxWidth: .infinity, alignment: .leading) - } + Label("Network", systemImage: "network") diff --git a/FullyNoded-Server/Views/ContentView.swift b/FullyNoded-Server/Views/ContentView.swift index a34ac927..3906ad85 100644 --- a/FullyNoded-Server/Views/ContentView.swift +++ b/FullyNoded-Server/Views/ContentView.swift @@ -27,7 +27,6 @@ struct ContentView: View { @State private var bitcoinCoreInstalled = false @State private var lightningInstalled = false @State private var joinMarketInstalled = false - @State private var xcodeSelectInstalled = false @State private var promptToInstallXcode = false @State private var promptToInstallBitcoin = false @State private var startCheckingForBitcoinInstall = false @@ -75,8 +74,7 @@ struct ContentView: View { jmTaggedReleases: [] ) } - } - if service.name == "Core Lightning" { + } else if service.name == "Core Lightning" { if lightningInstalled { CoreLightning() } else { @@ -95,8 +93,7 @@ struct ContentView: View { ) } - } - if service.name == "Join Market" { + } else if service.name == "Join Market" { if joinMarketInstalled { JoinMarket() } else { @@ -110,8 +107,7 @@ struct ContentView: View { jmTaggedReleases: jmTaggedReleases ) } - } - if service.name == "Tor" { + } else if service.name == "Tor" { HStack() { if torProgress < 100.0 { ProgressView("Tor bootstrapping \(Int(torProgress))% complete…", value: torProgress, total: 100) @@ -131,8 +127,6 @@ struct ContentView: View { } } } - - Home( showBitcoinCoreInstallButton: false, env: [:], @@ -220,8 +214,6 @@ struct ContentView: View { } } - - EmptyView() .onReceive(timerForTor) { _ in self.torRunning = TorClient.sharedInstance.state == .connected @@ -229,27 +221,20 @@ struct ContentView: View { } Text(service.name) } + } } } -// Home( -// showBitcoinCoreInstallButton: promptToInstallBitcoin, -// env: env, -// showJoinMarketInstallButton: !joinMarketInstalled, -// jmTaggedReleases: jmTaggedReleases -// ) } .onAppear(perform: { - if TorClient.sharedInstance.state == .connected { - torProgress = 100.0 - } else { - TorClient.sharedInstance.start(delegate: nil) - } - TorClient.sharedInstance.showProgress = { progress in - torProgress = Double(progress) - } - getSavedValues() - + /// For testing fresh install. +// DataManager.deleteAllData(entityName: "BitcoinRPCCreds") { deleted in +// print("deleted: \(deleted)") +// let domain = Bundle.main.bundleIdentifier! +// UserDefaults.standard.removePersistentDomain(forName: domain) +// UserDefaults.standard.synchronize() +// } + checkForXcode() }) .alert("Install Core Lightning?", isPresented: $promptToInstallLightning) { Button("OK") { @@ -265,6 +250,11 @@ struct ContentView: View { runScript(script: .installHomebrew, env: [:]) } } + .alert("Install Xcode Command Line Tools? This is required for Fully Noded - Server to function.", isPresented: $promptToInstallXcode, actions: { + Button("OK", role: .cancel) { + runScript(script: .installXcode, env: [:]) + } + }) .alert("Bitcoin Install complete.", isPresented: $bitcoinInstallSuccess) { Button("OK", role: .cancel) { runScript(script: .checkForBitcoin, env: env) @@ -281,6 +271,40 @@ struct ContentView: View { } } + private func checkForXcode() { + ScriptUtil.runScript(script: .checkXcodeSelect, env: nil, args: nil) { (output, data, errorMess) in + guard let output = output else { + showMessage(message: errorMess ?? "Unknown error checking for xcode select.") + return + } + if output.contains("XCode select installed") { + promptToInstallXcode = false + checkForBrew() + } else if output.contains("XCode select not installed") { + promptToInstallXcode = true + } + } + } + + private func checkForBrew() { + ScriptUtil.runScript(script: .checkForBrew, env: nil, args: nil) { (output, data, errorMess) in + guard let output = output, output != "" else { + promptToInstallBrew = true + return + } + + if TorClient.sharedInstance.state == .connected { + torProgress = 100.0 + } else { + TorClient.sharedInstance.start(delegate: nil) + } + TorClient.sharedInstance.showProgress = { progress in + torProgress = Double(progress) + } + getSavedValues() + } + } + private func installLightning() { DataManager.retrieve(entityName: "BitcoinRPCCreds") { bitcoinRPCCreds in guard let bitcoinRPCCreds = bitcoinRPCCreds else { @@ -309,7 +333,6 @@ struct ContentView: View { lightningEnv["DATA_DIR"] = Defaults.shared.dataDir.replacingOccurrences(of: " ", with: "*") lightningEnv["PREFIX"] = bitcoinEnvValues.prefix var network = "bitcoin" - print("Defaults.shared.chain: \(Defaults.shared.chain)") if Defaults.shared.chain != "main" { network = Defaults.shared.chain } @@ -320,9 +343,6 @@ struct ContentView: View { } private func getSavedValues() { - DataManager.retrieve(entityName: "BitcoinRPCCreds") { creds in - print("creds.count: \(creds?.count)") - } DataManager.retrieve(entityName: "BitcoinEnv") { bitcoinEnv in guard let bitcoinEnv = bitcoinEnv else { let dict = [ @@ -465,15 +485,15 @@ struct ContentView: View { case .checkForBitcoin: parseBitcoindVersionResponse(result: result) - case .checkXcodeSelect: - parseXcodeSelectResult(result: result) +// case .checkXcodeSelect: +// parseXcodeSelectResult(result: result) - case .checkForBrew: - if result != "" { - runScript(script: .lightningInstalled, env: env) - } else { - promptToInstallBrew = true - } +// case .checkForBrew: +// if result != "" { +// runScript(script: .lightningInstalled, env: env) +// } else { +// promptToInstallBrew = true +// } case .lightningInstalled: if result.hasPrefix("Installed") { diff --git a/FullyNoded-Server/Views/TaggedReleasesView.swift b/FullyNoded-Server/Views/TaggedReleasesView.swift index ce441656..ccb86bd8 100644 --- a/FullyNoded-Server/Views/TaggedReleasesView.swift +++ b/FullyNoded-Server/Views/TaggedReleasesView.swift @@ -11,6 +11,7 @@ struct TaggedReleasesView: View { let timerForBitcoinInstall = Timer.publish(every: 3, on: .main, in: .common).autoconnect() @State private var prune = false + @State private var prunedAmount = "" @State private var bitcoinCoreInstallComplete = false @State private var startCheckingForBitcoinInstall = false @State private var description = "" @@ -91,20 +92,22 @@ struct TaggedReleasesView: View { UserDefaults.standard.setValue(0, forKey: "txindex") UserDefaults.standard.setValue(1000, forKey: "prune") txIndex = 0 + prunedAmount = "\(Double(Defaults.shared.prune) / 0.00104858)" } else { UserDefaults.standard.setValue(1, forKey: "txindex") UserDefaults.standard.setValue(0, forKey: "prune") } + } + if prune { + TextField("", text: $prunedAmount) + Text("The amount in giga bytes the blockchain will consume.") + .foregroundStyle(.secondary) + } } .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) - Text("Pruning your node reduces the amount of disc space Bitcoin Core will use.") - .padding([.leading]) - .foregroundStyle(.secondary) - .frame(maxWidth: .infinity, alignment: .leading) - HStack() { if isAnimating { ProgressView() @@ -166,6 +169,9 @@ struct TaggedReleasesView: View { Spacer() .onAppear { prune = !((Defaults.shared.prune) == 0) + if prune { + prunedAmount = "\((Double(Defaults.shared.prune) * 0.00104858).rounded(toPlaces: 1))" + } taggedRelease = .init(url: nil, assetsURL: nil, uploadURL: nil, htmlURL: nil, id: nil, author: nil, nodeID: nil, tagName: "", targetCommitish: nil, name: nil, draft: nil, prerelease: nil, createdAt: nil, publishedAt: nil, tarballURL: "", zipballURL: nil, body: nil) } .alert(message, isPresented: $showError) { @@ -251,6 +257,12 @@ struct TaggedReleasesView: View { } private func install(_ taggedRelease: TaggedReleaseElement, useTor: Bool) { + var newPruneAmount: Int? + if prune, let dblAmount = Double(prunedAmount) { + let mebibytes = Int(dblAmount * 953.674) + UserDefaults.standard.setValue("\(mebibytes)", forKey: "prune") + newPruneAmount = mebibytes + } guard let tagName = taggedRelease.tagName else { showMessage(message: "No tagged name.") return @@ -269,7 +281,8 @@ struct TaggedReleasesView: View { macOSUrl = "\(clearnet)/bin/bitcoin-core-\(processedVersion)/bitcoin-\(processedVersion)-\(arch)-apple-darwin.tar.gz" } description = "Downloading Bitcoin Core tarball from \(macOSUrl)" - CreateFNDirConfigureCore.checkForExistingConf { startDownload in + + CreateFNDirConfigureCore.checkForExistingConf(updatedPruneValue: newPruneAmount) { startDownload in print("startDownload") if startDownload { isAnimating = true @@ -331,7 +344,6 @@ struct TaggedReleasesView: View { } private func updateCLNConfig(key: String) { - // key = "bitcoin-datadir=" let lightningConfPath = "/Users/\(NSUserName())/.lightning/config" guard let conf = conf(stringPath: lightningConfPath) else { return } let arr = conf.split(separator: "\n") From 39782f448fba26732dd1b52205b2f5dc589807a1 Mon Sep 17 00:00:00 2001 From: Fontaine Date: Thu, 7 Nov 2024 12:50:44 -0500 Subject: [PATCH 03/22] lightning: dedicated local lnlik button, minor refactor --- FullyNoded-Server/Helpers/Script.swift | 54 ++++++-- .../Scripts/InstallLightning.command | 3 +- FullyNoded-Server/Views/CoreLightning.swift | 117 ++++++++++++------ 3 files changed, 129 insertions(+), 45 deletions(-) diff --git a/FullyNoded-Server/Helpers/Script.swift b/FullyNoded-Server/Helpers/Script.swift index e16f260f..d69bd374 100644 --- a/FullyNoded-Server/Helpers/Script.swift +++ b/FullyNoded-Server/Helpers/Script.swift @@ -110,13 +110,49 @@ public enum SCRIPT: String { } } -public enum BTCCONF: String { - case prune = "prune" - case txindex = "txindex" - case mainnet = "mainnet" - case testnet = "testnet" - case regtest = "regtest" - case disablewallet = "disablewallet" - case datadir = "datadir" - case blocksdir = "blocksdir" +//public enum BTCCONF: String { +// case prune = "prune" +// case txindex = "txindex" +// case mainnet = "mainnet" +// case testnet = "testnet" +// case regtest = "regtest" +// case disablewallet = "disablewallet" +// case datadir = "datadir" +// case blocksdir = "blocksdir" +//} + +public enum ScriptUtil { + static func runScript(script: SCRIPT, env: [String: String]?, args: [String]?, completion: @escaping ((output: String?, rawData: Data?, errorMessage: String?)) -> (Void)) { + #if DEBUG + print("run script: \(script.stringValue)") + #endif + + let taskQueue = DispatchQueue.global(qos: DispatchQoS.QoSClass.background) + taskQueue.async { + let resource = script.stringValue + guard let path = Bundle.main.path(forResource: resource, ofType: "command") else { return } + let stdOut = Pipe() + let stdErr = Pipe() + let task = Process() + task.launchPath = path + if let args = args { + task.arguments = args + } + if let env = env { + task.environment = env + } + + task.standardOutput = stdOut + task.standardError = stdErr + task.launch() + task.waitUntilExit() + let data = stdOut.fileHandleForReading.readDataToEndOfFile() + let errData = stdErr.fileHandleForReading.readDataToEndOfFile() + let output = String(data: data, encoding: .utf8) + let errorOutput = String(data: errData, encoding: .utf8) + completion((output, data, errorOutput)) + } + } } + + diff --git a/FullyNoded-Server/Scripts/InstallLightning.command b/FullyNoded-Server/Scripts/InstallLightning.command index 8bd3fcae..9a683dbf 100755 --- a/FullyNoded-Server/Scripts/InstallLightning.command +++ b/FullyNoded-Server/Scripts/InstallLightning.command @@ -70,7 +70,7 @@ daemon" } function installLightning () { - sudo -u $(whoami) $BREW_PATH reinstall core-lightning + sudo -u $(whoami) $BREW_PATH install core-lightning cd /opt/homebrew/Cellar/core-lightning/24.08.1/libexec/c-lightning/plugins git clone https://github.com/daywalker90/clnrest-rs.git cd clnrest-rs @@ -78,6 +78,7 @@ function installLightning () { cargo build --release mv target/release/clnrest-rs /opt/homebrew/Cellar/core-lightning/24.08.1/libexec/c-lightning/plugins/clnrest-rs chmod +x /opt/homebrew/Cellar/core-lightning/24.08.1/libexec/c-lightning/plugins/clnrest-rs/clnrest-rs + echo "Core Lightning installation complete, you can close this terminal window." exit 1 } diff --git a/FullyNoded-Server/Views/CoreLightning.swift b/FullyNoded-Server/Views/CoreLightning.swift index ed47fbf2..135671fe 100644 --- a/FullyNoded-Server/Views/CoreLightning.swift +++ b/FullyNoded-Server/Views/CoreLightning.swift @@ -17,6 +17,7 @@ struct CoreLightning: View { @State private var nodeId = "" @State private var publicUrl = "" @State private var lnlink: String? + @State private var localLnlink: String? @State private var plasmaExists = false @State private var selectedChain = UserDefaults.standard.string(forKey: "chain") ?? "main" @State private var onionHost: String? = nil @@ -117,12 +118,14 @@ struct CoreLightning: View { .padding([.leading, .top]) .frame(maxWidth: .infinity, alignment: .leading) - Button("Connect Plasma via LNLink", systemImage: "qrcode") { - showQr() + Button("Connect Plasma remotely via LNLink", systemImage: "qrcode") { + getLnLink(isLocal: false) } .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) + + if let qrImage = qrImage { Image(nsImage: qrImage) .resizable() @@ -138,18 +141,6 @@ struct CoreLightning: View { } } - if plasmaExists { - if let lnlink = self.lnlink { - Link("Connect Plasma Locally via LNLink", destination: URL(string: lnlink)!) - .padding([.leading]) - .frame(maxWidth: .infinity, alignment: .leading) - } - } else { - Link("Download Plasma", destination: URL(string: "https://apps.apple.com/us/app/plasma-core-lightning-wallet/id6468914352")!) - .padding([.leading]) - .frame(maxWidth: .infinity, alignment: .leading) - } - Button("Connect via Onion (clnrest-rs)", systemImage: "qrcode") { self.onionHost = TorClient.sharedInstance.hostnames()?[5] runScript(script: .getRune) @@ -176,7 +167,27 @@ struct CoreLightning: View { Text(onionHost) .textSelection(.enabled) } + } + + if plasmaExists { + Button("Connect Plasma Locally") { + getLnLink(isLocal: true) + } + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) + + if let lnlink = self.localLnlink { + Link("Connect Plasma Locally via LNLink", destination: URL(string: lnlink)!) + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) + } + + } else { + Link("Download Plasma", destination: URL(string: "https://apps.apple.com/us/app/plasma-core-lightning-wallet/id6468914352")!) + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) } + Spacer() HStack() { Label(logOutput, systemImage: "info.circle") @@ -201,7 +212,7 @@ struct CoreLightning: View { } private func showQr() { - getPublicUrl() + getPublicUrl(isLocal: false) } private func startLightning() { @@ -310,30 +321,66 @@ struct CoreLightning: View { } } - func getPublicUrl() { - let path = URL(fileURLWithPath: "/Users/\(NSUserName())/.lightning/config") - guard let config = try? Data(contentsOf: path) else { - print("Unable to get ngrok.log.") - return - } - guard let stringValue = String(data: config, encoding: .utf8) else { - print("Unable to convert log data to utf8 string.") - return + func getLnLink(isLocal: Bool) { + ScriptUtil.runScript(script: .lightningNodeId, env: nil, args: nil) { (output, rawData, errorMessage) in + guard let data = rawData else { + return + } + + guard let info = dec(GetInfo.self, data).response as? GetInfo else { return } + self.nodeId = info.id + getRune(isLocal: isLocal) } - let array = stringValue.split(separator: "\n") - var anyAddr = false - for item in array { - if item.hasPrefix("addr=") { - anyAddr = true - let itemArr = item.split(separator: "=") - self.publicUrl = "\(itemArr[1])" - runScript(script: .lightningNodeId) + } + + func getRune(isLocal: Bool) { + ScriptUtil.runScript(script: .getRune, env: nil, args: nil) { (output, rawData, errorMessage) in + guard let data = rawData else { return } + guard let runeResponse = dec(Rune.self, data).response as? Rune, let rune = runeResponse.rune else { return } + if !isLocal { + let publicLnLink = "lnlink:\(self.nodeId)@\(self.publicUrl)?token=\(rune)" + if publicUrl != "" { + self.qrImage = publicLnLink.qrQode + } + } else { + self.localLnlink = "lnlink:\(self.nodeId)@127.0.0.1:9735?token=\(rune)" + } + if let onionHost = self.onionHost { + self.quickConnectClnRest = "clnrest://\(onionHost):18765?token=\(rune)" } } - if !anyAddr { + } + + func getPublicUrl(isLocal: Bool) { + if isLocal { + self.publicUrl = "127.0.0.1:9735" runScript(script: .lightningNodeId) - showMessage(message: "In order to connect via QR code remotely with Plasma you need to open the lightning config and add addr=, example: addr=100.89.65.23:9735. If you do not have a public IP you can use Plasma locally by clicking \"Connect Plasma Locally\".") + } else { + let path = URL(fileURLWithPath: "/Users/\(NSUserName())/.lightning/config") + guard let config = try? Data(contentsOf: path) else { + print("Unable to get ngrok.log.") + return + } + guard let stringValue = String(data: config, encoding: .utf8) else { + print("Unable to convert log data to utf8 string.") + return + } + let array = stringValue.split(separator: "\n") + var anyAddr = false + for item in array { + if item.hasPrefix("addr=") { + anyAddr = true + let itemArr = item.split(separator: "=") + self.publicUrl = "\(itemArr[1])" + runScript(script: .lightningNodeId) + } + } + if !anyAddr { + runScript(script: .lightningNodeId) + showMessage(message: "In order to connect via QR code remotely with Plasma you need to open the lightning config and add addr=, example: addr=100.89.65.23:9735. If you do not have a public IP you can use Plasma locally by clicking \"Connect Plasma Locally\".") + } } + } func parseDataResponse(script: SCRIPT, data: Data) { @@ -344,7 +391,7 @@ struct CoreLightning: View { if publicUrl != "" { self.qrImage = publicLnLink.qrQode } - self.lnlink = "lnlink:\(self.nodeId)@127.0.0.1:9735?token=\(rune)" + self.localLnlink = "lnlink:\(self.nodeId)@127.0.0.1:9735?token=\(rune)" if let onionHost = self.onionHost { self.quickConnectClnRest = "clnrest://\(onionHost):18765?token=\(rune)" } From 3c22c3c399fdc5c9373af5f382dfd93e3bad5185 Mon Sep 17 00:00:00 2001 From: Fontaine Date: Thu, 7 Nov 2024 12:51:13 -0500 Subject: [PATCH 04/22] fix: brew check script --- FullyNoded-Server/Scripts/BrewInstalled.command | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FullyNoded-Server/Scripts/BrewInstalled.command b/FullyNoded-Server/Scripts/BrewInstalled.command index ec2d5c8e..3d18f0bf 100755 --- a/FullyNoded-Server/Scripts/BrewInstalled.command +++ b/FullyNoded-Server/Scripts/BrewInstalled.command @@ -5,5 +5,5 @@ # # Created by Peter Denton on 9/5/24. # -echo brew help +sudo -u $(whoami) /opt/homebrew/bin/brew help exit 1 From bc3cb82e0a8765fbf2bd4701aae0eff011122f3a Mon Sep 17 00:00:00 2001 From: Fontaine Date: Thu, 7 Nov 2024 12:52:14 -0500 Subject: [PATCH 05/22] joinmarket: use python3 to run wallet-tool.py, increase size of QR, minor refactoring --- FullyNoded-Server/Scripts/InstallJoinMarket.command | 2 +- FullyNoded-Server/Views/JoinMarket.swift | 2 +- .../Views/JoinMarketTaggedReleases.swift | 11 +++++------ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/FullyNoded-Server/Scripts/InstallJoinMarket.command b/FullyNoded-Server/Scripts/InstallJoinMarket.command index b8fb5c0e..b71c7f51 100755 --- a/FullyNoded-Server/Scripts/InstallJoinMarket.command +++ b/FullyNoded-Server/Scripts/InstallJoinMarket.command @@ -21,7 +21,7 @@ function unpackTarball() { if [ ! -f "/Users/$(whoami)/Library/Application Support/joinmarket/joinmarket.cfg" ]; then source jmvenv/bin/activate cd scripts - python wallet-tool.py generate + python3 wallet-tool.py generate deactivate fi echo "Join Market Install complete." diff --git a/FullyNoded-Server/Views/JoinMarket.swift b/FullyNoded-Server/Views/JoinMarket.swift index 5332acd2..f1f56227 100644 --- a/FullyNoded-Server/Views/JoinMarket.swift +++ b/FullyNoded-Server/Views/JoinMarket.swift @@ -134,7 +134,7 @@ struct JoinMarket: View { Image(nsImage: qrImage) .resizable() .scaledToFit() - .frame(width: 200, height: 200) + .frame(width: 300, height: 300) .frame(maxWidth: .infinity, alignment: .leading) .padding(.leading) .onAppear { diff --git a/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift b/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift index b0b7432a..1f539fa9 100644 --- a/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift +++ b/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift @@ -115,6 +115,7 @@ struct JoinMarketTaggedReleasesView: View { private func configureJm() { + print("configureJm") var chain = UserDefaults.standard.object(forKey: "chain") as? String ?? "signet" let port = UserDefaults.standard.object(forKey: "port") as? String ?? "38332" switch chain { @@ -163,11 +164,11 @@ struct JoinMarketTaggedReleasesView: View { let jmConfPath = "/Users/\(NSUserName())/Library/Application Support/joinmarket/joinmarket.cfg" guard fileExists(path: jmConfPath) else { return } guard let conf = try? Data(contentsOf: URL(fileURLWithPath: jmConfPath)) else { - print("no jm conf") + showMessage(message: "No Join Market conf.") return } guard let string = String(data: conf, encoding: .utf8) else { - print("cant get string") + showMessage(message: "Can not convert JM config data to string.") return } let arr = string.split(separator: "\n") @@ -175,9 +176,7 @@ struct JoinMarketTaggedReleasesView: View { if item.hasPrefix("\(key) =") { let newConf = string.replacingOccurrences(of: item, with: key + " = " + value) if (try? newConf.write(to: URL(fileURLWithPath: jmConfPath), atomically: false, encoding: .utf8)) == nil { - print("failed writing to jm config") - } else { - print("wrote to joinmarket.cfg") + showMessage(message: "Failed writing to JM config.") } } } @@ -294,7 +293,7 @@ struct JoinMarketTaggedReleasesView: View { } private func downloadTask(url: URL, completion: @escaping (Data?) -> Void) { - var request = URLRequest(url: url) + let request = URLRequest(url: url) let task = URLSession.shared.downloadTask(with: request) { localURL, urlResponse, error in guard error == nil else { showMessage(message: error!.localizedDescription) From ab13d78b9ba04fb463142db71f8802a735c41d43 Mon Sep 17 00:00:00 2001 From: Fontaine Date: Thu, 7 Nov 2024 12:54:57 -0500 Subject: [PATCH 06/22] docs: readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 653c4559..5d76f192 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ ## Requirements - macOS 14.0 - M1/M2/M3/M? Silicon - arm64 -- brew -- xcode command line tools +- Python 3.10 for Join Market, should be located at `/Library/Frameworks/Python.framework/Versions`, if not a good guide can be found [here](https://www.codingforentrepreneurs.com/guides/install-python-on-macos). ## Installation On first use you will get a prompt about Fully Noded using an item on your keychain, this is an encryption key we create and use within the app to encrypt and decrypt sensitive data like your rpc password. From c6a218cb14e524754cbb5756fbbee81874673907 Mon Sep 17 00:00:00 2001 From: Fontaine Date: Sun, 10 Nov 2024 10:48:15 -0500 Subject: [PATCH 07/22] joinmarket: UI and install python3.10 via brew as dependency --- .../Scripts/InstallJoinMarket.command | 4 + FullyNoded-Server/Views/JoinMarket.swift | 253 +++++++++++------- 2 files changed, 159 insertions(+), 98 deletions(-) diff --git a/FullyNoded-Server/Scripts/InstallJoinMarket.command b/FullyNoded-Server/Scripts/InstallJoinMarket.command index b71c7f51..fc6b5b44 100755 --- a/FullyNoded-Server/Scripts/InstallJoinMarket.command +++ b/FullyNoded-Server/Scripts/InstallJoinMarket.command @@ -10,6 +10,10 @@ TAG_NAME=$1 AUTHOR=$2 function unpackTarball() { + if ! [ -d /Library/Frameworks/Python.framework/Versions/3.10 ]; then + echo "Installing python 3.10 with brew install python@3.10" + /opt/homebrew/bin/brew install python@3.10 + fi echo "Unpacking $TAG_NAME" cd /Users/$(whoami)/.fullynoded/JoinMarket /opt/homebrew/bin/gpg --import $AUTHOR.asc diff --git a/FullyNoded-Server/Views/JoinMarket.swift b/FullyNoded-Server/Views/JoinMarket.swift index f1f56227..02e639e3 100644 --- a/FullyNoded-Server/Views/JoinMarket.swift +++ b/FullyNoded-Server/Views/JoinMarket.swift @@ -26,129 +26,186 @@ struct JoinMarket: View { var body: some View { - HStack() { - Image(systemName: "server.rack") - .padding(.leading) - - Text("Join Market Server") - Spacer() - - Button { - isAutoRefreshing = false - isJoinMarketRunning() - } label: { - Image(systemName: "arrow.clockwise") - } - .padding([.trailing]) - } - .padding([.top]) - .frame(maxWidth: .infinity, alignment: .leading) - - HStack() { - if isAnimating { - ProgressView() - .scaleEffect(0.5) - .padding([.leading]) + Spacer() + VStack() { + HStack() { + Image(systemName: "server.rack") + .padding(.leading) + + Text("Join Market Server") + Spacer() + + Button { + isAutoRefreshing = false + isJoinMarketRunning() + } label: { + Image(systemName: "arrow.clockwise") + } + .padding([.trailing]) } - if isRunning { + //.padding([.]) + .frame(maxWidth: .infinity, alignment: .leading) + + HStack() { if isAnimating { - Image(systemName: "circle.fill") - .foregroundStyle(.orange) + ProgressView() + .scaleEffect(0.5) .padding([.leading]) + } + if isRunning { + if isAnimating { + Image(systemName: "circle.fill") + .foregroundStyle(.orange) + .padding([.leading]) + } else { + Image(systemName: "circle.fill") + .foregroundStyle(.green) + .padding([.leading]) + } + Text("Running") + .onAppear { + isAutoRefreshing = true + } } else { - Image(systemName: "circle.fill") - .foregroundStyle(.green) - .padding([.leading]) + if isAnimating { + Image(systemName: "circle.fill") + .foregroundStyle(.orange) + .padding([.leading]) + } else { + Image(systemName: "circle.fill") + .foregroundStyle(.red) + .padding([.leading]) + } + Text("Stopped") } - Text("Running") - .onAppear { - isAutoRefreshing = true + if !isRunning { + Button { + startJoinMarket() + } label: { + Text("Start") } - } else { - if isAnimating { - Image(systemName: "circle.fill") - .foregroundStyle(.orange) - .padding([.leading]) } else { - Image(systemName: "circle.fill") - .foregroundStyle(.red) - .padding([.leading]) + Button { + stopJoinMarket() + } label: { + Text("Stop") + } } - Text("Stopped") + EmptyView() + .onReceive(timerForStatus) { _ in + isJoinMarketRunning() + } } - if !isRunning { + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) + } + .padding() + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(.secondary, lineWidth: 1) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading, .trailing]) + ) + + VStack() { + Label("Network", systemImage: "network") + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) + + Text(selectedChain) + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) + } + .padding() + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(.secondary, lineWidth: 1) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading, .trailing]) + ) + + VStack() { + Label("Utilities", systemImage: "wrench.and.screwdriver") + .padding(.leading) + .frame(maxWidth: .infinity, alignment: .leading) + + HStack() { Button { - startJoinMarket() + openFile(file: "joinmarket.cfg") } label: { - Text("Start") + Text("joinmarket.cfg") } - } else { Button { - stopJoinMarket() + configureJm() } label: { - Text("Stop") + Text("Configure JM") } - } - EmptyView() - .onReceive(timerForStatus) { _ in - isJoinMarketRunning() + Button { + //openFile(file: "") + NSWorkspace.shared.selectFile(nil, inFileViewerRootedAtPath: "/Users/\(NSUserName())/Library/Application Support/joinmarket") + + } label: { + Text("Data Dir") } - } - .padding([.leading, .bottom]) - .frame(maxWidth: .infinity, alignment: .leading) - - Label(selectedChain.capitalized, systemImage: "network") - .padding([.leading, .bottom]) - .frame(maxWidth: .infinity, alignment: .leading) - - Label("Utilities", systemImage: "wrench.and.screwdriver") - .padding(.leading) - .frame(maxWidth: .infinity, alignment: .leading) - - HStack() { - Button { - openFile(file: "joinmarket.cfg") - } label: { - Text("joinmarket.cfg") } - Button { - configureJm() - } label: { - Text("Configure JM") - } - } - .padding([.leading, .trailing]) - .frame(maxWidth: .infinity, alignment: .leading) - - Label("Quick Connect", systemImage: "qrcode") - .padding([.leading, .top]) + .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) - - Button("Connect Fully Noded - Join Market", systemImage: "qrcode") { - showConnectUrls() } - .padding([.leading, .trailing]) - .frame(maxWidth: .infinity, alignment: .leading) + .padding() + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(.secondary, lineWidth: 1) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading, .trailing]) + ) - if let qrImage = qrImage { - Image(nsImage: qrImage) - .resizable() - .scaledToFit() - .frame(width: 300, height: 300) + VStack() { + Label("Quick Connect", systemImage: "qrcode") + .padding([.leading]) .frame(maxWidth: .infinity, alignment: .leading) - .padding(.leading) - .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + 15) { - self.qrImage = nil - self.url = nil + + Button("Connect Fully Noded - Join Market", systemImage: "qrcode") { + showConnectUrls() + } + .padding([.leading, .trailing]) + .frame(maxWidth: .infinity, alignment: .leading) + + if let qrImage = qrImage { + Image(nsImage: qrImage) + .resizable() + .scaledToFit() + .frame(width: 300, height: 300) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.leading) + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 15) { + self.qrImage = nil + self.url = nil + } } + if let url = url { + Link("Connect Fully Noded - Join Market", destination: URL(string: url)!) + .padding([.leading, .bottom]) + .frame(maxWidth: .infinity, alignment: .leading) } - if let url = url { - Link("Connect Fully Noded - Join Market", destination: URL(string: url)!) - .padding([.leading, .bottom]) - .frame(maxWidth: .infinity, alignment: .leading) } + + // if let hostnames = TorClient.sharedInstance.hostnames() { + // Text(hostnames[0] + ":" + "28183") + // } } + .padding() + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(.secondary, lineWidth: 1) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading, .trailing]) + ) + Spacer() From 8153b1947a8f5570068595fba01f54466dbd8791 Mon Sep 17 00:00:00 2001 From: Fontaine Date: Sun, 10 Nov 2024 10:49:03 -0500 Subject: [PATCH 08/22] fix: add borders to fields --- FullyNoded-Server/Views/BitcoinCore.swift | 373 +++++++++++--------- FullyNoded-Server/Views/CoreLightning.swift | 308 +++++++++------- 2 files changed, 383 insertions(+), 298 deletions(-) diff --git a/FullyNoded-Server/Views/BitcoinCore.swift b/FullyNoded-Server/Views/BitcoinCore.swift index d999cf85..539f9bfb 100644 --- a/FullyNoded-Server/Views/BitcoinCore.swift +++ b/FullyNoded-Server/Views/BitcoinCore.swift @@ -28,215 +28,252 @@ struct BitcoinCore: View { var body: some View { - HStack() { - Image(systemName: "server.rack") - .padding(.leading) - if let version = env["VERSION"] { - Text("Bitcoin Core Server v\(version)") - } else { - Text("Bitcoin Core Server") - } - if let blockchainInfo = blockchainInfo, blockchainInfo.initialblockdownload { - Label { - Text("Downloading the blockchain...") - .foregroundStyle(.secondary) - } icon: { - ProgressView() - .scaleEffect(0.5) - } - } - Spacer() - Button { - isBitcoinCoreRunning() - } label: { - Image(systemName: "arrow.clockwise") - } - .padding([.trailing]) - } - .padding([.top]) - .frame(maxWidth: .infinity, alignment: .leading) - - HStack() { - if isAnimating { - ProgressView() - .scaleEffect(0.5) - .padding([.leading]) - } - if isRunning { - if isAnimating { - Image(systemName: "circle.fill") - .foregroundStyle(.orange) - .padding([.leading]) - } else { - Image(systemName: "circle.fill") - .foregroundStyle(.green) - .padding([.leading]) - } - Text("Running") - } else { - if isAnimating { - Image(systemName: "circle.fill") - .foregroundStyle(.orange) - .padding([.leading]) + Spacer() + VStack() { + + HStack() { + Image(systemName: "server.rack") + .padding(.leading) + if let version = env["VERSION"] { + Text("Bitcoin Core Server v\(version)") } else { - Image(systemName: "circle.fill") - .foregroundStyle(.red) - .padding([.leading]) + Text("Bitcoin Core Server") } - Text("Stopped") - } - if !isRunning { - Button { - startBitcoinCore() - } label: { - Text("Start") + if let blockchainInfo = blockchainInfo, blockchainInfo.initialblockdownload { + Label { + Text("Downloading the blockchain...") + .foregroundStyle(.secondary) + } icon: { + ProgressView() + .scaleEffect(0.5) + } } - } else { + Spacer() Button { - stopBitcoinCore() + isBitcoinCoreRunning() } label: { - Text("Stop") + Image(systemName: "arrow.clockwise") } + .padding([.trailing]) } + .padding([.leading, .trailing]) + .frame(maxWidth: .infinity, alignment: .leading) - if let blockchainInfo = blockchainInfo { - if blockchainInfo.progressString == "Fully verified" { - Label { - Text(blockchainInfo.progressString) - } icon: { - Image(systemName: "checkmark.seal.fill") + HStack() { + if isAnimating { + ProgressView() + .scaleEffect(0.5) + .padding([.leading]) + } + if isRunning { + if isAnimating { + Image(systemName: "circle.fill") + .foregroundStyle(.orange) + .padding([.leading]) + } else { + Image(systemName: "circle.fill") .foregroundStyle(.green) + .padding([.leading]) } - //.padding([.leading]) - //.frame(maxWidth: .infinity, alignment: .leading) + Text("Running") } else { - Label { - Text(blockchainInfo.progressString) - } icon: { - Image(systemName: "xmark.seal") + if isAnimating { + Image(systemName: "circle.fill") .foregroundStyle(.orange) + .padding([.leading]) + } else { + Image(systemName: "circle.fill") + .foregroundStyle(.red) + .padding([.leading]) + } + Text("Stopped") + } + if !isRunning { + Button { + startBitcoinCore() + } label: { + Text("Start") + } + } else { + Button { + stopBitcoinCore() + } label: { + Text("Stop") } - //.padding([.leading]) - //.frame(maxWidth: .infinity, alignment: .leading) } - Label { - Text("Blockheight: " + "\(blockchainInfo.blockheight)") - } icon: { - Image(systemName: "square.stack.3d.up") + + if let blockchainInfo = blockchainInfo { + if blockchainInfo.progressString == "Fully verified" { + Label { + Text(blockchainInfo.progressString) + } icon: { + Image(systemName: "checkmark.seal.fill") + .foregroundStyle(.green) + } + } else { + Label { + Text(blockchainInfo.progressString) + } icon: { + Image(systemName: "xmark.seal") + .foregroundStyle(.orange) + } + } + Label { + Text("Blockheight: " + "\(blockchainInfo.blockheight)") + } icon: { + Image(systemName: "square.stack.3d.up") + } } - //.padding([.leading]) - // .frame(maxWidth: .infinity, alignment: .leading) + EmptyView() + .onReceive(timerForBitcoinStatus) { _ in + isBitcoinCoreRunning() + } } + .padding([.leading, .bottom]) + .frame(maxWidth: .infinity, alignment: .leading) - EmptyView() - .onReceive(timerForBitcoinStatus) { _ in - isBitcoinCoreRunning() - } } - .padding([.leading, .bottom]) - .frame(maxWidth: .infinity, alignment: .leading) + .padding([.top]) + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(.secondary, lineWidth: 1) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading, .trailing]) + ) + VStack() { + Label("Network", systemImage: "network") + .padding(.leading) + .frame(maxWidth: .infinity, alignment: .leading) - - Label("Network", systemImage: "network") - .padding(.leading) - .frame(maxWidth: .infinity, alignment: .leading) - - HStack() { - Picker("", selection: $selectedChain) { - ForEach(chains, id: \.self) { - Text($0) + HStack() { + Picker("", selection: $selectedChain) { + ForEach(chains, id: \.self) { + Text($0) + } } + .onChange(of: selectedChain) { + updateChain(chain: selectedChain) + isBitcoinCoreRunning() + } + .frame(width: 150) } - .onChange(of: selectedChain) { - updateChain(chain: selectedChain) - isBitcoinCoreRunning() - } - .frame(width: 150) - } - .padding([.leading, .trailing, .bottom]) - .frame(maxWidth: .infinity, alignment: .leading) - - Label("Utilities", systemImage: "wrench.and.screwdriver") - .padding(.leading) + .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) + + } + .padding() + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(.secondary, lineWidth: 1) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading, .trailing]) + ) - HStack() { - Button { - runScript(script: .launchVerifier) - } label: { - Text("Verify") - } - .padding(.leading) - Button { - openFile(file: "\(Defaults.shared.dataDir)/bitcoin.conf") - } label: { - Text("bitcoin.conf") - } - if let debugPath = debugLogPath() { + VStack() { + Label("Utilities", systemImage: "wrench.and.screwdriver") + .padding(.leading) + .frame(maxWidth: .infinity, alignment: .leading) + + HStack() { Button { - openFile(file: debugPath) + runScript(script: .launchVerifier) } label: { - Text("debug.log") + Text("Verify") } - } - Button { - refreshRPCAuth() - } label: { - Text("Refresh RPC Authentication") - } - Button { - NSWorkspace.shared.selectFile(nil, inFileViewerRootedAtPath: Defaults.shared.dataDir) - } label: { - Text("Data") - } - if Defaults.shared.prune != 0 { + .padding(.leading) Button { - promptToReindex = true + openFile(file: "\(Defaults.shared.dataDir)/bitcoin.conf") } label: { - Text("Reindex") + Text("bitcoin.conf") } + if let debugPath = debugLogPath() { + Button { + openFile(file: debugPath) + } label: { + Text("debug.log") + } + } + Button { + refreshRPCAuth() + } label: { + Text("Refresh RPC Authentication") + } + Button { + NSWorkspace.shared.selectFile(nil, inFileViewerRootedAtPath: Defaults.shared.dataDir) + } label: { + Text("Data") + } + if Defaults.shared.prune != 0 { + Button { + promptToReindex = true + } label: { + Text("Reindex") + } + } + } - - } - .padding([.leading, .trailing]) - .frame(maxWidth: .infinity, alignment: .leading) - - Label("Quick Connect", systemImage: "qrcode") - .padding([.leading, .top]) + .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) - - Button("Connect Fully Noded", systemImage: "qrcode") { - connectFN() } - .padding([.leading, .trailing]) - .frame(maxWidth: .infinity, alignment: .leading) - - if let qrImage = qrImage { - Image(nsImage: qrImage) - .resizable() - .scaledToFit() - .frame(width: 100, height: 100) + .padding() + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(.secondary, lineWidth: 1) .frame(maxWidth: .infinity, alignment: .leading) - .padding(.leading) - .onAppear { - setSensitiveDataToNil() - } - } + .padding([.leading, .trailing]) + ) - if let fullyNodedUrl = fullyNodedUrl { - Link("Connect Fully Noded", destination: URL(string: fullyNodedUrl)!) + + + VStack() { + Label("Quick Connect", systemImage: "qrcode") .padding([.leading]) .frame(maxWidth: .infinity, alignment: .leading) + + Button("Connect Fully Noded", systemImage: "qrcode") { + connectFN() + } + .padding([.leading, .trailing]) + .frame(maxWidth: .infinity, alignment: .leading) + + if let qrImage = qrImage { + Image(nsImage: qrImage) + .resizable() + .scaledToFit() + .frame(width: 100, height: 100) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.leading) + .onAppear { + setSensitiveDataToNil() + } + } + + if let fullyNodedUrl = fullyNodedUrl { + Link("Connect Fully Noded", destination: URL(string: fullyNodedUrl)!) + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) + } + + if let unifyUrl = unifyUrl { + Link("Connect Unify", destination: URL(string: unifyUrl)!) + .padding([.leading, .bottom]) + .frame(maxWidth: .infinity, alignment: .leading) + } } - - if let unifyUrl = unifyUrl { - Link("Connect Unify", destination: URL(string: unifyUrl)!) - .padding([.leading, .bottom]) + .padding() + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(.secondary, lineWidth: 1) .frame(maxWidth: .infinity, alignment: .leading) - } + .padding([.leading, .trailing]) + ) Spacer() diff --git a/FullyNoded-Server/Views/CoreLightning.swift b/FullyNoded-Server/Views/CoreLightning.swift index 135671fe..fa09dd76 100644 --- a/FullyNoded-Server/Views/CoreLightning.swift +++ b/FullyNoded-Server/Views/CoreLightning.swift @@ -24,169 +24,217 @@ struct CoreLightning: View { @State private var quickConnectClnRest: String? = nil var body: some View { - HStack() { - Image(systemName: "server.rack") - .padding(.leading) - - Text("Core Lightning Server") - Spacer() - Button { - isLightningOn() - } label: { - Image(systemName: "arrow.clockwise") - } - .padding(.trailing) - } - .padding([.top]) - .frame(maxWidth: .infinity, alignment: .leading) - - HStack() { - if isAnimating { - ProgressView() - .scaleEffect(0.5) + Spacer() + VStack() { + HStack() { + Image(systemName: "server.rack") + .padding(.leading) + + Text("Core Lightning Server") + Spacer() + Button { + isLightningOn() + } label: { + Image(systemName: "arrow.clockwise") + } + .padding(.trailing) } - if isRunning { + //.padding([.top]) + .frame(maxWidth: .infinity, alignment: .leading) + + HStack() { if isAnimating { - Image(systemName: "circle.fill") - .foregroundStyle(.orange) - .padding(.leading) + ProgressView() + .scaleEffect(0.5) + } + if isRunning { + if isAnimating { + Image(systemName: "circle.fill") + .foregroundStyle(.orange) + .padding(.leading) + } else { + Image(systemName: "circle.fill") + .foregroundStyle(.green) + .padding(.leading) + } + Text("Running") } else { - Image(systemName: "circle.fill") - .foregroundStyle(.green) - .padding(.leading) + if isAnimating { + Image(systemName: "circle.fill") + .foregroundStyle(.orange) + .padding(.leading) + } else { + Image(systemName: "circle.fill") + .foregroundStyle(.red) + .padding(.leading) + } + Text("Stopped") } - Text("Running") - } else { - if isAnimating { - Image(systemName: "circle.fill") - .foregroundStyle(.orange) - .padding(.leading) + + if !isRunning { + Button { + startLightning() + } label: { + Text("Start") + } } else { - Image(systemName: "circle.fill") - .foregroundStyle(.red) - .padding(.leading) + Button { + stopLightning() + } label: { + Text("Stop") + } } - Text("Stopped") + } + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) + } + .padding() + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(.secondary, lineWidth: 1) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading, .trailing]) + ) + + + VStack() { + Label("Network", systemImage: "network") + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) + + Text(selectedChain) + .padding([.leading]) + .padding(.leading) + .frame(maxWidth: .infinity, alignment: .leading) + } + .padding() + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(.secondary, lineWidth: 1) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading, .trailing]) + ) + + VStack() { + Label("Utilities", systemImage: "wrench.and.screwdriver") + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) - if !isRunning { + HStack() { Button { - startLightning() + let env = ["FILE":"/Users/\(NSUserName())/.lightning/config"] + openConf(script: .openFile, env: env, args: []) { _ in } } label: { - Text("Start") + Text("Config") } - } else { + .padding(.leading) + Button { - stopLightning() + let env = ["FILE":"/Users/\(NSUserName())/.lightning/lightning.log"] + openConf(script: .openFile, env: env, args: []) { _ in } } label: { - Text("Stop") + Text("Log") } } - - } - .padding([.leading]) - .frame(maxWidth: .infinity, alignment: .leading) - - Label(selectedChain.capitalized, systemImage: "network") - .padding([.leading, .top]) - .frame(maxWidth: .infinity, alignment: .leading) - - Label("Utilities", systemImage: "wrench.and.screwdriver") - .padding([.leading, .top]) - .frame(maxWidth: .infinity, alignment: .leading) - - HStack() { - Button { - let env = ["FILE":"/Users/\(NSUserName())/.lightning/config"] - openConf(script: .openFile, env: env, args: []) { _ in } - } label: { - Text("Config") - } - .padding(.leading) - - Button { - let env = ["FILE":"/Users/\(NSUserName())/.lightning/lightning.log"] - openConf(script: .openFile, env: env, args: []) { _ in } - } label: { - Text("Log") - } - } - .padding([.leading, .trailing]) - .frame(maxWidth: .infinity, alignment: .leading) - - Label("Quick Connect", systemImage: "qrcode") - .padding([.leading, .top]) + .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) - - Button("Connect Plasma remotely via LNLink", systemImage: "qrcode") { - getLnLink(isLocal: false) } - .padding([.leading, .trailing]) - .frame(maxWidth: .infinity, alignment: .leading) - - - - if let qrImage = qrImage { - Image(nsImage: qrImage) - .resizable() - .scaledToFit() - .frame(width: 100, height: 100) + .padding() + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(.secondary, lineWidth: 1) .frame(maxWidth: .infinity, alignment: .leading) - .padding(.leading) - .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + 15) { - self.qrImage = nil - self.lnlink = nil - } - } - } + .padding([.leading, .trailing]) + ) - Button("Connect via Onion (clnrest-rs)", systemImage: "qrcode") { - self.onionHost = TorClient.sharedInstance.hostnames()?[5] - runScript(script: .getRune) - } - .padding([.leading]) - .frame(maxWidth: .infinity, alignment: .leading) - if let quickConnectClnRest = self.quickConnectClnRest { - let qr = quickConnectClnRest.qrQode - Image(nsImage: qr) - .resizable() - .scaledToFit() - .frame(width: 100, height: 100) + VStack() { + Label("Quick Connect", systemImage: "qrcode") + .padding([.leading]) .frame(maxWidth: .infinity, alignment: .leading) - .padding(.leading) - .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + 15) { - self.quickConnectClnRest = nil - self.onionHost = nil - self.lnlink = nil + + Button("Connect Plasma remotely via LNLink", systemImage: "qrcode") { + getLnLink(isLocal: false) + } + .padding([.leading, .trailing]) + .frame(maxWidth: .infinity, alignment: .leading) + + + + if let qrImage = qrImage { + Image(nsImage: qrImage) + .resizable() + .scaledToFit() + .frame(width: 100, height: 100) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.leading) + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 15) { + self.qrImage = nil + self.lnlink = nil + } } - } - if let onionHost = onionHost { - Text(onionHost) - .textSelection(.enabled) } - } - - if plasmaExists { - Button("Connect Plasma Locally") { - getLnLink(isLocal: true) + + Button("Connect via Onion (clnrest-rs)", systemImage: "qrcode") { + self.onionHost = TorClient.sharedInstance.hostnames()?[5] + runScript(script: .getRune) } .padding([.leading]) .frame(maxWidth: .infinity, alignment: .leading) - if let lnlink = self.localLnlink { - Link("Connect Plasma Locally via LNLink", destination: URL(string: lnlink)!) - .padding([.leading]) + if let quickConnectClnRest = self.quickConnectClnRest { + let qr = quickConnectClnRest.qrQode + Image(nsImage: qr) + .resizable() + .scaledToFit() + .frame(width: 100, height: 100) .frame(maxWidth: .infinity, alignment: .leading) + .padding(.leading) + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 15) { + self.quickConnectClnRest = nil + self.onionHost = nil + self.lnlink = nil + } + } + if let onionHost = onionHost { + Text(onionHost) + .textSelection(.enabled) + } } - } else { - Link("Download Plasma", destination: URL(string: "https://apps.apple.com/us/app/plasma-core-lightning-wallet/id6468914352")!) + if plasmaExists { + Button("Connect Plasma Locally") { + getLnLink(isLocal: true) + } .padding([.leading]) .frame(maxWidth: .infinity, alignment: .leading) + + if let lnlink = self.localLnlink { + Link("Connect Plasma Locally via LNLink", destination: URL(string: lnlink)!) + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) + } + + } else { + Link("Download Plasma", destination: URL(string: "https://apps.apple.com/us/app/plasma-core-lightning-wallet/id6468914352")!) + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) + } } + .padding() + .cornerRadius(8) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(.secondary, lineWidth: 1) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading, .trailing]) + ) Spacer() HStack() { From 424df747e3427ba9c0abb90165b94488601418e7 Mon Sep 17 00:00:00 2001 From: Fontaine Date: Tue, 12 Nov 2024 11:26:55 -0500 Subject: [PATCH 09/22] feat: jm now configures for coinjoins and tor, needs testing. General refactoring. Ability to increase gap limit and rescan via join market. --- FullyNoded-Server.xcodeproj/project.pbxproj | 8 + FullyNoded-Server/Extensions.swift | 7 + FullyNoded-Server/Helpers/BitcoinRPC.swift | 5 +- FullyNoded-Server/Helpers/Script.swift | 6 + .../Scripts/IncreaseGapLimit.command | 19 ++ .../Scripts/LaunchIncreaseGapLimit.command | 15 ++ FullyNoded-Server/Scripts/StartJm.command | 2 +- FullyNoded-Server/Views/BitcoinCore.swift | 142 ++++++------ FullyNoded-Server/Views/CoreLightning.swift | 203 +++++++++--------- FullyNoded-Server/Views/JoinMarket.swift | 170 ++++++++------- 10 files changed, 320 insertions(+), 257 deletions(-) create mode 100755 FullyNoded-Server/Scripts/IncreaseGapLimit.command create mode 100755 FullyNoded-Server/Scripts/LaunchIncreaseGapLimit.command diff --git a/FullyNoded-Server.xcodeproj/project.pbxproj b/FullyNoded-Server.xcodeproj/project.pbxproj index d32c9570..5441ce45 100644 --- a/FullyNoded-Server.xcodeproj/project.pbxproj +++ b/FullyNoded-Server.xcodeproj/project.pbxproj @@ -75,6 +75,8 @@ 0AD7BE212CC2B1F100428D02 /* StartJm.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AD7BE202CC2B1F100428D02 /* StartJm.command */; }; 0AD7BE232CC2B47400428D02 /* LaunchJMStarter.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AD7BE222CC2B47400428D02 /* LaunchJMStarter.command */; }; 0AD7BE252CC2BCEF00428D02 /* StopJm.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AD7BE242CC2BCEF00428D02 /* StopJm.command */; }; + 593A891F2CE28334001504F0 /* IncreaseGapLimit.command in Resources */ = {isa = PBXBuildFile; fileRef = 593A891E2CE28334001504F0 /* IncreaseGapLimit.command */; }; + 593A89212CE28400001504F0 /* LaunchIncreaseGapLimit.command in Resources */ = {isa = PBXBuildFile; fileRef = 593A89202CE28400001504F0 /* LaunchIncreaseGapLimit.command */; }; BF3EE5E9CBA2EF2BFB961A21 /* Pods_FullyNoded_Server.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D69717EDC523941317071BC8 /* Pods_FullyNoded_Server.framework */; }; /* End PBXBuildFile section */ @@ -151,6 +153,8 @@ 0AD7BE222CC2B47400428D02 /* LaunchJMStarter.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = LaunchJMStarter.command; sourceTree = ""; }; 0AD7BE242CC2BCEF00428D02 /* StopJm.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = StopJm.command; sourceTree = ""; }; 1B8BA5D0924A1AE2EC951616 /* Pods-FullyNoded-Server.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FullyNoded-Server.debug.xcconfig"; path = "Target Support Files/Pods-FullyNoded-Server/Pods-FullyNoded-Server.debug.xcconfig"; sourceTree = ""; }; + 593A891E2CE28334001504F0 /* IncreaseGapLimit.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = IncreaseGapLimit.command; sourceTree = ""; }; + 593A89202CE28400001504F0 /* LaunchIncreaseGapLimit.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = LaunchIncreaseGapLimit.command; sourceTree = ""; }; D69717EDC523941317071BC8 /* Pods_FullyNoded_Server.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FullyNoded_Server.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DEFA9324C99AAF1DC60AC76C /* Pods-FullyNoded-Server.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FullyNoded-Server.release.xcconfig"; path = "Target Support Files/Pods-FullyNoded-Server/Pods-FullyNoded-Server.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -306,6 +310,8 @@ 0AD7BE222CC2B47400428D02 /* LaunchJMStarter.command */, 0AD7BE242CC2BCEF00428D02 /* StopJm.command */, 0A0632AF2CD06B470059FAD4 /* Reindex.command */, + 593A891E2CE28334001504F0 /* IncreaseGapLimit.command */, + 593A89202CE28400001504F0 /* LaunchIncreaseGapLimit.command */, ); path = Scripts; sourceTree = ""; @@ -410,6 +416,7 @@ 0A5CE8DE2C8A225A00534A8D /* LaunchLightningInstall.command in Resources */, 0A5CE8F22C91FE2A00534A8D /* StartLightning.command in Resources */, 0AA6923E2C7F831F00366192 /* Assets.xcassets in Resources */, + 593A89212CE28400001504F0 /* LaunchIncreaseGapLimit.command in Resources */, 0A5CE8F62C92013D00534A8D /* StopLightning.command in Resources */, 0AD7BE112CBD6AA500428D02 /* InstallJoinMarket.command in Resources */, 0AA6925F2C7F8EC700366192 /* CheckXCodeSelect.command in Resources */, @@ -421,6 +428,7 @@ 0A573E1D2CADC15400899F84 /* KillBitcoind.command in Resources */, 0A0632B02CD06B470059FAD4 /* Reindex.command in Resources */, 0A5CE8E22C8A2F4000534A8D /* IsLightningOn.command in Resources */, + 593A891F2CE28334001504F0 /* IncreaseGapLimit.command in Resources */, 0AA6925E2C7F8EC700366192 /* CheckForBitcoinCore.command in Resources */, 0A573E312CB577D100899F84 /* GetRune.command in Resources */, 0AA692682C7F8EC700366192 /* LaunchXcodeInstall.command in Resources */, diff --git a/FullyNoded-Server/Extensions.swift b/FullyNoded-Server/Extensions.swift index 5cafb2ff..66da02ff 100644 --- a/FullyNoded-Server/Extensions.swift +++ b/FullyNoded-Server/Extensions.swift @@ -31,6 +31,13 @@ extension Double { let exahashesPerSecond = self / 1000000000000000000.0 return "\(Int(exahashesPerSecond)) EX/s" } + + var avoidNotation: String { + let numberFormatter = NumberFormatter() + numberFormatter.maximumFractionDigits = 8 + numberFormatter.numberStyle = .decimal + return numberFormatter.string(for: self) ?? "" + } } extension Int { diff --git a/FullyNoded-Server/Helpers/BitcoinRPC.swift b/FullyNoded-Server/Helpers/BitcoinRPC.swift index ba1dae02..d22a87f2 100644 --- a/FullyNoded-Server/Helpers/BitcoinRPC.swift +++ b/FullyNoded-Server/Helpers/BitcoinRPC.swift @@ -42,7 +42,10 @@ class BitcoinRPC { return } - let stringUrl = "http://\(user):\(rpcPassword)@\(nodeIp)" + var stringUrl = "http://\(user):\(rpcPassword)@\(nodeIp)" + if method == "rescanblockchain" { + stringUrl += "/wallet/jm_wallet" + } guard let url = URL(string: stringUrl) else { completion((nil, "Error converting the url.")) return diff --git a/FullyNoded-Server/Helpers/Script.swift b/FullyNoded-Server/Helpers/Script.swift index d69bd374..882ca221 100644 --- a/FullyNoded-Server/Helpers/Script.swift +++ b/FullyNoded-Server/Helpers/Script.swift @@ -8,6 +8,8 @@ import Foundation public enum SCRIPT: String { + case launchIncreaseGapLimit + case increaseGapLimit case reindex case stopJm case launchJmStarter @@ -44,6 +46,10 @@ public enum SCRIPT: String { var stringValue:String { switch self { + case .launchIncreaseGapLimit: + return "LaunchIncreaseGapLimit" + case .increaseGapLimit: + return "IncreaseGapLimit" case .reindex: return "Reindex" case .stopJm: diff --git a/FullyNoded-Server/Scripts/IncreaseGapLimit.command b/FullyNoded-Server/Scripts/IncreaseGapLimit.command new file mode 100755 index 00000000..9fb0b55d --- /dev/null +++ b/FullyNoded-Server/Scripts/IncreaseGapLimit.command @@ -0,0 +1,19 @@ +#!/bin/sh + +# IncreaseGapLimit.command +# FullyNoded-Server +# +# Created by Peter Denton on 11/11/24. +# +TAG_NAME=$1 +GAP_AMOUNT=$2 +WALLET_NAME=$3 + +cd /Users/$(whoami)/.fullynoded/JoinMarket/joinmarket-$TAG_NAME +echo "source jmvenv/bin/activate" +source jmvenv/bin/activate +echo "cd scripts" +cd scripts +echo "python3 wallet-tool.py -g $GAP_AMOUNT $WALLET_NAME" +python3 wallet-tool.py -g $GAP_AMOUNT $WALLET_NAME + diff --git a/FullyNoded-Server/Scripts/LaunchIncreaseGapLimit.command b/FullyNoded-Server/Scripts/LaunchIncreaseGapLimit.command new file mode 100755 index 00000000..fb1e4c3e --- /dev/null +++ b/FullyNoded-Server/Scripts/LaunchIncreaseGapLimit.command @@ -0,0 +1,15 @@ +#!/bin/sh + +# LaunchIncreaseGapLimit.command +# FullyNoded-Server +# +# Created by Peter Denton on 11/11/24. +# + +SCRIPT_PATH="/Users/$(whoami)/.fullynoded/increaseGapLimit.sh" +LOG="/Users/$(whoami)/.fullynoded/fullynoded.log" +touch $SCRIPT_PATH +echo "\"$(cd "$(dirname "$0")"; pwd)/IncreaseGapLimit.command\" $TAG_NAME $GAP_AMOUNT $WALLET_NAME | tee -a $LOG" > $SCRIPT_PATH +chmod +x $SCRIPT_PATH +open -a Terminal $SCRIPT_PATH +exit 1 diff --git a/FullyNoded-Server/Scripts/StartJm.command b/FullyNoded-Server/Scripts/StartJm.command index 663ca92c..3b22573a 100755 --- a/FullyNoded-Server/Scripts/StartJm.command +++ b/FullyNoded-Server/Scripts/StartJm.command @@ -24,5 +24,5 @@ source jmvenv/bin/activate echo "cd scripts" cd scripts echo "python jmwalletd.py" -python jmwalletd.py +python3 jmwalletd.py diff --git a/FullyNoded-Server/Views/BitcoinCore.swift b/FullyNoded-Server/Views/BitcoinCore.swift index 539f9bfb..49861313 100644 --- a/FullyNoded-Server/Views/BitcoinCore.swift +++ b/FullyNoded-Server/Views/BitcoinCore.swift @@ -119,7 +119,7 @@ struct BitcoinCore: View { } } Label { - Text("Blockheight: " + "\(blockchainInfo.blockheight)") + Text("Blockheight " + "\(blockchainInfo.blockheight)") } icon: { Image(systemName: "square.stack.3d.up") } @@ -181,7 +181,16 @@ struct BitcoinCore: View { HStack() { Button { - runScript(script: .launchVerifier) + ScriptUtil.runScript(script: .launchVerifier, env: env, args: nil) { (_, _, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } else { + + } + return + } + } } label: { Text("Verify") } @@ -206,7 +215,7 @@ struct BitcoinCore: View { Button { NSWorkspace.shared.selectFile(nil, inFileViewerRootedAtPath: Defaults.shared.dataDir) } label: { - Text("Data") + Text("Data Dir") } if Defaults.shared.prune != 0 { Button { @@ -287,11 +296,19 @@ struct BitcoinCore: View { .alert(message, isPresented: $showError) { Button("OK", role: .cancel) {} } - .alert("This action will delete the entire blockchain and download it again, are you sure you want to proceed?", isPresented: $promptToReindex) { + .alert("This action will delete the entire blockchain and download it again, are you sure you want to proceed? (it can take awhile..)", isPresented: $promptToReindex) { Button("Reindex now", role: .destructive) { if !isRunning { isAnimating = true - runScript(script: .reindex) + ScriptUtil.runScript(script: .reindex, env: env, args: nil) { (_, _, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } + return + } + showMessage(message: "Reindex initiated, this can take awhile..") + } } else { showMessage(message: "Bitcoin Core must stopped before redindexing.") } @@ -401,7 +418,18 @@ struct BitcoinCore: View { showMessage(message: "BitcoinRPCCreds update failed") return } - runScript(script: .killBitcoind) + ScriptUtil.runScript(script: .killBitcoind, env: env, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } else { + + } + return + } + guard let output = output else { return } + parseScriptResult(script: .killBitcoind, result: output) + } } } @@ -476,8 +504,14 @@ struct BitcoinCore: View { } private func openFile(file: String) { - let env = ["FILE": "\(file)"] - openConf(script: .openFile, env: env, args: []) { _ in } + ScriptUtil.runScript(script: .openFile, env: ["FILE": "\(file)"], args: nil) { (_, _, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } + return + } + } } private func updateChain(chain: String) { @@ -564,12 +598,34 @@ struct BitcoinCore: View { private func startBitcoinCore() { isAnimating = true - runScript(script: .startBitcoin) + ScriptUtil.runScript(script: .startBitcoin, env: env, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } else { + + } + return + } + guard let output = output else { return } + parseDidBitcoinStart(result: output) + } } private func startBitcoinParse(result: String) { DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) { - self.runScript(script: .didBitcoindStart) + ScriptUtil.runScript(script: .didBitcoindStart, env: env, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } else { + + } + return + } + guard let output = output else { return } + parseScriptResult(script: .didBitcoindStart, result: output) + } } } @@ -686,50 +742,7 @@ struct BitcoinCore: View { showError = true self.message = message } - - private func runScript(script: SCRIPT) { - #if DEBUG - print("run script: \(script.stringValue)") - #endif - let taskQueue = DispatchQueue.global(qos: DispatchQoS.QoSClass.background) - taskQueue.async { - let resource = script.stringValue - guard let path = Bundle.main.path(forResource: resource, ofType: "command") else { return } - let stdOut = Pipe() - let stdErr = Pipe() - let task = Process() - task.launchPath = path - task.environment = env - task.standardOutput = stdOut - task.standardError = stdErr - task.launch() - task.waitUntilExit() - let data = stdOut.fileHandleForReading.readDataToEndOfFile() - let errData = stdErr.fileHandleForReading.readDataToEndOfFile() - var result = "" - - if let output = String(data: data, encoding: .utf8) { - #if DEBUG - print("output: \(output)") - #endif - result += output - } - - if let errorOutput = String(data: errData, encoding: .utf8) { - #if DEBUG - print("error: \(errorOutput)") - #endif - result += errorOutput - if errorOutput != "" { - showMessage(message: errorOutput) - } - } - - parseScriptResult(script: script, result: result) - } - } - func parseScriptResult(script: SCRIPT, result: String) { switch script { case .startBitcoin: @@ -749,27 +762,4 @@ struct BitcoinCore: View { break } } - - private func openConf(script: SCRIPT, env: [String:String], args: [String], completion: @escaping ((Bool)) -> Void) { - let resource = script.stringValue - guard let path = Bundle.main.path(forResource: resource, ofType: "command") else { - return - } - let stdOut = Pipe() - let task = Process() - task.launchPath = path - task.environment = env - task.arguments = args - task.standardOutput = stdOut - task.launch() - task.waitUntilExit() - let data = stdOut.fileHandleForReading.readDataToEndOfFile() - var result = "" - if let output = String(data: data, encoding: .utf8) { - result += output - completion(true) - } else { - completion(false) - } - } } diff --git a/FullyNoded-Server/Views/CoreLightning.swift b/FullyNoded-Server/Views/CoreLightning.swift index fa09dd76..0a1ba03f 100644 --- a/FullyNoded-Server/Views/CoreLightning.swift +++ b/FullyNoded-Server/Views/CoreLightning.swift @@ -39,7 +39,6 @@ struct CoreLightning: View { } .padding(.trailing) } - //.padding([.top]) .frame(maxWidth: .infinity, alignment: .leading) HStack() { @@ -98,7 +97,6 @@ struct CoreLightning: View { .padding([.leading, .trailing]) ) - VStack() { Label("Network", systemImage: "network") .padding([.leading]) @@ -126,7 +124,7 @@ struct CoreLightning: View { HStack() { Button { let env = ["FILE":"/Users/\(NSUserName())/.lightning/config"] - openConf(script: .openFile, env: env, args: []) { _ in } + openFile(env: env) } label: { Text("Config") } @@ -134,7 +132,7 @@ struct CoreLightning: View { Button { let env = ["FILE":"/Users/\(NSUserName())/.lightning/lightning.log"] - openConf(script: .openFile, env: env, args: []) { _ in } + openFile(env: env) } label: { Text("Log") } @@ -151,7 +149,6 @@ struct CoreLightning: View { .padding([.leading, .trailing]) ) - VStack() { Label("Quick Connect", systemImage: "qrcode") .padding([.leading]) @@ -162,9 +159,7 @@ struct CoreLightning: View { } .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) - - - + if let qrImage = qrImage { Image(nsImage: qrImage) .resizable() @@ -182,7 +177,18 @@ struct CoreLightning: View { Button("Connect via Onion (clnrest-rs)", systemImage: "qrcode") { self.onionHost = TorClient.sharedInstance.hostnames()?[5] - runScript(script: .getRune) + ScriptUtil.runScript(script: .getRune, env: nil, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } else if let data = rawData { + parseDataResponse(script: .getRune, data: data) + } + return + } + guard let output = output, let data = rawData else { return } + parseDataResponse(script: .getRune, data: data) + } } .padding([.leading]) .frame(maxWidth: .infinity, alignment: .leading) @@ -235,7 +241,6 @@ struct CoreLightning: View { .frame(maxWidth: .infinity, alignment: .leading) .padding([.leading, .trailing]) ) - Spacer() HStack() { Label(logOutput, systemImage: "info.circle") @@ -250,6 +255,17 @@ struct CoreLightning: View { } } + private func openFile(env: [String: String]?) { + ScriptUtil.runScript(script: .openFile, env: env, args: nil) { (_, _, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } + return + } + } + } + private func checkIfPlasmaExists() { guard let filePaths = try? FileManager.default.contentsOfDirectory(atPath: "/Applications") else { return } for filePath in filePaths { @@ -265,17 +281,65 @@ struct CoreLightning: View { private func startLightning() { isAnimating = true - runScript(script: .startLightning) + DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { + ScriptUtil.runScript(script: .lightingRunning, env: nil, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } else if let output = output { + parseScriptResult(script: .lightingRunning, result: output) + } + return + } + guard let output = output else { return } + parseScriptResult(script: .lightingRunning, result: output) + } + } + ScriptUtil.runScript(script: .startLightning, env: nil, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } else if let output = output { + parseScriptResult(script: .startLightning, result: output) + } + return + } + guard let output = output else { return } + parseScriptResult(script: .startLightning, result: output) + } } private func isLightningOn() { isAnimating = true - runScript(script: .lightingRunning) + ScriptUtil.runScript(script: .lightingRunning, env: nil, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } else if let output = output { + parseScriptResult(script: .lightingRunning, result: output) + } + return + } + guard let output = output else { return } + parseScriptResult(script: .lightingRunning, result: output) + } + } private func stopLightning() { isAnimating = true - runScript(script: .stopLightning) + ScriptUtil.runScript(script: .stopLightning, env: nil, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } else if let output = output { + parseScriptResult(script: .stopLightning, result: output) + } + return + } + guard let output = output else { return } + parseScriptResult(script: .stopLightning, result: output) + } } private func stopLightningParse(result: String) { @@ -306,69 +370,6 @@ struct CoreLightning: View { self.message = message } - private func runScript(script: SCRIPT) { - #if DEBUG - print("run script: \(script.stringValue)") - #endif - - let taskQueue = DispatchQueue.global(qos: DispatchQoS.QoSClass.background) - taskQueue.async { - let resource = script.stringValue - guard let path = Bundle.main.path(forResource: resource, ofType: "command") else { return } - let stdOut = Pipe() - let stdErr = Pipe() - let task = Process() - task.launchPath = path - task.standardOutput = stdOut - task.standardError = stdErr - task.launch() - - switch script { - case .startLightning: - DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { - self.runScript(script: .lightingRunning) - } - - default: - break - } - - task.waitUntilExit() - - let data = stdOut.fileHandleForReading.readDataToEndOfFile() - let errData = stdErr.fileHandleForReading.readDataToEndOfFile() - var result = "" - - if let output = String(data: data, encoding: .utf8) { - #if DEBUG - print("output: \(output)") - #endif - result += output - } - - switch script { - case .getRune, .lightningNodeId: - parseDataResponse(script: script, data: data) - - default: - break - } - - if let errorOutput = String(data: errData, encoding: .utf8) { - #if DEBUG - print("error: \(errorOutput)") - #endif - - if errorOutput != "", !errorOutput.contains("Your account is limited to 1 simultaneous ngrok agent sessions") { - showMessage(message: errorOutput) - isAnimating = false - } else { - parseScriptResult(script: script, result: result) - } - } - } - } - func getLnLink(isLocal: Bool) { ScriptUtil.runScript(script: .lightningNodeId, env: nil, args: nil) { (output, rawData, errorMessage) in guard let data = rawData else { @@ -402,7 +403,7 @@ struct CoreLightning: View { func getPublicUrl(isLocal: Bool) { if isLocal { self.publicUrl = "127.0.0.1:9735" - runScript(script: .lightningNodeId) + getNodeID() } else { let path = URL(fileURLWithPath: "/Users/\(NSUserName())/.lightning/config") guard let config = try? Data(contentsOf: path) else { @@ -420,17 +421,32 @@ struct CoreLightning: View { anyAddr = true let itemArr = item.split(separator: "=") self.publicUrl = "\(itemArr[1])" - runScript(script: .lightningNodeId) + getNodeID() } } if !anyAddr { - runScript(script: .lightningNodeId) + getNodeID() showMessage(message: "In order to connect via QR code remotely with Plasma you need to open the lightning config and add addr=, example: addr=100.89.65.23:9735. If you do not have a public IP you can use Plasma locally by clicking \"Connect Plasma Locally\".") } } } + private func getNodeID() { + ScriptUtil.runScript(script: .lightningNodeId, env: nil, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } else if let output = output { + parseScriptResult(script: .lightningNodeId, result: output) + } + return + } + guard let output = output else { return } + parseScriptResult(script: .lightningNodeId, result: output) + } + } + func parseDataResponse(script: SCRIPT, data: Data) { switch script { case .getRune: @@ -447,7 +463,7 @@ struct CoreLightning: View { case .lightningNodeId: guard let info = dec(GetInfo.self, data).response as? GetInfo else { return } self.nodeId = info.id - runScript(script: .getRune) + //runScript(script: .getRune) default: break @@ -484,31 +500,4 @@ struct CoreLightning: View { return((nil, "\(error)")) } } - - private func openConf(script: SCRIPT, env: [String:String], args: [String], completion: @escaping ((Bool)) -> Void) { - #if DEBUG - print("script: \(script.stringValue)") - #endif - let resource = script.stringValue - guard let path = Bundle.main.path(forResource: resource, ofType: "command") else { return } - let stdOut = Pipe() - let task = Process() - task.launchPath = path - task.environment = env - task.arguments = args - task.standardOutput = stdOut - task.launch() - task.waitUntilExit() - let data = stdOut.fileHandleForReading.readDataToEndOfFile() - var result = "" - if let output = String(data: data, encoding: .utf8) { - #if DEBUG - print("result: \(output)") - #endif - result += output - completion(true) - } else { - completion(false) - } - } } diff --git a/FullyNoded-Server/Views/JoinMarket.swift b/FullyNoded-Server/Views/JoinMarket.swift index 02e639e3..8a7a091b 100644 --- a/FullyNoded-Server/Views/JoinMarket.swift +++ b/FullyNoded-Server/Views/JoinMarket.swift @@ -9,6 +9,9 @@ import SwiftUI struct JoinMarket: View { + @State private var walletName = "" + @State private var gapLimit = "" + @State private var promptToIncreaseGapLimit = false @State private var version = UserDefaults.standard.string(forKey: "tagName") ?? "" @State private var qrImage: NSImage? = nil @State private var startCheckingIfRunning = false @@ -115,6 +118,7 @@ struct JoinMarket: View { Text(selectedChain) .padding([.leading]) + .padding(.leading) .frame(maxWidth: .infinity, alignment: .leading) } .padding() @@ -143,12 +147,40 @@ struct JoinMarket: View { Text("Configure JM") } Button { - //openFile(file: "") NSWorkspace.shared.selectFile(nil, inFileViewerRootedAtPath: "/Users/\(NSUserName())/Library/Application Support/joinmarket") } label: { Text("Data Dir") } + Button { + + } label: { + Text("Increase gap limit") + } + Button { + BitcoinRPC.shared.command(method: "getblockchaininfo", params: [:]) { (result, error) in + guard error == nil, let result = result as? [String: Any] else { + showMessage(message: error ?? "Unknown error getblbockchaininfo.") + return + } + guard let pruneheight = result["pruneheight"] as? Int else { + showMessage(message: "No pruneheight") + return + } + + BitcoinRPC.shared.command(method: "rescanblockchain", params: ["start_height": pruneheight]) { (result, error) in + guard error == nil, let _ = result as? [String: Any] else { + showMessage(message: error ?? "Unknown error rescanblockchain.") + return + } + } + // No response from core when initiating a rescan... + showMessage(message: "Blockchain rescan started.") + } + + } label: { + Text("Rescan") + } } .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) @@ -220,6 +252,24 @@ struct JoinMarket: View { .alert(message, isPresented: $showError) { Button("OK", role: .cancel) {} } + .alert("Increase the gap limit to? (upon completion a rescan will be required).", isPresented: $promptToIncreaseGapLimit) { + TextField("Enter the new gap limit", text: $gapLimit) + TextField("Enter the wallet name", text: $walletName) + Button("OK", action: increaseGapLimit) + } + } + + private func increaseGapLimit() { + let env: [String: String] = ["TAG_NAME": env["TAG_NAME"]!, "GAP_AMOUNT": gapLimit, "WALLET_NAME": walletName] + ScriptUtil.runScript(script: .launchIncreaseGapLimit, env: env, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } + return + } + showMessage(message: "Gap limit increased, check the script output to be sure.") + } } private func configureJm() { @@ -235,6 +285,11 @@ struct JoinMarket: View { updateConf(key: "network", value: chain) updateConf(key: "rpc_port", value: port) updateConf(key: "rpc_wallet_file", value: "jm_wallet") + updateConf(key: "tor_control_host", value: "/Users/\(NSUserName())/Library/Caches/tor/cp") + updateConf(key: "#max_cj_fee_abs", value: "\(Int.random(in: 5000...10000))") + updateConf(key: "#max_cj_fee_rel", value: Double.random(in: 0.00002...0.000025).avoidNotation) + updateConf(key: "max_cj_fee_abs", value: "\(Int.random(in: 5000...10000))") + updateConf(key: "max_cj_fee_rel", value: Double.random(in: 0.00002...0.000025).avoidNotation) DataManager.retrieve(entityName: "BitcoinRPCCreds") { rpcCreds in guard let rpcCreds = rpcCreds, @@ -252,7 +307,10 @@ struct JoinMarket: View { guard error == nil else { if !error!.contains("Database already exists.") { showMessage(message: error!) + } else { + showMessage(message: "Join Market configured ✓") } + isAnimating = false return } @@ -280,8 +338,9 @@ struct JoinMarket: View { } let arr = string.split(separator: "\n") for item in arr { + let uncommentedKey = key.replacingOccurrences(of: "#", with: "") if item.hasPrefix("\(key) =") { - let newConf = string.replacingOccurrences(of: item, with: key + " = " + value) + let newConf = string.replacingOccurrences(of: item, with: uncommentedKey + " = " + value) if (try? newConf.write(to: URL(fileURLWithPath: jmConfPath), atomically: false, encoding: .utf8)) == nil { print("failed writing to jm config") } else { @@ -315,21 +374,52 @@ struct JoinMarket: View { } private func openFile(file: String) { - let env = ["FILE": "/Users/\(NSUserName())/Library/Application Support/joinmarket/\(file)"] - - openConf(script: .openFile, env: env, args: []) { _ in } + let fileEnv = ["FILE": "/Users/\(NSUserName())/Library/Application Support/joinmarket/\(file)"] + ScriptUtil.runScript(script: .openFile, env: fileEnv, args: nil) { (_, _, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } + return + } + } } private func startJoinMarket() { + let fm = FileManager.default + let path = "/Users/\(NSUserName())/Library/Application Support/joinmarket/wallets" + + if let wallets = try? fm.contentsOfDirectory(atPath: path) { + for wallet in wallets { + print("Found \(wallet)") + if wallet.hasSuffix(".lock") { + // Delete the .lock file + try? fm.removeItem(atPath: path + "/" + wallet) + } + } + } isAnimating = true env["TAG_NAME"] = UserDefaults.standard.string(forKey: "tagName") ?? "" - runScript(script: .launchJmStarter) + ScriptUtil.runScript(script: .launchJmStarter, env: self.env, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } + return + } + } } private func stopJoinMarket() { - runScript(script: .stopJm) + ScriptUtil.runScript(script: .stopJm, env: nil, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } + return + } + } } - private func isJoinMarketRunning() { if !isAutoRefreshing { @@ -359,70 +449,6 @@ struct JoinMarket: View { showError = true self.message = message } - - private func runScript(script: SCRIPT) { - #if DEBUG - print("run script: \(script.stringValue)") - #endif - - let taskQueue = DispatchQueue.global(qos: DispatchQoS.QoSClass.background) - taskQueue.async { - let resource = script.stringValue - guard let path = Bundle.main.path(forResource: resource, ofType: "command") else { return } - let stdOut = Pipe() - let stdErr = Pipe() - let task = Process() - task.launchPath = path - task.environment = env - task.standardOutput = stdOut - task.standardError = stdErr - task.launch() - task.waitUntilExit() - let data = stdOut.fileHandleForReading.readDataToEndOfFile() - let errData = stdErr.fileHandleForReading.readDataToEndOfFile() - var result = "" - - if let output = String(data: data, encoding: .utf8) { - #if DEBUG - print("output: \(output)") - #endif - result += output - } - - if let errorOutput = String(data: errData, encoding: .utf8) { - #if DEBUG - print("error: \(errorOutput)") - #endif - result += errorOutput - if errorOutput != "" { - showMessage(message: errorOutput) - } - } - } - } - - private func openConf(script: SCRIPT, env: [String:String], args: [String], completion: @escaping ((Bool)) -> Void) { - let resource = script.stringValue - guard let path = Bundle.main.path(forResource: resource, ofType: "command") else { - return - } - let stdOut = Pipe() - let task = Process() - task.launchPath = path - task.environment = env - task.arguments = args - task.standardOutput = stdOut - task.launch() - task.waitUntilExit() - let data = stdOut.fileHandleForReading.readDataToEndOfFile() - var result = "" - if let output = String(data: data, encoding: .utf8) { - result += output - completion(true) - } else { - completion(false) - } - } } #Preview { From de4df714e1219a6cd306c1e34e66846fb9796600 Mon Sep 17 00:00:00 2001 From: Fontaine Date: Wed, 13 Nov 2024 12:20:36 -0500 Subject: [PATCH 10/22] feat: better? join market defaults (should prob make user input them), UI improvements, refactoring. --- FullyNoded-Server.xcodeproj/project.pbxproj | 4 + FullyNoded-Server/Views/BitcoinCore.swift | 2 +- FullyNoded-Server/Views/ContentView.swift | 156 +++++++------------- FullyNoded-Server/Views/CoreLightning.swift | 2 +- FullyNoded-Server/Views/FNIcon.swift | 25 ++++ FullyNoded-Server/Views/JoinMarket.swift | 11 +- 6 files changed, 89 insertions(+), 111 deletions(-) create mode 100644 FullyNoded-Server/Views/FNIcon.swift diff --git a/FullyNoded-Server.xcodeproj/project.pbxproj b/FullyNoded-Server.xcodeproj/project.pbxproj index 5441ce45..0a70f6bc 100644 --- a/FullyNoded-Server.xcodeproj/project.pbxproj +++ b/FullyNoded-Server.xcodeproj/project.pbxproj @@ -77,6 +77,7 @@ 0AD7BE252CC2BCEF00428D02 /* StopJm.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AD7BE242CC2BCEF00428D02 /* StopJm.command */; }; 593A891F2CE28334001504F0 /* IncreaseGapLimit.command in Resources */ = {isa = PBXBuildFile; fileRef = 593A891E2CE28334001504F0 /* IncreaseGapLimit.command */; }; 593A89212CE28400001504F0 /* LaunchIncreaseGapLimit.command in Resources */ = {isa = PBXBuildFile; fileRef = 593A89202CE28400001504F0 /* LaunchIncreaseGapLimit.command */; }; + 593A89232CE511F8001504F0 /* FNIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 593A89222CE511F8001504F0 /* FNIcon.swift */; }; BF3EE5E9CBA2EF2BFB961A21 /* Pods_FullyNoded_Server.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D69717EDC523941317071BC8 /* Pods_FullyNoded_Server.framework */; }; /* End PBXBuildFile section */ @@ -155,6 +156,7 @@ 1B8BA5D0924A1AE2EC951616 /* Pods-FullyNoded-Server.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FullyNoded-Server.debug.xcconfig"; path = "Target Support Files/Pods-FullyNoded-Server/Pods-FullyNoded-Server.debug.xcconfig"; sourceTree = ""; }; 593A891E2CE28334001504F0 /* IncreaseGapLimit.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = IncreaseGapLimit.command; sourceTree = ""; }; 593A89202CE28400001504F0 /* LaunchIncreaseGapLimit.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = LaunchIncreaseGapLimit.command; sourceTree = ""; }; + 593A89222CE511F8001504F0 /* FNIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FNIcon.swift; sourceTree = ""; }; D69717EDC523941317071BC8 /* Pods_FullyNoded_Server.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FullyNoded_Server.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DEFA9324C99AAF1DC60AC76C /* Pods-FullyNoded-Server.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FullyNoded-Server.release.xcconfig"; path = "Target Support Files/Pods-FullyNoded-Server/Pods-FullyNoded-Server.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -181,6 +183,7 @@ 0A9822E22CA42BEC008DB52E /* TaggedReleasesView.swift */, 0AD7BE0E2CB980D500428D02 /* JoinMarketTaggedReleases.swift */, 0AD7BE162CBD8DA000428D02 /* JoinMarket.swift */, + 593A89222CE511F8001504F0 /* FNIcon.swift */, ); path = Views; sourceTree = ""; @@ -498,6 +501,7 @@ 0AD7BE1D2CBD923300428D02 /* JMWallet.swift in Sources */, 0AD7BE132CBD6F1000428D02 /* Assets.swift in Sources */, 0A573E252CB435F200899F84 /* GetInfo.swift in Sources */, + 593A89232CE511F8001504F0 /* FNIcon.swift in Sources */, 0A5CE8EE2C91F9F500534A8D /* Crypto.swift in Sources */, 0A5CE8E62C91EC6800534A8D /* BitcoinEnv.swift in Sources */, 0A5CE8CE2C89EC1F00534A8D /* RPCAuth.swift in Sources */, diff --git a/FullyNoded-Server/Views/BitcoinCore.swift b/FullyNoded-Server/Views/BitcoinCore.swift index 49861313..f7998283 100644 --- a/FullyNoded-Server/Views/BitcoinCore.swift +++ b/FullyNoded-Server/Views/BitcoinCore.swift @@ -28,7 +28,7 @@ struct BitcoinCore: View { var body: some View { - Spacer() + FNIcon() VStack() { HStack() { diff --git a/FullyNoded-Server/Views/ContentView.swift b/FullyNoded-Server/Views/ContentView.swift index 3906ad85..bb41b1a5 100644 --- a/FullyNoded-Server/Views/ContentView.swift +++ b/FullyNoded-Server/Views/ContentView.swift @@ -20,6 +20,7 @@ public struct Service: Identifiable { struct ContentView: View { + @State private var isInstallingLightning = false @State private var torProgress = 0.0 @State private var showError = false @State private var message = "" @@ -75,22 +76,29 @@ struct ContentView: View { ) } } else if service.name == "Core Lightning" { - if lightningInstalled { + if isInstallingLightning { + HStack() { + ProgressView() + .scaleEffect(0.5) + Text("Installing and configuring Core Lightning. (wait for the terminal script to complete)") + } + .frame(maxWidth: .infinity, alignment: .topLeading) + .padding([.leading, .top]) + + } else if lightningInstalled { CoreLightning() } else { + FNIcon() + Spacer() if bitcoinCoreInstalled { Button("Install Core Lightning") { installLightning() } + //.padding([]) + Spacer() } else { Text("First install Bitcoin Core.") } - Home( - showBitcoinCoreInstallButton: false, - env: [:], - showJoinMarketInstallButton: false, - jmTaggedReleases: [] - ) } } else if service.name == "Join Market" { @@ -108,6 +116,7 @@ struct ContentView: View { ) } } else if service.name == "Tor" { + FNIcon() HStack() { if torProgress < 100.0 { ProgressView("Tor bootstrapping \(Int(torProgress))% complete…", value: torProgress, total: 100) @@ -127,12 +136,8 @@ struct ContentView: View { } } } - Home( - showBitcoinCoreInstallButton: false, - env: [:], - showJoinMarketInstallButton: false, - jmTaggedReleases: [] - ) + .frame(maxWidth: .infinity, alignment: .leading) + Spacer() } } label: { HStack() { @@ -247,28 +252,22 @@ struct ContentView: View { } .alert("Install Brew? Core Lightning and Join Market installation relies on Brew.", isPresented: $promptToInstallBrew) { Button("OK", role: .cancel) { - runScript(script: .installHomebrew, env: [:]) + ScriptUtil.runScript(script: .installHomebrew, env: nil, args: nil) { (_, _, _) in } } } .alert("Install Xcode Command Line Tools? This is required for Fully Noded - Server to function.", isPresented: $promptToInstallXcode, actions: { Button("OK", role: .cancel) { - runScript(script: .installXcode, env: [:]) + ScriptUtil.runScript(script: .installXcode, env: nil, args: nil) { (_, _, _) in } } }) .alert("Bitcoin Install complete.", isPresented: $bitcoinInstallSuccess) { Button("OK", role: .cancel) { - runScript(script: .checkForBitcoin, env: env) + checkForBitcoin() } } .alert("A terminal should have launched to install Bitcoin Core, close the terminal window when it says its finished.", isPresented: $startCheckingForBitcoinInstall) { Button("OK", role: .cancel) {} } - - .alert("Install XCode command line tools? FullyNoded-Server relies on Xcode command line tools to function.", isPresented: $promptToInstallXcode) { - Button("OK", role: .cancel) { - runScript(script: .installXcode, env: env) - } - } } private func checkForXcode() { @@ -306,23 +305,28 @@ struct ContentView: View { } private func installLightning() { + isInstallingLightning = true DataManager.retrieve(entityName: "BitcoinRPCCreds") { bitcoinRPCCreds in guard let bitcoinRPCCreds = bitcoinRPCCreds else { + isInstallingLightning = false showMessage(message: "NO Bitcoin RPC Creds, create them?") return } guard let encryptedRpcPass = bitcoinRPCCreds["password"] as? Data else { + isInstallingLightning = false showMessage(message: "Unable to get encrypted rpc password.") return } guard let decryptedRpcPass = Crypto.decrypt(encryptedRpcPass) else { + isInstallingLightning = false showMessage(message: "Decrypting rpc password failed.") return } guard let rpcPass = String(data: decryptedRpcPass, encoding: .utf8) else { + isInstallingLightning = false showMessage(message: "Encoding rpc password data as utf8 failed.") return } @@ -338,7 +342,15 @@ struct ContentView: View { } lightningEnv["NETWORK"] = network - runScript(script: .launchLightningInstall, env: lightningEnv) + ScriptUtil.runScript(script: .launchLightningInstall, env: lightningEnv, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } + return + } + return + } } } @@ -368,7 +380,7 @@ struct ContentView: View { ] services = [bitcoinCore, coreLightning, joinMarket, tor] - runScript(script: .checkForBitcoin, env: env) + checkForBitcoin() } return @@ -386,14 +398,28 @@ struct ContentView: View { ] services = [bitcoinCore, coreLightning, joinMarket, tor] - runScript(script: .checkForBitcoin, env: env) + checkForBitcoin() + } + } + + private func checkForBitcoin() { + ScriptUtil.runScript(script: .checkForBitcoin, env: env, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) + } else if let output = output { + parseBitcoindVersionResponse(result: output) + } + return + } + guard let output = output else { return } + parseBitcoindVersionResponse(result: output) } } func parseBitcoindVersionResponse(result: String) { if result.contains("Bitcoin Core Daemon version") || result.contains("Bitcoin Core version") { bitcoinCoreInstalled = true - runScript(script: .checkForBrew, env: env) let tempPath = "/Users/\(NSUserName())/.fullynoded/installBitcoin.sh" if FileManager.default.fileExists(atPath: tempPath) { try? FileManager.default.removeItem(atPath: tempPath) @@ -426,89 +452,11 @@ struct ContentView: View { } } - private func runScript(script: SCRIPT, env: [String: String]) { - #if DEBUG - print("run script: \(script.stringValue)") - #endif - - let taskQueue = DispatchQueue.global(qos: DispatchQoS.QoSClass.background) - taskQueue.async { - let resource = script.stringValue - guard let path = Bundle.main.path(forResource: resource, ofType: "command") else { return } - let stdOut = Pipe() - let stdErr = Pipe() - let task = Process() - task.launchPath = path - task.environment = env - task.standardOutput = stdOut - task.standardError = stdErr - task.launch() - task.waitUntilExit() - let data = stdOut.fileHandleForReading.readDataToEndOfFile() - let errData = stdErr.fileHandleForReading.readDataToEndOfFile() - var result = "" - - if let output = String(data: data, encoding: .utf8) { - #if DEBUG - print("output: \(output)") - #endif - result += output - } - - if let errorOutput = String(data: errData, encoding: .utf8) { - #if DEBUG - print("error: \(errorOutput)") - #endif - result += errorOutput - - if errorOutput != "" { - showMessage(message: errorOutput) - } - } - - parseScriptResult(script: script, result: result) - } - } - - private func showMessage(message: String) { showError = true self.message = message } - func parseScriptResult(script: SCRIPT, result: String) { - #if DEBUG - print("parse \(script.stringValue)") - print("result: \(result)") - #endif - switch script { - case .checkForBitcoin: - parseBitcoindVersionResponse(result: result) - -// case .checkXcodeSelect: -// parseXcodeSelectResult(result: result) - -// case .checkForBrew: -// if result != "" { -// runScript(script: .lightningInstalled, env: env) -// } else { -// promptToInstallBrew = true -// } - - case .lightningInstalled: - if result.hasPrefix("Installed") { - runScript(script: .lightingRunning, env: env) - lightningInstalled = true - } else { - lightningInstalled = false - promptToInstallLightning = true - } - - default: - break - } - } - private func parseXcodeSelectResult(result: String) { if result.contains("XCode select not installed") { promptToInstallXcode = true diff --git a/FullyNoded-Server/Views/CoreLightning.swift b/FullyNoded-Server/Views/CoreLightning.swift index 0a1ba03f..7db78920 100644 --- a/FullyNoded-Server/Views/CoreLightning.swift +++ b/FullyNoded-Server/Views/CoreLightning.swift @@ -24,7 +24,7 @@ struct CoreLightning: View { @State private var quickConnectClnRest: String? = nil var body: some View { - Spacer() + FNIcon() VStack() { HStack() { Image(systemName: "server.rack") diff --git a/FullyNoded-Server/Views/FNIcon.swift b/FullyNoded-Server/Views/FNIcon.swift new file mode 100644 index 00000000..42ab1044 --- /dev/null +++ b/FullyNoded-Server/Views/FNIcon.swift @@ -0,0 +1,25 @@ +// +// FNIcon.swift +// FullyNoded-Server +// +// Created by Peter Denton on 11/13/24. +// + +import SwiftUI + +struct FNIcon: View { + var body: some View { + Image("1024") + .resizable() + .cornerRadius(20.0) + .frame(width: 80.0, height: 80.0) + .padding([.all]) + .scaledToFit() + .frame(maxWidth: .infinity, alignment: .topLeading) + //Spacer() + } +} + +#Preview { + FNIcon() +} diff --git a/FullyNoded-Server/Views/JoinMarket.swift b/FullyNoded-Server/Views/JoinMarket.swift index 8a7a091b..bd209fba 100644 --- a/FullyNoded-Server/Views/JoinMarket.swift +++ b/FullyNoded-Server/Views/JoinMarket.swift @@ -29,7 +29,7 @@ struct JoinMarket: View { var body: some View { - Spacer() + FNIcon() VStack() { HStack() { Image(systemName: "server.rack") @@ -282,14 +282,15 @@ struct JoinMarket: View { default: break } + updateConf(key: "tx_fees", value: "7000")//https://github.com/openoms/bitcoin-tutorials/blob/master/joinmarket/README.md updateConf(key: "network", value: chain) updateConf(key: "rpc_port", value: port) updateConf(key: "rpc_wallet_file", value: "jm_wallet") updateConf(key: "tor_control_host", value: "/Users/\(NSUserName())/Library/Caches/tor/cp") - updateConf(key: "#max_cj_fee_abs", value: "\(Int.random(in: 5000...10000))") - updateConf(key: "#max_cj_fee_rel", value: Double.random(in: 0.00002...0.000025).avoidNotation) - updateConf(key: "max_cj_fee_abs", value: "\(Int.random(in: 5000...10000))") - updateConf(key: "max_cj_fee_rel", value: Double.random(in: 0.00002...0.000025).avoidNotation) + updateConf(key: "#max_cj_fee_abs", value: "\(Int.random(in: 2200...5000))") + updateConf(key: "#max_cj_fee_rel", value: Double.random(in: 0.00199...0.00243).avoidNotation) + updateConf(key: "max_cj_fee_abs", value: "\(Int.random(in: 2200...5000))") + updateConf(key: "max_cj_fee_rel", value: Double.random(in: 0.00243...0.00421).avoidNotation) DataManager.retrieve(entityName: "BitcoinRPCCreds") { rpcCreds in guard let rpcCreds = rpcCreds, From 6952acfd97631e8a30b84dd2b1a0388bb1ff4eb8 Mon Sep 17 00:00:00 2001 From: Fontaine Date: Wed, 13 Nov 2024 13:09:08 -0500 Subject: [PATCH 11/22] feat: obwatcher button for joinmarket --- FullyNoded-Server.xcodeproj/project.pbxproj | 8 ++++++++ FullyNoded-Server/Helpers/Script.swift | 6 ++++++ .../Scripts/LaunchObWatcher.command | 14 ++++++++++++++ FullyNoded-Server/Scripts/ObWatcher.command | 17 +++++++++++++++++ FullyNoded-Server/Views/ContentView.swift | 2 +- FullyNoded-Server/Views/JoinMarket.swift | 11 +++++++++++ 6 files changed, 57 insertions(+), 1 deletion(-) create mode 100755 FullyNoded-Server/Scripts/LaunchObWatcher.command create mode 100755 FullyNoded-Server/Scripts/ObWatcher.command diff --git a/FullyNoded-Server.xcodeproj/project.pbxproj b/FullyNoded-Server.xcodeproj/project.pbxproj index 0a70f6bc..c066529e 100644 --- a/FullyNoded-Server.xcodeproj/project.pbxproj +++ b/FullyNoded-Server.xcodeproj/project.pbxproj @@ -78,6 +78,8 @@ 593A891F2CE28334001504F0 /* IncreaseGapLimit.command in Resources */ = {isa = PBXBuildFile; fileRef = 593A891E2CE28334001504F0 /* IncreaseGapLimit.command */; }; 593A89212CE28400001504F0 /* LaunchIncreaseGapLimit.command in Resources */ = {isa = PBXBuildFile; fileRef = 593A89202CE28400001504F0 /* LaunchIncreaseGapLimit.command */; }; 593A89232CE511F8001504F0 /* FNIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 593A89222CE511F8001504F0 /* FNIcon.swift */; }; + 593A89252CE519B3001504F0 /* LaunchObWatcher.command in Resources */ = {isa = PBXBuildFile; fileRef = 593A89242CE519B3001504F0 /* LaunchObWatcher.command */; }; + 593A89272CE51A35001504F0 /* ObWatcher.command in Resources */ = {isa = PBXBuildFile; fileRef = 593A89262CE51A35001504F0 /* ObWatcher.command */; }; BF3EE5E9CBA2EF2BFB961A21 /* Pods_FullyNoded_Server.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D69717EDC523941317071BC8 /* Pods_FullyNoded_Server.framework */; }; /* End PBXBuildFile section */ @@ -157,6 +159,8 @@ 593A891E2CE28334001504F0 /* IncreaseGapLimit.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = IncreaseGapLimit.command; sourceTree = ""; }; 593A89202CE28400001504F0 /* LaunchIncreaseGapLimit.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = LaunchIncreaseGapLimit.command; sourceTree = ""; }; 593A89222CE511F8001504F0 /* FNIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FNIcon.swift; sourceTree = ""; }; + 593A89242CE519B3001504F0 /* LaunchObWatcher.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = LaunchObWatcher.command; sourceTree = ""; }; + 593A89262CE51A35001504F0 /* ObWatcher.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ObWatcher.command; sourceTree = ""; }; D69717EDC523941317071BC8 /* Pods_FullyNoded_Server.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FullyNoded_Server.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DEFA9324C99AAF1DC60AC76C /* Pods-FullyNoded-Server.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FullyNoded-Server.release.xcconfig"; path = "Target Support Files/Pods-FullyNoded-Server/Pods-FullyNoded-Server.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -315,6 +319,8 @@ 0A0632AF2CD06B470059FAD4 /* Reindex.command */, 593A891E2CE28334001504F0 /* IncreaseGapLimit.command */, 593A89202CE28400001504F0 /* LaunchIncreaseGapLimit.command */, + 593A89242CE519B3001504F0 /* LaunchObWatcher.command */, + 593A89262CE51A35001504F0 /* ObWatcher.command */, ); path = Scripts; sourceTree = ""; @@ -404,6 +410,7 @@ 0AA692422C7F831F00366192 /* Preview Assets.xcassets in Resources */, 0AA692632C7F8EC700366192 /* IsProcessRunning.command in Resources */, 0AA692672C7F8EC700366192 /* LaunchVerifier.command in Resources */, + 593A89272CE51A35001504F0 /* ObWatcher.command in Resources */, 0AA692612C7F8EC700366192 /* InstallBrew.command in Resources */, 0AA6926C2C7F8EC700366192 /* StopBitcoin.command in Resources */, 0AD7BE152CBD7AC100428D02 /* LaunchJMInstaller.command in Resources */, @@ -424,6 +431,7 @@ 0AD7BE112CBD6AA500428D02 /* InstallJoinMarket.command in Resources */, 0AA6925F2C7F8EC700366192 /* CheckXCodeSelect.command in Resources */, 0A5CE8DC2C8A1DAA00534A8D /* InstallLightning.command in Resources */, + 593A89252CE519B3001504F0 /* LaunchObWatcher.command in Resources */, 0AD7BE232CC2B47400428D02 /* LaunchJMStarter.command in Resources */, 0A573E232CB432D200899F84 /* LightningNodeId.command in Resources */, 0AA6926E2C7F8EC700366192 /* Verify.command in Resources */, diff --git a/FullyNoded-Server/Helpers/Script.swift b/FullyNoded-Server/Helpers/Script.swift index 882ca221..7717993c 100644 --- a/FullyNoded-Server/Helpers/Script.swift +++ b/FullyNoded-Server/Helpers/Script.swift @@ -8,6 +8,8 @@ import Foundation public enum SCRIPT: String { + case obWatcher + case launchObWatcher case launchIncreaseGapLimit case increaseGapLimit case reindex @@ -46,6 +48,10 @@ public enum SCRIPT: String { var stringValue:String { switch self { + case .obWatcher: + return "ObWatcher" + case .launchObWatcher: + return "LaunchObWatcher" case .launchIncreaseGapLimit: return "LaunchIncreaseGapLimit" case .increaseGapLimit: diff --git a/FullyNoded-Server/Scripts/LaunchObWatcher.command b/FullyNoded-Server/Scripts/LaunchObWatcher.command new file mode 100755 index 00000000..25824c8b --- /dev/null +++ b/FullyNoded-Server/Scripts/LaunchObWatcher.command @@ -0,0 +1,14 @@ +#!/bin/sh + +# LaunchObWatcher.command +# FullyNoded-Server +# +# Created by Peter Denton on 11/13/24. +# +SCRIPT_PATH="/Users/$(whoami)/.fullynoded/obWatcher.sh" +LOG="/Users/$(whoami)/.fullynoded/fullynoded.log" +touch $SCRIPT_PATH +echo "\"$(cd "$(dirname "$0")"; pwd)/ObWatcher.command\" $TAG_NAME | tee -a $LOG" > $SCRIPT_PATH +chmod +x $SCRIPT_PATH +open -a Terminal $SCRIPT_PATH +exit 1 diff --git a/FullyNoded-Server/Scripts/ObWatcher.command b/FullyNoded-Server/Scripts/ObWatcher.command new file mode 100755 index 00000000..850fa6a0 --- /dev/null +++ b/FullyNoded-Server/Scripts/ObWatcher.command @@ -0,0 +1,17 @@ +#!/bin/sh + +# ObWatcher.command +# FullyNoded-Server +# +# Created by Peter Denton on 11/13/24. +# +TAG_NAME=$1 +cd /Users/$(whoami)/.fullynoded/JoinMarket/joinmarket-$TAG_NAME +echo "source jmvenv/bin/activate" +source jmvenv/bin/activate +echo "cd scripts/obwatch" +cd scripts/obwatch +echo "pip3 install matplotlib" +pip3 install matplotlib +echo "python3 ob-watcher.py" +python3 ob-watcher.py diff --git a/FullyNoded-Server/Views/ContentView.swift b/FullyNoded-Server/Views/ContentView.swift index bb41b1a5..10e4ec4a 100644 --- a/FullyNoded-Server/Views/ContentView.swift +++ b/FullyNoded-Server/Views/ContentView.swift @@ -94,7 +94,6 @@ struct ContentView: View { Button("Install Core Lightning") { installLightning() } - //.padding([]) Spacer() } else { Text("First install Bitcoin Core.") @@ -176,6 +175,7 @@ struct ContentView: View { .onReceive(timerForLightningInstall) { _ in if FileManager.default.fileExists(atPath: "/opt/homebrew/Cellar/core-lightning/24.08.1/bin/lightningd") { lightningInstalled = true + isInstallingLightning = false self.timerForLightningInstall.upstream.connect().cancel() } } diff --git a/FullyNoded-Server/Views/JoinMarket.swift b/FullyNoded-Server/Views/JoinMarket.swift index bd209fba..6b532db6 100644 --- a/FullyNoded-Server/Views/JoinMarket.swift +++ b/FullyNoded-Server/Views/JoinMarket.swift @@ -181,6 +181,16 @@ struct JoinMarket: View { } label: { Text("Rescan") } + Button { + ScriptUtil.runScript(script: .launchObWatcher, env: self.env, args: nil) { (output, _, errorMessage) in + guard let errorMess = errorMessage, errorMess != "" else { + showMessage(message: "A terminal has launched, read its output, you should be able to go to a browser and visit http://localhost:62601 to see the order book.") + return } + showMessage(message: errorMess) + } + } label: { + Text("Order Book") + } } .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) @@ -246,6 +256,7 @@ struct JoinMarket: View { .padding(.all) } .onAppear(perform: { + env["TAG_NAME"] = UserDefaults.standard.string(forKey: "tagName") ?? "" selectedChain = UserDefaults.standard.string(forKey: "chain") ?? "main" isJoinMarketRunning() }) From 21fc1f6894a8d23cf96dc094c592f5645c190405 Mon Sep 17 00:00:00 2001 From: Fontaine Date: Thu, 14 Nov 2024 14:25:05 -0500 Subject: [PATCH 12/22] refactor: no longer include rpc creds in quickconnect url, force user to add rpc auth to the server instead. gemneral refactoring and improvements. --- FullyNoded-Server.xcodeproj/project.pbxproj | 4 + FullyNoded-Server/Core Data/DataManager.swift | 40 +-- FullyNoded-Server/Helpers/BitcoinConf.swift | 6 +- FullyNoded-Server/Helpers/BitcoinRPC.swift | 2 +- .../Helpers/InstallBtcCore.swift | 6 +- FullyNoded-Server/Models/Entity.swift | 13 + FullyNoded-Server/Views/BitcoinCore.swift | 150 ++++++--- FullyNoded-Server/Views/ContentView.swift | 295 +++++++++--------- FullyNoded-Server/Views/CoreLightning.swift | 100 +++--- FullyNoded-Server/Views/JoinMarket.swift | 95 +++--- .../Views/JoinMarketTaggedReleases.swift | 2 +- .../Views/TaggedReleasesView.swift | 6 +- 12 files changed, 398 insertions(+), 321 deletions(-) create mode 100644 FullyNoded-Server/Models/Entity.swift diff --git a/FullyNoded-Server.xcodeproj/project.pbxproj b/FullyNoded-Server.xcodeproj/project.pbxproj index c066529e..16ce4e4b 100644 --- a/FullyNoded-Server.xcodeproj/project.pbxproj +++ b/FullyNoded-Server.xcodeproj/project.pbxproj @@ -80,6 +80,7 @@ 593A89232CE511F8001504F0 /* FNIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 593A89222CE511F8001504F0 /* FNIcon.swift */; }; 593A89252CE519B3001504F0 /* LaunchObWatcher.command in Resources */ = {isa = PBXBuildFile; fileRef = 593A89242CE519B3001504F0 /* LaunchObWatcher.command */; }; 593A89272CE51A35001504F0 /* ObWatcher.command in Resources */ = {isa = PBXBuildFile; fileRef = 593A89262CE51A35001504F0 /* ObWatcher.command */; }; + 593A89292CE6797C001504F0 /* Entity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 593A89282CE6797C001504F0 /* Entity.swift */; }; BF3EE5E9CBA2EF2BFB961A21 /* Pods_FullyNoded_Server.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D69717EDC523941317071BC8 /* Pods_FullyNoded_Server.framework */; }; /* End PBXBuildFile section */ @@ -161,6 +162,7 @@ 593A89222CE511F8001504F0 /* FNIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FNIcon.swift; sourceTree = ""; }; 593A89242CE519B3001504F0 /* LaunchObWatcher.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = LaunchObWatcher.command; sourceTree = ""; }; 593A89262CE51A35001504F0 /* ObWatcher.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ObWatcher.command; sourceTree = ""; }; + 593A89282CE6797C001504F0 /* Entity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Entity.swift; sourceTree = ""; }; D69717EDC523941317071BC8 /* Pods_FullyNoded_Server.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FullyNoded_Server.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DEFA9324C99AAF1DC60AC76C /* Pods-FullyNoded-Server.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FullyNoded-Server.release.xcconfig"; path = "Target Support Files/Pods-FullyNoded-Server/Pods-FullyNoded-Server.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -211,6 +213,7 @@ 0AD7BE122CBD6F1000428D02 /* Assets.swift */, 0AD7BE1C2CBD923300428D02 /* JMWallet.swift */, 0AA43FCF2CCE1B3D0049D4AD /* BlockchainInfo.swift */, + 593A89282CE6797C001504F0 /* Entity.swift */, ); path = Models; sourceTree = ""; @@ -513,6 +516,7 @@ 0A5CE8EE2C91F9F500534A8D /* Crypto.swift in Sources */, 0A5CE8E62C91EC6800534A8D /* BitcoinEnv.swift in Sources */, 0A5CE8CE2C89EC1F00534A8D /* RPCAuth.swift in Sources */, + 593A89292CE6797C001504F0 /* Entity.swift in Sources */, 0A573E1A2CA4715500899F84 /* TorClient.swift in Sources */, 0AA692352C7F831D00366192 /* FullyNoded_ServerApp.swift in Sources */, 0AA692722C80B01A00366192 /* BitcoinRPC.swift in Sources */, diff --git a/FullyNoded-Server/Core Data/DataManager.swift b/FullyNoded-Server/Core Data/DataManager.swift index 9cf43de8..6c02329b 100644 --- a/FullyNoded-Server/Core Data/DataManager.swift +++ b/FullyNoded-Server/Core Data/DataManager.swift @@ -25,10 +25,9 @@ class DataManager: NSObject { container.loadPersistentStores { _, _ in } } - class func retrieve(entityName: String, completion: @escaping (([String:Any]?)) -> Void) { - print("retrieve: \(entityName)") + class func retrieve(entityName: Entity, completion: @escaping (([String:Any]?)) -> Void) { let context = DataManager.shared.container.viewContext - let fetchRequest = NSFetchRequest(entityName: entityName) + let fetchRequest = NSFetchRequest(entityName: entityName.rawValue) fetchRequest.returnsObjectsAsFaults = false fetchRequest.resultType = .dictionaryResultType @@ -45,9 +44,9 @@ class DataManager: NSObject { } - class func deleteAllData(entityName: String, completion: @escaping ((Bool)) -> Void) { + class func deleteAllData(entityName: Entity, completion: @escaping ((Bool)) -> Void) { let context = DataManager.shared.container.viewContext - let fetchRequest = NSFetchRequest(entityName: entityName) + let fetchRequest = NSFetchRequest(entityName: entityName.rawValue) fetchRequest.returnsObjectsAsFaults = false do { @@ -66,11 +65,10 @@ class DataManager: NSObject { } } - class func saveEntity(entityName: String, dict: [String:Any], completion: @escaping ((Bool)) -> Void) { - print("saveEntity") + class func saveEntity(entityName: Entity, dict: [String:Any], completion: @escaping ((Bool)) -> Void) { let context = DataManager.shared.container.viewContext - guard let entity = NSEntityDescription.entity(forEntityName: entityName, in: context) else { + guard let entity = NSEntityDescription.entity(forEntityName: entityName.rawValue, in: context) else { completion(false) return } @@ -91,21 +89,23 @@ class DataManager: NSObject { completion(success) } - class func update(keyToUpdate: String, newValue: Any, entity: String, completion: @escaping ((Bool)) -> Void) { + class func update(keyToUpdate: String, newValue: Any, entity: Entity, completion: @escaping ((Bool)) -> Void) { let context = DataManager.shared.container.viewContext - let fetchRequest = NSFetchRequest(entityName: entity) + let fetchRequest = NSFetchRequest(entityName: entity.rawValue) fetchRequest.returnsObjectsAsFaults = false - guard let results = try? context.fetch(fetchRequest), results.count > 0 else { completion(false); return } + guard let results = try? context.fetch(fetchRequest), results.count > 0 else { + completion(false) + return + } - //for data in results[0] { - results[0].setValue(newValue, forKey: keyToUpdate) - do { - try context.save() - completion(true) - } catch { - completion(false) - } - //} + results[0].setValue(newValue, forKey: keyToUpdate) + + do { + try context.save() + completion(true) + } catch { + completion(false) + } } } diff --git a/FullyNoded-Server/Helpers/BitcoinConf.swift b/FullyNoded-Server/Helpers/BitcoinConf.swift index 7217b4df..0241c848 100644 --- a/FullyNoded-Server/Helpers/BitcoinConf.swift +++ b/FullyNoded-Server/Helpers/BitcoinConf.swift @@ -32,14 +32,14 @@ class BitcoinConf { } static func saveCreds(rpcuser: String, encryptedPass: Data) { - DataManager.retrieve(entityName: "BitcoinRPCCreds") { existingCreds in + DataManager.retrieve(entityName: .rpcCreds) { existingCreds in if let _ = existingCreds { - DataManager.update(keyToUpdate: "password", newValue: encryptedPass, entity: "BitcoinRPCCreds") { updated in + DataManager.update(keyToUpdate: "password", newValue: encryptedPass, entity: .rpcCreds) { updated in guard updated else { return } UserDefaults.standard.setValue(rpcuser, forKey: "rpcuser") } } else { - DataManager.saveEntity(entityName: "BitcoinRPCCreds", dict: ["password": encryptedPass]) { saved in + DataManager.saveEntity(entityName: .rpcCreds, dict: ["password": encryptedPass]) { saved in guard saved else { return } UserDefaults.standard.setValue(rpcuser, forKey: "rpcuser") } diff --git a/FullyNoded-Server/Helpers/BitcoinRPC.swift b/FullyNoded-Server/Helpers/BitcoinRPC.swift index d22a87f2..3e68d6c0 100644 --- a/FullyNoded-Server/Helpers/BitcoinRPC.swift +++ b/FullyNoded-Server/Helpers/BitcoinRPC.swift @@ -19,7 +19,7 @@ class BitcoinRPC { let nodeIp = "127.0.0.1:\(port)" let user = UserDefaults.standard.string(forKey: "rpcuser") ?? "FullyNoded-Server" - DataManager.retrieve(entityName: "BitcoinRPCCreds") { [weak self] creds in + DataManager.retrieve(entityName: .rpcCreds) { [weak self] creds in guard let self = self else { return } guard let creds = creds else { diff --git a/FullyNoded-Server/Helpers/InstallBtcCore.swift b/FullyNoded-Server/Helpers/InstallBtcCore.swift index b6b5fdda..c17de7ad 100644 --- a/FullyNoded-Server/Helpers/InstallBtcCore.swift +++ b/FullyNoded-Server/Helpers/InstallBtcCore.swift @@ -146,14 +146,14 @@ class CreateFNDirConfigureCore { } class func updateRpcCreds(encryptedPass: Data, rpcUser: String, completion: @escaping (Bool) -> Void) { - DataManager.retrieve(entityName: "BitcoinRPCCreds") { existingCreds in + DataManager.retrieve(entityName: .rpcCreds) { existingCreds in if let _ = existingCreds { - DataManager.update(keyToUpdate: "password", newValue: encryptedPass, entity: "BitcoinRPCCreds") { updated in + DataManager.update(keyToUpdate: "password", newValue: encryptedPass, entity: .rpcCreds) { updated in UserDefaults.standard.set("FullyNoded-Server", forKey: "rpcuser") completion(updated) } } else { - DataManager.saveEntity(entityName: "BitcoinRPCCreds", dict: ["password": encryptedPass]) { saved in + DataManager.saveEntity(entityName: .rpcCreds, dict: ["password": encryptedPass]) { saved in UserDefaults.standard.set("FullyNoded-Server", forKey: "rpcuser") completion(saved) } diff --git a/FullyNoded-Server/Models/Entity.swift b/FullyNoded-Server/Models/Entity.swift new file mode 100644 index 00000000..caabf640 --- /dev/null +++ b/FullyNoded-Server/Models/Entity.swift @@ -0,0 +1,13 @@ +// +// Entity.swift +// FullyNoded-Server +// +// Created by Peter Denton on 11/14/24. +// + +import Foundation + +public enum Entity: String { + case rpcCreds = "BitcoinRPCCreds" + case bitcoinEnv = "BitcoinEnv" +} diff --git a/FullyNoded-Server/Views/BitcoinCore.swift b/FullyNoded-Server/Views/BitcoinCore.swift index f7998283..6cadebf6 100644 --- a/FullyNoded-Server/Views/BitcoinCore.swift +++ b/FullyNoded-Server/Views/BitcoinCore.swift @@ -10,6 +10,7 @@ import SwiftUI struct BitcoinCore: View { + @State private var rpcAuth = "" @State private var qrImage: NSImage? = nil @State private var startCheckingIfRunning = false @State private var showError = false @@ -70,23 +71,27 @@ struct BitcoinCore: View { Image(systemName: "circle.fill") .foregroundStyle(.orange) .padding([.leading]) + Text("Stopping...") } else { Image(systemName: "circle.fill") .foregroundStyle(.green) .padding([.leading]) + Text("Running") } - Text("Running") + } else { if isAnimating { Image(systemName: "circle.fill") .foregroundStyle(.orange) .padding([.leading]) + Text("Starting...") } else { Image(systemName: "circle.fill") .foregroundStyle(.red) .padding([.leading]) + Text("Stopped") } - Text("Stopped") + } if !isRunning { Button { @@ -181,16 +186,7 @@ struct BitcoinCore: View { HStack() { Button { - ScriptUtil.runScript(script: .launchVerifier, env: env, args: nil) { (_, _, errorMessage) in - guard errorMessage == nil else { - if errorMessage != "" { - showMessage(message: errorMessage!) - } else { - - } - return - } - } + verify() } label: { Text("Verify") } @@ -213,7 +209,7 @@ struct BitcoinCore: View { Text("Refresh RPC Authentication") } Button { - NSWorkspace.shared.selectFile(nil, inFileViewerRootedAtPath: Defaults.shared.dataDir) + openDataDir() } label: { Text("Data Dir") } @@ -238,8 +234,6 @@ struct BitcoinCore: View { .padding([.leading, .trailing]) ) - - VStack() { Label("Quick Connect", systemImage: "qrcode") .padding([.leading]) @@ -251,6 +245,24 @@ struct BitcoinCore: View { .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) + HStack() { + Text("Authorize an additional RPC user:") + .padding([.leading]) + TextField("rpcauth=FullyNoded:xxxx$xxxx", text: $rpcAuth) + .padding([]) + if rpcAuth != "" { + Button { + if addRpcAuthToConf() { + rpcAuth = "" + showMessage(message: "RPC user authorized. You will need to restart your node for the change to take effect.") + } + } label: { + Text("Add RPC auth") + } + } + Spacer() + } + if let qrImage = qrImage { Image(nsImage: qrImage) .resizable() @@ -258,9 +270,6 @@ struct BitcoinCore: View { .frame(width: 100, height: 100) .frame(maxWidth: .infinity, alignment: .leading) .padding(.leading) - .onAppear { - setSensitiveDataToNil() - } } if let fullyNodedUrl = fullyNodedUrl { @@ -298,20 +307,41 @@ struct BitcoinCore: View { } .alert("This action will delete the entire blockchain and download it again, are you sure you want to proceed? (it can take awhile..)", isPresented: $promptToReindex) { Button("Reindex now", role: .destructive) { - if !isRunning { - isAnimating = true - ScriptUtil.runScript(script: .reindex, env: env, args: nil) { (_, _, errorMessage) in - guard errorMessage == nil else { - if errorMessage != "" { - showMessage(message: errorMessage!) - } - return - } - showMessage(message: "Reindex initiated, this can take awhile..") + reindex() + } + } + } + + private func reindex() { + if !isRunning { + isAnimating = true + ScriptUtil.runScript(script: .reindex, env: env, args: nil) { (_, _, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) } + return + } + showMessage(message: "Reindex initiated, this can take awhile..") + } + } else { + showMessage(message: "Bitcoin Core must stopped before redindexing.") + } + } + + private func openDataDir() { + NSWorkspace.shared.selectFile(nil, inFileViewerRootedAtPath: Defaults.shared.dataDir) + } + + private func verify() { + ScriptUtil.runScript(script: .launchVerifier, env: env, args: nil) { (_, _, errorMessage) in + guard errorMessage == nil else { + if errorMessage != "" { + showMessage(message: errorMessage!) } else { - showMessage(message: "Bitcoin Core must stopped before redindexing.") + } + return } } } @@ -374,11 +404,7 @@ struct BitcoinCore: View { return } - let dataDir = Defaults.shared.dataDir - - let bitcoinConfPath = dataDir + "/bitcoin.conf" - - guard let conf = conf(stringPath: bitcoinConfPath) else { + guard let conf = bitcoinConf() else { return } @@ -398,7 +424,7 @@ struct BitcoinCore: View { \(removeFullyNodedUser) """ - guard ((try? newConf.write(to: URL(fileURLWithPath: bitcoinConfPath), atomically: false, encoding: .utf8)) != nil) else { + guard writeBitcoinConf(newConf: newConf) else { showMessage(message: "Can not write the new conf.") return } @@ -413,7 +439,7 @@ struct BitcoinCore: View { return } - DataManager.update(keyToUpdate: "password", newValue: encryptedPass, entity: "BitcoinRPCCreds") { updated in + DataManager.update(keyToUpdate: "password", newValue: encryptedPass, entity: .rpcCreds) { updated in guard updated else { showMessage(message: "BitcoinRPCCreds update failed") return @@ -433,17 +459,40 @@ struct BitcoinCore: View { } } - private func setSensitiveDataToNil() { - DispatchQueue.main.asyncAfter(deadline: .now() + 15) { - self.qrImage = nil - self.fullyNodedUrl = nil - self.unifyUrl = nil + private func bitcoinConfPath() -> String { + let dataDir = Defaults.shared.dataDir + return dataDir + "/bitcoin.conf" + } + + private func bitcoinConf() -> String? { + return conf(stringPath: bitcoinConfPath()) + } + + private func writeBitcoinConf(newConf: String) -> Bool { + return ((try? newConf.write(to: URL(fileURLWithPath: bitcoinConfPath()), atomically: false, encoding: .utf8)) != nil) + } + + private func addRpcAuthToConf() -> Bool { + guard let conf = bitcoinConf() else { + return false + } + + let newConf = """ + \(rpcAuth) + \(conf) + """ + + guard writeBitcoinConf(newConf: newConf) else { + showMessage(message: "Can not write the new conf.") + return false } + + return true } private func initialLoad() { selectedChain = UserDefaults.standard.string(forKey: "chain") ?? "signet" - DataManager.retrieve(entityName: "BitcoinEnv") { env in + DataManager.retrieve(entityName: .bitcoinEnv) { env in guard let env = env else { return } let envValues = BitcoinEnvValues(dictionary: env) self.env = [ @@ -478,28 +527,28 @@ struct BitcoinCore: View { break } - DataManager.retrieve(entityName: "BitcoinRPCCreds") { rpcCred in + DataManager.retrieve(entityName: .rpcCreds) { rpcCred in guard let rpcCred = rpcCred, let encryptedPass = rpcCred["password"] as? Data else { - print("no passwrod") + showMessage(message: "No rpc password saved.") return } guard let decryptedPass = Crypto.decrypt(encryptedPass) else { - print("cant decrypt") + showMessage(message: "Unable to decrypt rpc password data.") return } guard let rpcPass = String(data: decryptedPass, encoding: .utf8) else { - print("cant convert") + showMessage(message: "Unable to encode decrypted rpc data to utf8 string.") return } - let url = "http://FullyNoded-Server:\(rpcPass)@\(onionHost)" + let url = "http://xxx:xxx@\(onionHost)" qrImage = url.qrQode let port = UserDefaults.standard.object(forKey: "port") as? String ?? "38332" - self.fullyNodedUrl = "btcrpc://FullyNoded-Server:\(rpcPass)@localhost:\(port)" - self.unifyUrl = "unify://FullyNoded-Server:\(rpcPass)@localhost:\(port)" + self.fullyNodedUrl = "btcrpc://xxx:xxx@localhost:\(port)" + self.unifyUrl = "unify://xxx:xxx@localhost:\(port)" } } @@ -526,7 +575,7 @@ struct BitcoinCore: View { UserDefaults.standard.setValue(chain.lowercased(), forKey: "chain") self.env["CHAIN"] = chain self.blockchainInfo = nil - DataManager.update(keyToUpdate: "chain", newValue: chain, entity: "BitcoinEnv") { updated in + DataManager.update(keyToUpdate: "chain", newValue: chain, entity: .bitcoinEnv) { updated in guard updated else { showMessage(message: "There was an issue updating your network...") return @@ -583,7 +632,6 @@ struct BitcoinCore: View { if item.hasPrefix("network=") { let existingNetworkArr = item.split(separator: "=") if existingNetworkArr.count == 2 { - let existingNetwork = existingNetworkArr[1] var network = chain if network == "main" { network = "bitcoin" diff --git a/FullyNoded-Server/Views/ContentView.swift b/FullyNoded-Server/Views/ContentView.swift index 10e4ec4a..f78783fc 100644 --- a/FullyNoded-Server/Views/ContentView.swift +++ b/FullyNoded-Server/Views/ContentView.swift @@ -60,177 +60,186 @@ struct ContentView: View { var body: some View { - NavigationView { - List { - ForEach(services) { service in - NavigationLink { - if service.name == "Bitcoin Core" { - if bitcoinCoreInstalled { - BitcoinCore() - } else { - Home( - showBitcoinCoreInstallButton: true, - env: env, - showJoinMarketInstallButton: false, - jmTaggedReleases: [] - ) - } - } else if service.name == "Core Lightning" { - if isInstallingLightning { - HStack() { - ProgressView() - .scaleEffect(0.5) - Text("Installing and configuring Core Lightning. (wait for the terminal script to complete)") - } - .frame(maxWidth: .infinity, alignment: .topLeading) - .padding([.leading, .top]) - - } else if lightningInstalled { - CoreLightning() - } else { - FNIcon() - Spacer() + NavigationView { + List { + ForEach(services) { service in + NavigationLink { + if service.name == "Bitcoin Core" { if bitcoinCoreInstalled { - Button("Install Core Lightning") { - installLightning() - } - Spacer() + BitcoinCore() } else { - Text("First install Bitcoin Core.") + Home( + showBitcoinCoreInstallButton: true, + env: env, + showJoinMarketInstallButton: false, + jmTaggedReleases: [] + ) } - } - - } else if service.name == "Join Market" { - if joinMarketInstalled { - JoinMarket() - } else { - if !bitcoinCoreInstalled { - Text("First install Bitcoin Core.") - } - Home( - showBitcoinCoreInstallButton: false, - env: env, - showJoinMarketInstallButton: true, - jmTaggedReleases: jmTaggedReleases - ) - } - } else if service.name == "Tor" { - FNIcon() - HStack() { - if torProgress < 100.0 { - ProgressView("Tor bootstrapping \(Int(torProgress))% complete…", value: torProgress, total: 100) - .padding([.leading, .trailing]) - .frame(alignment: .topLeading) + } else if service.name == "Core Lightning" { + if isInstallingLightning { + HStack() { + ProgressView() + .scaleEffect(0.5) + Text("Installing and configuring Core Lightning. (wait for the terminal script to complete)") + } + .frame(maxWidth: .infinity, alignment: .topLeading) + .padding([.leading, .top]) + + } else if lightningInstalled { + CoreLightning() } else { - if torRunning { - Image(systemName: "circle.fill") - .foregroundStyle(.green) - .padding([.leading]) - Text("Tor running") + FNIcon() + Spacer() + if bitcoinCoreInstalled { + Button("Install Core Lightning") { + installLightning() + } + Spacer() } else { - Image(systemName: "circle.fill") - .foregroundStyle(.orange) - .padding([.leading]) - Text("Tor stopped") + Text("First install Bitcoin Core.") } } - } - .frame(maxWidth: .infinity, alignment: .leading) - Spacer() - } - } label: { - HStack() { - if service.name == "Bitcoin Core" { - if bitcoinCoreInstalled { - Image(systemName: "checkmark") - .foregroundStyle(.green) + + } else if service.name == "Join Market" { + if joinMarketInstalled { + JoinMarket() } else { - Image(systemName: "xmark") - .foregroundStyle(.gray) - EmptyView() - .onReceive(timerForBitcoinInstall) { _ in - DataManager.retrieve(entityName: "BitcoinEnv") { bitcoinEnv in - guard let bitcoinEnv = bitcoinEnv else { return } - let envValues = BitcoinEnvValues(dictionary: bitcoinEnv) - let tempPath = "/Users/\(NSUserName())/.fullynoded/BitcoinCore/\(envValues.prefix)/bin/bitcoind" - if FileManager.default.fileExists(atPath: tempPath) { - bitcoinCoreInstalled = true - self.timerForBitcoinInstall.upstream.connect().cancel() - getJmRelease() - } + if !bitcoinCoreInstalled { + Text("First install Bitcoin Core.") + } + Home( + showBitcoinCoreInstallButton: false, + env: env, + showJoinMarketInstallButton: true, + jmTaggedReleases: jmTaggedReleases + ) + } + } else if service.name == "Tor" { + FNIcon() + HStack() { + if torProgress < 100.0 { + ProgressView("Tor v0.4.8.12 bootstrapping \(Int(torProgress))% complete…", value: torProgress, total: 100) + .padding([.leading, .trailing]) + .frame(alignment: .topLeading) + } else { + if torRunning { + Image(systemName: "circle.fill") + .foregroundStyle(.green) + .padding([.leading]) + Text("Tor v0.4.8.12 running") + } else { + Image(systemName: "circle.fill") + .foregroundStyle(.orange) + .padding([.leading]) + Text("Tor v0.4.8.12 stopped") + } + } + Toggle("", isOn: $torRunning) + .toggleStyle(SwitchToggleStyle()) + .onChange(of: torRunning) { + if !torRunning { + TorClient.sharedInstance.resign() } - } } + .frame(maxWidth: .infinity, alignment: .leading) + Spacer() } - - if service.name == "Core Lightning" { - if lightningInstalled { - Image(systemName: "checkmark") - .foregroundStyle(.green) - } else { - Image(systemName: "xmark") - .foregroundStyle(.gray) - EmptyView() - .onReceive(timerForLightningInstall) { _ in - if FileManager.default.fileExists(atPath: "/opt/homebrew/Cellar/core-lightning/24.08.1/bin/lightningd") { - lightningInstalled = true - isInstallingLightning = false - self.timerForLightningInstall.upstream.connect().cancel() + } label: { + HStack() { + if service.name == "Bitcoin Core" { + if bitcoinCoreInstalled { + Image(systemName: "checkmark") + .foregroundStyle(.green) + } else { + Image(systemName: "xmark") + .foregroundStyle(.gray) + EmptyView() + .onReceive(timerForBitcoinInstall) { _ in + DataManager.retrieve(entityName: .bitcoinEnv) { bitcoinEnv in + guard let bitcoinEnv = bitcoinEnv else { return } + let envValues = BitcoinEnvValues(dictionary: bitcoinEnv) + let tempPath = "/Users/\(NSUserName())/.fullynoded/BitcoinCore/\(envValues.prefix)/bin/bitcoind" + if FileManager.default.fileExists(atPath: tempPath) { + bitcoinCoreInstalled = true + self.timerForBitcoinInstall.upstream.connect().cancel() + getJmRelease() + } + } + } - } + } } - } - - if service.name == "Join Market" { - if joinMarketInstalled { - Image(systemName: "checkmark") - .foregroundStyle(.green) - } else { - Image(systemName: "xmark") - .foregroundStyle(.gray) - EmptyView() - .onReceive(timerForJMInstall) { _ in - if let tagName = UserDefaults.standard.string(forKey: "tagName") { - let jmConfigPath = "/Users/\(NSUserName())/Library/Application Support/joinmarket/joinmarket.cfg" - if FileManager.default.fileExists(atPath: "/Users/\(NSUserName())/.fullynoded/JoinMarket/joinmarket-\(tagName)/scripts/jmwalletd.py") && FileManager.default.fileExists(atPath: jmConfigPath) { - joinMarketInstalled = true - self.timerForJMInstall.upstream.connect().cancel() + + if service.name == "Core Lightning" { + if lightningInstalled { + Image(systemName: "checkmark") + .foregroundStyle(.green) + } else { + Image(systemName: "xmark") + .foregroundStyle(.gray) + EmptyView() + .onReceive(timerForLightningInstall) { _ in + if FileManager.default.fileExists(atPath: "/opt/homebrew/Cellar/core-lightning/24.08.1/bin/lightningd") { + lightningInstalled = true + isInstallingLightning = false + self.timerForLightningInstall.upstream.connect().cancel() } } - } + } } - } - - if service.name == "Tor" { - if torProgress < 100.0 { - ProgressView() - //.padding(.leading) - #if os(macOS) - .scaleEffect(0.5) - #endif - } else { - if torRunning { + + if service.name == "Join Market" { + if joinMarketInstalled { Image(systemName: "checkmark") .foregroundStyle(.green) } else { Image(systemName: "xmark") .foregroundStyle(.gray) + EmptyView() + .onReceive(timerForJMInstall) { _ in + if let tagName = UserDefaults.standard.string(forKey: "tagName") { + let jmConfigPath = "/Users/\(NSUserName())/Library/Application Support/joinmarket/joinmarket.cfg" + if FileManager.default.fileExists(atPath: "/Users/\(NSUserName())/.fullynoded/JoinMarket/joinmarket-\(tagName)/scripts/jmwalletd.py") && FileManager.default.fileExists(atPath: jmConfigPath) { + joinMarketInstalled = true + self.timerForJMInstall.upstream.connect().cancel() + } + } + } } } - EmptyView() - .onReceive(timerForTor) { _ in - self.torRunning = TorClient.sharedInstance.state == .connected + if service.name == "Tor" { + if torProgress < 100.0 { + ProgressView() +#if os(macOS) + .scaleEffect(0.5) +#endif + } else { + if torRunning { + Image(systemName: "checkmark") + .foregroundStyle(.green) + } else { + Image(systemName: "xmark") + .foregroundStyle(.gray) + } } + + EmptyView() + .onReceive(timerForTor) { _ in + self.torRunning = TorClient.sharedInstance.state == .connected + } + } + Text(service.name) } - Text(service.name) + } - } } + Text("Select a service.") + .foregroundStyle(.secondary) } - } + .onAppear(perform: { /// For testing fresh install. // DataManager.deleteAllData(entityName: "BitcoinRPCCreds") { deleted in @@ -306,7 +315,7 @@ struct ContentView: View { private func installLightning() { isInstallingLightning = true - DataManager.retrieve(entityName: "BitcoinRPCCreds") { bitcoinRPCCreds in + DataManager.retrieve(entityName: .rpcCreds) { bitcoinRPCCreds in guard let bitcoinRPCCreds = bitcoinRPCCreds else { isInstallingLightning = false showMessage(message: "NO Bitcoin RPC Creds, create them?") @@ -355,7 +364,7 @@ struct ContentView: View { } private func getSavedValues() { - DataManager.retrieve(entityName: "BitcoinEnv") { bitcoinEnv in + DataManager.retrieve(entityName: .bitcoinEnv) { bitcoinEnv in guard let bitcoinEnv = bitcoinEnv else { let dict = [ "binaryName": "bitcoin-26.2-arm64-apple-darwin.tar.gz", @@ -365,7 +374,7 @@ struct ContentView: View { "chain": Defaults.shared.chain ] - DataManager.saveEntity(entityName: "BitcoinEnv", dict: dict) { saved in + DataManager.saveEntity(entityName: .bitcoinEnv, dict: dict) { saved in guard saved else { showMessage(message: "Unable to save default bitcoin env values.") return diff --git a/FullyNoded-Server/Views/CoreLightning.swift b/FullyNoded-Server/Views/CoreLightning.swift index 7db78920..22cccbc3 100644 --- a/FullyNoded-Server/Views/CoreLightning.swift +++ b/FullyNoded-Server/Views/CoreLightning.swift @@ -30,7 +30,7 @@ struct CoreLightning: View { Image(systemName: "server.rack") .padding(.leading) - Text("Core Lightning Server") + Text("Core Lightning Server v24.08.1") Spacer() Button { isLightningOn() @@ -51,23 +51,27 @@ struct CoreLightning: View { Image(systemName: "circle.fill") .foregroundStyle(.orange) .padding(.leading) + Text("Stopping...") } else { Image(systemName: "circle.fill") .foregroundStyle(.green) .padding(.leading) + Text("Running") } - Text("Running") + } else { if isAnimating { Image(systemName: "circle.fill") .foregroundStyle(.orange) .padding(.leading) + Text("Starting...") } else { Image(systemName: "circle.fill") .foregroundStyle(.red) .padding(.leading) + Text("Stopped") } - Text("Stopped") + } if !isRunning { @@ -182,12 +186,12 @@ struct CoreLightning: View { if errorMessage != "" { showMessage(message: errorMessage!) } else if let data = rawData { - parseDataResponse(script: .getRune, data: data) + parseRuneResponse(data: data) } return } guard let output = output, let data = rawData else { return } - parseDataResponse(script: .getRune, data: data) + parseRuneResponse(data: data) } } .padding([.leading]) @@ -279,6 +283,15 @@ struct CoreLightning: View { getPublicUrl(isLocal: false) } + private func parseLightningRunning(output: String) { + isAnimating = false + if output.contains("Running") { + isRunning = true + } else if output.contains("Stopped") { + isRunning = false + } + } + private func startLightning() { isAnimating = true DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { @@ -287,25 +300,21 @@ struct CoreLightning: View { if errorMessage != "" { showMessage(message: errorMessage!) } else if let output = output { - parseScriptResult(script: .lightingRunning, result: output) + parseLightningRunning(output: output) } return } guard let output = output else { return } - parseScriptResult(script: .lightingRunning, result: output) + parseLightningRunning(output: output) } } ScriptUtil.runScript(script: .startLightning, env: nil, args: nil) { (output, rawData, errorMessage) in guard errorMessage == nil else { if errorMessage != "" { showMessage(message: errorMessage!) - } else if let output = output { - parseScriptResult(script: .startLightning, result: output) } return } - guard let output = output else { return } - parseScriptResult(script: .startLightning, result: output) } } @@ -316,14 +325,13 @@ struct CoreLightning: View { if errorMessage != "" { showMessage(message: errorMessage!) } else if let output = output { - parseScriptResult(script: .lightingRunning, result: output) + parseLightningRunning(output: output) } return } guard let output = output else { return } - parseScriptResult(script: .lightingRunning, result: output) + parseLightningRunning(output: output) } - } private func stopLightning() { @@ -333,12 +341,12 @@ struct CoreLightning: View { if errorMessage != "" { showMessage(message: errorMessage!) } else if let output = output { - parseScriptResult(script: .stopLightning, result: output) + stopLightningParse(result: output) } return } guard let output = output else { return } - parseScriptResult(script: .stopLightning, result: output) + stopLightningParse(result: output) } } @@ -437,59 +445,33 @@ struct CoreLightning: View { guard errorMessage == nil else { if errorMessage != "" { showMessage(message: errorMessage!) - } else if let output = output { - parseScriptResult(script: .lightningNodeId, result: output) + } else if let data = rawData { + parseLigtningNodeId(data: data) } return } - guard let output = output else { return } - parseScriptResult(script: .lightningNodeId, result: output) + guard let data = rawData else { return } + parseLigtningNodeId(data: data) } } - func parseDataResponse(script: SCRIPT, data: Data) { - switch script { - case .getRune: - guard let runeResponse = dec(Rune.self, data).response as? Rune, let rune = runeResponse.rune else { return } - let publicLnLink = "lnlink:\(self.nodeId)@\(self.publicUrl)?token=\(rune)" - if publicUrl != "" { - self.qrImage = publicLnLink.qrQode - } - self.localLnlink = "lnlink:\(self.nodeId)@127.0.0.1:9735?token=\(rune)" - if let onionHost = self.onionHost { - self.quickConnectClnRest = "clnrest://\(onionHost):18765?token=\(rune)" - } - - case .lightningNodeId: - guard let info = dec(GetInfo.self, data).response as? GetInfo else { return } - self.nodeId = info.id - //runScript(script: .getRune) - - default: - break - } + private func parseLigtningNodeId(data: Data) { + guard let info = dec(GetInfo.self, data).response as? GetInfo else { return } + self.nodeId = info.id } - func parseScriptResult(script: SCRIPT, result: String) { - switch script { - case .stopLightning: - stopLightningParse(result: result) - - case .lightingRunning: - isAnimating = false - if result.contains("Running") { - isRunning = true - - } else if result.contains("Stopped") { - isRunning = false - } - - default: - break + private func parseRuneResponse(data: Data) { + guard let runeResponse = dec(Rune.self, data).response as? Rune, let rune = runeResponse.rune else { return } + let publicLnLink = "lnlink:\(self.nodeId)@\(self.publicUrl)?token=\(rune)" + if publicUrl != "" { + self.qrImage = publicLnLink.qrQode + } + self.localLnlink = "lnlink:\(self.nodeId)@127.0.0.1:9735?token=\(rune)" + if let onionHost = self.onionHost { + self.quickConnectClnRest = "clnrest://\(onionHost):18765?token=\(rune)" } - - showLog() } + private func dec(_ codable: Codable.Type, _ jsonData: Data) -> (response: Any?, errorDesc: String?) { let decoder = JSONDecoder() diff --git a/FullyNoded-Server/Views/JoinMarket.swift b/FullyNoded-Server/Views/JoinMarket.swift index 6b532db6..1949a0b8 100644 --- a/FullyNoded-Server/Views/JoinMarket.swift +++ b/FullyNoded-Server/Views/JoinMarket.swift @@ -35,7 +35,7 @@ struct JoinMarket: View { Image(systemName: "server.rack") .padding(.leading) - Text("Join Market Server") + Text("Join Market Server v\(version)") Spacer() Button { @@ -46,7 +46,6 @@ struct JoinMarket: View { } .padding([.trailing]) } - //.padding([.]) .frame(maxWidth: .infinity, alignment: .leading) HStack() { @@ -60,26 +59,38 @@ struct JoinMarket: View { Image(systemName: "circle.fill") .foregroundStyle(.orange) .padding([.leading]) + + Text("Starting...") + .onAppear { + isAutoRefreshing = true + } + } else { Image(systemName: "circle.fill") .foregroundStyle(.green) .padding([.leading]) + + Text("Running") + .onAppear { + isAutoRefreshing = true + } } - Text("Running") - .onAppear { - isAutoRefreshing = true - } + } else { if isAnimating { Image(systemName: "circle.fill") .foregroundStyle(.orange) .padding([.leading]) + + Text("Starting...") + } else { Image(systemName: "circle.fill") .foregroundStyle(.red) .padding([.leading]) + Text("Stopped") } - Text("Stopped") + } if !isRunning { Button { @@ -147,47 +158,22 @@ struct JoinMarket: View { Text("Configure JM") } Button { - NSWorkspace.shared.selectFile(nil, inFileViewerRootedAtPath: "/Users/\(NSUserName())/Library/Application Support/joinmarket") - + openDataDir() } label: { Text("Data Dir") } Button { - + increaseGapLimit() } label: { Text("Increase gap limit") } Button { - BitcoinRPC.shared.command(method: "getblockchaininfo", params: [:]) { (result, error) in - guard error == nil, let result = result as? [String: Any] else { - showMessage(message: error ?? "Unknown error getblbockchaininfo.") - return - } - guard let pruneheight = result["pruneheight"] as? Int else { - showMessage(message: "No pruneheight") - return - } - - BitcoinRPC.shared.command(method: "rescanblockchain", params: ["start_height": pruneheight]) { (result, error) in - guard error == nil, let _ = result as? [String: Any] else { - showMessage(message: error ?? "Unknown error rescanblockchain.") - return - } - } - // No response from core when initiating a rescan... - showMessage(message: "Blockchain rescan started.") - } - + rescan() } label: { Text("Rescan") } Button { - ScriptUtil.runScript(script: .launchObWatcher, env: self.env, args: nil) { (output, _, errorMessage) in - guard let errorMess = errorMessage, errorMess != "" else { - showMessage(message: "A terminal has launched, read its output, you should be able to go to a browser and visit http://localhost:62601 to see the order book.") - return } - showMessage(message: errorMess) - } + orderBook() } label: { Text("Order Book") } @@ -270,6 +256,41 @@ struct JoinMarket: View { } } + private func openDataDir() { + NSWorkspace.shared.selectFile(nil, inFileViewerRootedAtPath: "/Users/\(NSUserName())/Library/Application Support/joinmarket") + } + + private func orderBook() { + ScriptUtil.runScript(script: .launchObWatcher, env: self.env, args: nil) { (output, _, errorMessage) in + guard let errorMess = errorMessage, errorMess != "" else { + showMessage(message: "A terminal has launched, read its output, you should be able to go to a browser and visit http://localhost:62601 to see the order book.") + return } + showMessage(message: errorMess) + } + } + + private func rescan() { + BitcoinRPC.shared.command(method: "getblockchaininfo", params: [:]) { (result, error) in + guard error == nil, let result = result as? [String: Any] else { + showMessage(message: error ?? "Unknown error getblbockchaininfo.") + return + } + guard let pruneheight = result["pruneheight"] as? Int else { + showMessage(message: "No pruneheight") + return + } + + BitcoinRPC.shared.command(method: "rescanblockchain", params: ["start_height": pruneheight]) { (result, error) in + guard error == nil, let _ = result as? [String: Any] else { + showMessage(message: error ?? "Unknown error rescanblockchain.") + return + } + } + // No response from core when initiating a rescan... + showMessage(message: "Blockchain rescan started.") + } + } + private func increaseGapLimit() { let env: [String: String] = ["TAG_NAME": env["TAG_NAME"]!, "GAP_AMOUNT": gapLimit, "WALLET_NAME": walletName] ScriptUtil.runScript(script: .launchIncreaseGapLimit, env: env, args: nil) { (output, rawData, errorMessage) in @@ -303,7 +324,7 @@ struct JoinMarket: View { updateConf(key: "max_cj_fee_abs", value: "\(Int.random(in: 2200...5000))") updateConf(key: "max_cj_fee_rel", value: Double.random(in: 0.00243...0.00421).avoidNotation) - DataManager.retrieve(entityName: "BitcoinRPCCreds") { rpcCreds in + DataManager.retrieve(entityName: .rpcCreds) { rpcCreds in guard let rpcCreds = rpcCreds, let encryptedPassword = rpcCreds["password"] as? Data, let decryptedPass = Crypto.decrypt(encryptedPassword), diff --git a/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift b/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift index 1f539fa9..1578c671 100644 --- a/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift +++ b/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift @@ -129,7 +129,7 @@ struct JoinMarketTaggedReleasesView: View { updateConf(key: "rpc_port", value: port) updateConf(key: "rpc_wallet_file", value: "jm_wallet") - DataManager.retrieve(entityName: "BitcoinRPCCreds") { rpcCreds in + DataManager.retrieve(entityName: .rpcCreds) { rpcCreds in guard let rpcCreds = rpcCreds, let encryptedPassword = rpcCreds["password"] as? Data, let decryptedPass = Crypto.decrypt(encryptedPassword), diff --git a/FullyNoded-Server/Views/TaggedReleasesView.swift b/FullyNoded-Server/Views/TaggedReleasesView.swift index ccb86bd8..fca699f2 100644 --- a/FullyNoded-Server/Views/TaggedReleasesView.swift +++ b/FullyNoded-Server/Views/TaggedReleasesView.swift @@ -203,7 +203,7 @@ struct TaggedReleasesView: View { } private func saveEnvVaules(version: String) { - DataManager.deleteAllData(entityName: "BitcoinEnv") { deleted in + DataManager.deleteAllData(entityName: .bitcoinEnv) { deleted in guard deleted else { return } let dict = [ @@ -214,7 +214,7 @@ struct TaggedReleasesView: View { "chain": Defaults.shared.chain ] - DataManager.saveEntity(entityName: "BitcoinEnv", dict: dict) { saved in + DataManager.saveEntity(entityName: .bitcoinEnv, dict: dict) { saved in guard saved else { showMessage(message: "Unable to save default bitcoin env values.") return @@ -352,7 +352,7 @@ struct TaggedReleasesView: View { if key.hasPrefix("bitcoin-datadir") { writeConf(conf: conf, key: key, value: Defaults.shared.dataDir, lightningConfPath: lightningConfPath, itemToReplace: item) } else if key.hasPrefix("bitcoin-rpcpassword") { - DataManager.retrieve(entityName: "BitcoinRPCCreds") { creds in + DataManager.retrieve(entityName: .rpcCreds) { creds in guard let creds = creds else { return } guard let encryptedPass = creds["password"] as? Data else { return } guard let decryptedPass = Crypto.decrypt(encryptedPass) else { return } From d2967eddca1226539ec798ff532bea37ecc2b0cf Mon Sep 17 00:00:00 2001 From: Fontaine Date: Thu, 14 Nov 2024 14:34:52 -0500 Subject: [PATCH 13/22] feat: UI update --- FullyNoded-Server/Views/BitcoinCore.swift | 14 ++++++++++---- FullyNoded-Server/Views/CoreLightning.swift | 11 ++++++++--- FullyNoded-Server/Views/JoinMarket.swift | 11 ++++++++--- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/FullyNoded-Server/Views/BitcoinCore.swift b/FullyNoded-Server/Views/BitcoinCore.swift index 6cadebf6..a7adf938 100644 --- a/FullyNoded-Server/Views/BitcoinCore.swift +++ b/FullyNoded-Server/Views/BitcoinCore.swift @@ -295,10 +295,16 @@ struct BitcoinCore: View { Spacer() - HStack() { - Label(logOutput, systemImage: "info.circle") - .padding(.all) - } + Label { + Text(logOutput) + .foregroundStyle(.green) + } icon: { + Image(systemName: "info.circle") + .foregroundStyle(.green) + } + .padding(.all) + .foregroundStyle(.secondary) + .onAppear(perform: { initialLoad() }) diff --git a/FullyNoded-Server/Views/CoreLightning.swift b/FullyNoded-Server/Views/CoreLightning.swift index 22cccbc3..1d370b9f 100644 --- a/FullyNoded-Server/Views/CoreLightning.swift +++ b/FullyNoded-Server/Views/CoreLightning.swift @@ -246,10 +246,15 @@ struct CoreLightning: View { .padding([.leading, .trailing]) ) Spacer() - HStack() { - Label(logOutput, systemImage: "info.circle") - .padding(.all) + Label { + Text(logOutput) + .foregroundStyle(.green) + } icon: { + Image(systemName: "info.circle") + .foregroundStyle(.green) } + .padding(.all) + .foregroundStyle(.secondary) .onAppear(perform: { isLightningOn() checkIfPlasmaExists() diff --git a/FullyNoded-Server/Views/JoinMarket.swift b/FullyNoded-Server/Views/JoinMarket.swift index 1949a0b8..2f6d99df 100644 --- a/FullyNoded-Server/Views/JoinMarket.swift +++ b/FullyNoded-Server/Views/JoinMarket.swift @@ -237,10 +237,15 @@ struct JoinMarket: View { Spacer() - HStack() { - Label(logOutput, systemImage: "info.circle") - .padding(.all) + Label { + Text(logOutput) + .foregroundStyle(.green) + } icon: { + Image(systemName: "info.circle") + .foregroundStyle(.green) } + .padding(.all) + .foregroundStyle(.secondary) .onAppear(perform: { env["TAG_NAME"] = UserDefaults.standard.string(forKey: "tagName") ?? "" selectedChain = UserDefaults.standard.string(forKey: "chain") ?? "main" From 17e327b6d6684856983cd74853e672218c1eb9ee Mon Sep 17 00:00:00 2001 From: Fontaine Date: Tue, 19 Nov 2024 09:30:59 -0500 Subject: [PATCH 14/22] lightning: add auto refresh --- FullyNoded-Server/Views/CoreLightning.swift | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/FullyNoded-Server/Views/CoreLightning.swift b/FullyNoded-Server/Views/CoreLightning.swift index 1d370b9f..863cd1a3 100644 --- a/FullyNoded-Server/Views/CoreLightning.swift +++ b/FullyNoded-Server/Views/CoreLightning.swift @@ -22,6 +22,7 @@ struct CoreLightning: View { @State private var selectedChain = UserDefaults.standard.string(forKey: "chain") ?? "main" @State private var onionHost: String? = nil @State private var quickConnectClnRest: String? = nil + private let timerForStatus = Timer.publish(every: 15, on: .main, in: .common).autoconnect() var body: some View { FNIcon() @@ -190,7 +191,7 @@ struct CoreLightning: View { } return } - guard let output = output, let data = rawData else { return } + guard let _ = output, let data = rawData else { return } parseRuneResponse(data: data) } } @@ -248,17 +249,20 @@ struct CoreLightning: View { Spacer() Label { Text(logOutput) - .foregroundStyle(.green) } icon: { Image(systemName: "info.circle") - .foregroundStyle(.green) } .padding(.all) - .foregroundStyle(.secondary) + .foregroundStyle(.tertiary) .onAppear(perform: { isLightningOn() checkIfPlasmaExists() }) + EmptyView() + .onReceive(timerForStatus) { _ in + isLightningOn() + } + .alert(message, isPresented: $showError) { Button("OK", role: .cancel) {} } @@ -295,6 +299,7 @@ struct CoreLightning: View { } else if output.contains("Stopped") { isRunning = false } + showLog() } private func startLightning() { From 58eef837c331afbf351471cf17705ba1921db7ce Mon Sep 17 00:00:00 2001 From: Fontaine Date: Tue, 19 Nov 2024 09:31:48 -0500 Subject: [PATCH 15/22] joinmarket: launch safari for order book automatically, minor refactor --- FullyNoded-Server/Views/JoinMarket.swift | 55 +++++++++++++----------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/FullyNoded-Server/Views/JoinMarket.swift b/FullyNoded-Server/Views/JoinMarket.swift index 2f6d99df..723d0783 100644 --- a/FullyNoded-Server/Views/JoinMarket.swift +++ b/FullyNoded-Server/Views/JoinMarket.swift @@ -8,7 +8,7 @@ import SwiftUI struct JoinMarket: View { - + @Environment(\.openURL) var openURL @State private var walletName = "" @State private var gapLimit = "" @State private var promptToIncreaseGapLimit = false @@ -24,6 +24,7 @@ struct JoinMarket: View { @State private var env: [String: String] = [:] @State private var url: String? @State private var isAutoRefreshing = false + @State private var orderBookOpened = false private let timerForStatus = Timer.publish(every: 5, on: .main, in: .common).autoconnect() private var chains = ["main", "test", "signet", "regtest"] @@ -209,10 +210,7 @@ struct JoinMarket: View { .frame(maxWidth: .infinity, alignment: .leading) .padding(.leading) .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + 15) { - self.qrImage = nil - self.url = nil - } + hideQrData() } if let url = url { Link("Connect Fully Noded - Join Market", destination: URL(string: url)!) @@ -220,10 +218,6 @@ struct JoinMarket: View { .frame(maxWidth: .infinity, alignment: .leading) } } - - // if let hostnames = TorClient.sharedInstance.hostnames() { - // Text(hostnames[0] + ":" + "28183") - // } } .padding() .cornerRadius(8) @@ -234,22 +228,9 @@ struct JoinMarket: View { .padding([.leading, .trailing]) ) - Spacer() - - Label { - Text(logOutput) - .foregroundStyle(.green) - } icon: { - Image(systemName: "info.circle") - .foregroundStyle(.green) - } - .padding(.all) - .foregroundStyle(.secondary) .onAppear(perform: { - env["TAG_NAME"] = UserDefaults.standard.string(forKey: "tagName") ?? "" - selectedChain = UserDefaults.standard.string(forKey: "chain") ?? "main" - isJoinMarketRunning() + initialLoad() }) .alert(message, isPresented: $showError) { Button("OK", role: .cancel) {} @@ -259,6 +240,25 @@ struct JoinMarket: View { TextField("Enter the wallet name", text: $walletName) Button("OK", action: increaseGapLimit) } + .alert("The order book launches a terminal (see output if any issues and report) and opens the browser at http://localhost:62601 to display the current order book.", + isPresented: $orderBookOpened) { + Button("Open") { + openOrderBookNow() + } + } + } + + private func hideQrData() { + DispatchQueue.main.asyncAfter(deadline: .now() + 15) { + self.qrImage = nil + self.url = nil + } + } + + private func initialLoad() { + env["TAG_NAME"] = UserDefaults.standard.string(forKey: "tagName") ?? "" + selectedChain = UserDefaults.standard.string(forKey: "chain") ?? "main" + isJoinMarketRunning() } private func openDataDir() { @@ -266,10 +266,15 @@ struct JoinMarket: View { } private func orderBook() { + orderBookOpened = true + } + + private func openOrderBookNow() { ScriptUtil.runScript(script: .launchObWatcher, env: self.env, args: nil) { (output, _, errorMessage) in guard let errorMess = errorMessage, errorMess != "" else { - showMessage(message: "A terminal has launched, read its output, you should be able to go to a browser and visit http://localhost:62601 to see the order book.") - return } + openURL(URL(string: "http://localhost:62601")!) + return + } showMessage(message: errorMess) } } From e3bf63cb6875f9b9041eb68fece5ef776314a899 Mon Sep 17 00:00:00 2001 From: Fontaine Date: Tue, 19 Nov 2024 09:32:11 -0500 Subject: [PATCH 16/22] bitcoincore: minor UI change --- FullyNoded-Server/Views/BitcoinCore.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FullyNoded-Server/Views/BitcoinCore.swift b/FullyNoded-Server/Views/BitcoinCore.swift index a7adf938..6c0edbaa 100644 --- a/FullyNoded-Server/Views/BitcoinCore.swift +++ b/FullyNoded-Server/Views/BitcoinCore.swift @@ -297,13 +297,13 @@ struct BitcoinCore: View { Label { Text(logOutput) - .foregroundStyle(.green) + //.foregroundStyle(.green) } icon: { Image(systemName: "info.circle") - .foregroundStyle(.green) + //.foregroundStyle(.green) } .padding(.all) - .foregroundStyle(.secondary) + .foregroundStyle(.tertiary) .onAppear(perform: { initialLoad() From 78d78b7aa2e08ee7ca7c37dc9a70a58169f02adf Mon Sep 17 00:00:00 2001 From: Fontaine Date: Fri, 29 Nov 2024 10:48:47 -0500 Subject: [PATCH 17/22] feat: remove rpc creds from quickconnect --- FullyNoded-Server/Views/BitcoinCore.swift | 19 +++++------- FullyNoded-Server/Views/ContentView.swift | 3 +- FullyNoded-Server/Views/CoreLightning.swift | 33 +++++---------------- FullyNoded-Server/Views/JoinMarket.swift | 10 ++----- 4 files changed, 21 insertions(+), 44 deletions(-) diff --git a/FullyNoded-Server/Views/BitcoinCore.swift b/FullyNoded-Server/Views/BitcoinCore.swift index 6c0edbaa..bac86b52 100644 --- a/FullyNoded-Server/Views/BitcoinCore.swift +++ b/FullyNoded-Server/Views/BitcoinCore.swift @@ -297,10 +297,8 @@ struct BitcoinCore: View { Label { Text(logOutput) - //.foregroundStyle(.green) } icon: { Image(systemName: "info.circle") - //.foregroundStyle(.green) } .padding(.all) .foregroundStyle(.tertiary) @@ -404,7 +402,6 @@ struct BitcoinCore: View { } private func refreshRPCAuth() { - // First remove all "FullyNoded-Server" users from the bitcoin.conf guard let newCreds = RPCAuth().generateCreds(username: "FullyNoded-Server", password: nil) else { showMessage(message: "Unable to create rpc creds.") return @@ -539,15 +536,15 @@ struct BitcoinCore: View { return } - guard let decryptedPass = Crypto.decrypt(encryptedPass) else { - showMessage(message: "Unable to decrypt rpc password data.") - return - } +// guard let decryptedPass = Crypto.decrypt(encryptedPass) else { +// showMessage(message: "Unable to decrypt rpc password data.") +// return +// } - guard let rpcPass = String(data: decryptedPass, encoding: .utf8) else { - showMessage(message: "Unable to encode decrypted rpc data to utf8 string.") - return - } +// guard let rpcPass = String(data: decryptedPass, encoding: .utf8) else { +// showMessage(message: "Unable to encode decrypted rpc data to utf8 string.") +// return +// } let url = "http://xxx:xxx@\(onionHost)" qrImage = url.qrQode diff --git a/FullyNoded-Server/Views/ContentView.swift b/FullyNoded-Server/Views/ContentView.swift index f78783fc..c75d1b96 100644 --- a/FullyNoded-Server/Views/ContentView.swift +++ b/FullyNoded-Server/Views/ContentView.swift @@ -235,10 +235,11 @@ struct ContentView: View { } } - } + }.padding() Text("Select a service.") .foregroundStyle(.secondary) } + //.padding(.all) .onAppear(perform: { /// For testing fresh install. diff --git a/FullyNoded-Server/Views/CoreLightning.swift b/FullyNoded-Server/Views/CoreLightning.swift index 863cd1a3..eb641eb4 100644 --- a/FullyNoded-Server/Views/CoreLightning.swift +++ b/FullyNoded-Server/Views/CoreLightning.swift @@ -247,13 +247,13 @@ struct CoreLightning: View { .padding([.leading, .trailing]) ) Spacer() - Label { - Text(logOutput) - } icon: { - Image(systemName: "info.circle") - } - .padding(.all) - .foregroundStyle(.tertiary) +// Label { +// Text(logOutput) +// } icon: { +// Image(systemName: "info.circle") +// } +// .padding(.all) +// .foregroundStyle(.tertiary) .onAppear(perform: { isLightningOn() checkIfPlasmaExists() @@ -299,7 +299,6 @@ struct CoreLightning: View { } else if output.contains("Stopped") { isRunning = false } - showLog() } private func startLightning() { @@ -364,22 +363,6 @@ struct CoreLightning: View { isAnimating = false if result.contains("Shutdown complete") { isRunning = false - showLog() - } - } - - private func showLog() { - let path = URL(fileURLWithPath: "/Users/\(NSUserName())/.lightning/lightning.log") - guard let log = try? String(contentsOf: path, encoding: .utf8) else { - print("can not get lightning.log") - return - } - let logItems = log.components(separatedBy: "\n") - DispatchQueue.main.async { - if logItems.count > 2 { - let lastLogItem = "\(logItems[logItems.count - 2])" - logOutput = lastLogItem - } } } @@ -425,7 +408,7 @@ struct CoreLightning: View { } else { let path = URL(fileURLWithPath: "/Users/\(NSUserName())/.lightning/config") guard let config = try? Data(contentsOf: path) else { - print("Unable to get ngrok.log.") + print("Unable to get config.") return } guard let stringValue = String(data: config, encoding: .utf8) else { diff --git a/FullyNoded-Server/Views/JoinMarket.swift b/FullyNoded-Server/Views/JoinMarket.swift index 723d0783..eddb8acc 100644 --- a/FullyNoded-Server/Views/JoinMarket.swift +++ b/FullyNoded-Server/Views/JoinMarket.swift @@ -240,11 +240,8 @@ struct JoinMarket: View { TextField("Enter the wallet name", text: $walletName) Button("OK", action: increaseGapLimit) } - .alert("The order book launches a terminal (see output if any issues and report) and opens the browser at http://localhost:62601 to display the current order book.", - isPresented: $orderBookOpened) { - Button("Open") { - openOrderBookNow() - } + .alert("The order book launches a terminal (see output if any issues and report) and opens the browser at http://localhost:62601 to display the current order book.", isPresented: $orderBookOpened) { + Button("Open", action: openOrderBookNow) } } @@ -434,7 +431,6 @@ struct JoinMarket: View { if let wallets = try? fm.contentsOfDirectory(atPath: path) { for wallet in wallets { - print("Found \(wallet)") if wallet.hasSuffix(".lock") { // Delete the .lock file try? fm.removeItem(atPath: path + "/" + wallet) @@ -474,7 +470,7 @@ struct JoinMarket: View { guard errorDesc == nil else { if errorDesc!.contains("Could not connect to the server.") { isRunning = false - } else if !errorDesc!.contains("The request timd out.") { + } else if !errorDesc!.contains("The request timed out.") { showMessage(message: errorDesc!) } return From 0d1e203dac1743a0810cf4c4f341f47b5ad7e9ad Mon Sep 17 00:00:00 2001 From: Fonta1n3 Date: Mon, 2 Dec 2024 16:44:01 -0600 Subject: [PATCH 18/22] feat: general fixes and improvements --- FullyNoded-Server.xcodeproj/project.pbxproj | 14 ++- .../UserInterfaceState.xcuserstate | Bin 42591 -> 163781 bytes .../UserInterfaceState.xcuserstate | Bin 37935 -> 173994 bytes .../Assets.xcassets/1024.imageset/1024.png | Bin 45290 -> 0 bytes .../1024.imageset/Contents.json | 21 ----- .../AppIcon.appiconset/1024-mac.png | Bin 0 -> 52270 bytes .../AppIcon.appiconset/128-mac.png | Bin 0 -> 4296 bytes .../AppIcon.appiconset/16-mac.png | Bin 0 -> 296 bytes .../AppIcon.appiconset/256-mac.png | Bin 0 -> 11016 bytes .../AppIcon.appiconset/32-mac.png | Bin 0 -> 734 bytes .../AppIcon.appiconset/512-mac.png | Bin 0 -> 23548 bytes .../AppIcon.appiconset/64-mac.png | Bin 0 -> 1606 bytes .../AppIcon.appiconset/Contents.json | 15 +++- .../Helpers/InstallBtcCore.swift | 9 +- FullyNoded-Server/Helpers/Script.swift | 37 +++++--- .../Scripts/CheckForBitcoinCore.command | 3 +- .../Scripts/DeleteWallet.command | 58 ------------- .../Scripts/LaunchInstaller.command | 1 - .../Scripts/LaunchUpdateLightning.command | 14 +++ .../Scripts/UpdateLightning.command | 9 ++ FullyNoded-Server/Views/BitcoinCore.swift | 80 +++++++++++------- FullyNoded-Server/Views/CoreLightning.swift | 44 +++++----- FullyNoded-Server/Views/JoinMarket.swift | 55 +++++++++--- .../Views/TaggedReleasesView.swift | 21 +++-- 24 files changed, 206 insertions(+), 175 deletions(-) delete mode 100644 FullyNoded-Server/Assets.xcassets/1024.imageset/1024.png delete mode 100644 FullyNoded-Server/Assets.xcassets/1024.imageset/Contents.json create mode 100644 FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/1024-mac.png create mode 100644 FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/128-mac.png create mode 100644 FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/16-mac.png create mode 100644 FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/256-mac.png create mode 100644 FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/32-mac.png create mode 100644 FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/512-mac.png create mode 100644 FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/64-mac.png delete mode 100755 FullyNoded-Server/Scripts/DeleteWallet.command create mode 100755 FullyNoded-Server/Scripts/LaunchUpdateLightning.command create mode 100755 FullyNoded-Server/Scripts/UpdateLightning.command diff --git a/FullyNoded-Server.xcodeproj/project.pbxproj b/FullyNoded-Server.xcodeproj/project.pbxproj index 16ce4e4b..8debdf2e 100644 --- a/FullyNoded-Server.xcodeproj/project.pbxproj +++ b/FullyNoded-Server.xcodeproj/project.pbxproj @@ -46,7 +46,6 @@ 0AA6924B2C7F89E800366192 /* Script.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA6924A2C7F89E800366192 /* Script.swift */; }; 0AA6925E2C7F8EC700366192 /* CheckForBitcoinCore.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AA6924C2C7F8EC700366192 /* CheckForBitcoinCore.command */; }; 0AA6925F2C7F8EC700366192 /* CheckXCodeSelect.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AA6924D2C7F8EC700366192 /* CheckXCodeSelect.command */; }; - 0AA692602C7F8EC700366192 /* DeleteWallet.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AA6924E2C7F8EC700366192 /* DeleteWallet.command */; }; 0AA692612C7F8EC700366192 /* InstallBrew.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AA6924F2C7F8EC700366192 /* InstallBrew.command */; }; 0AA692622C7F8EC700366192 /* InstallXcode.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AA692502C7F8EC700366192 /* InstallXcode.command */; }; 0AA692632C7F8EC700366192 /* IsProcessRunning.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AA692512C7F8EC700366192 /* IsProcessRunning.command */; }; @@ -63,6 +62,8 @@ 0AA6926E2C7F8EC700366192 /* Verify.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AA6925C2C7F8EC700366192 /* Verify.command */; }; 0AA692702C7F962A00366192 /* Home.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA6926F2C7F962A00366192 /* Home.swift */; }; 0AA692722C80B01A00366192 /* BitcoinRPC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA692712C80B01A00366192 /* BitcoinRPC.swift */; }; + 0AC92C2B2CFE5F4600F10EC6 /* UpdateLightning.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AC92C2A2CFE5F4600F10EC6 /* UpdateLightning.command */; }; + 0AC92C2D2CFE5FC300F10EC6 /* LaunchUpdateLightning.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AC92C2C2CFE5FC300F10EC6 /* LaunchUpdateLightning.command */; }; 0AD7BE0D2CB97F4100428D02 /* LatestJoinMarketRelease.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD7BE0C2CB97F4100428D02 /* LatestJoinMarketRelease.swift */; }; 0AD7BE0F2CB980D500428D02 /* JoinMarketTaggedReleases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AD7BE0E2CB980D500428D02 /* JoinMarketTaggedReleases.swift */; }; 0AD7BE112CBD6AA500428D02 /* InstallJoinMarket.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AD7BE102CBD6AA500428D02 /* InstallJoinMarket.command */; }; @@ -127,7 +128,6 @@ 0AA6924A2C7F89E800366192 /* Script.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Script.swift; sourceTree = ""; }; 0AA6924C2C7F8EC700366192 /* CheckForBitcoinCore.command */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = CheckForBitcoinCore.command; sourceTree = ""; }; 0AA6924D2C7F8EC700366192 /* CheckXCodeSelect.command */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = CheckXCodeSelect.command; sourceTree = ""; }; - 0AA6924E2C7F8EC700366192 /* DeleteWallet.command */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = DeleteWallet.command; sourceTree = ""; }; 0AA6924F2C7F8EC700366192 /* InstallBrew.command */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = InstallBrew.command; sourceTree = ""; }; 0AA692502C7F8EC700366192 /* InstallXcode.command */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = InstallXcode.command; sourceTree = ""; }; 0AA692512C7F8EC700366192 /* IsProcessRunning.command */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = IsProcessRunning.command; sourceTree = ""; }; @@ -144,6 +144,8 @@ 0AA6925C2C7F8EC700366192 /* Verify.command */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = Verify.command; sourceTree = ""; }; 0AA6926F2C7F962A00366192 /* Home.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Home.swift; sourceTree = ""; }; 0AA692712C80B01A00366192 /* BitcoinRPC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BitcoinRPC.swift; sourceTree = ""; }; + 0AC92C2A2CFE5F4600F10EC6 /* UpdateLightning.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = UpdateLightning.command; sourceTree = ""; }; + 0AC92C2C2CFE5FC300F10EC6 /* LaunchUpdateLightning.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = LaunchUpdateLightning.command; sourceTree = ""; }; 0AD7BE0C2CB97F4100428D02 /* LatestJoinMarketRelease.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatestJoinMarketRelease.swift; sourceTree = ""; }; 0AD7BE0E2CB980D500428D02 /* JoinMarketTaggedReleases.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinMarketTaggedReleases.swift; sourceTree = ""; }; 0AD7BE102CBD6AA500428D02 /* InstallJoinMarket.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = InstallJoinMarket.command; sourceTree = ""; }; @@ -289,7 +291,6 @@ children = ( 0AA6924C2C7F8EC700366192 /* CheckForBitcoinCore.command */, 0AA6924D2C7F8EC700366192 /* CheckXCodeSelect.command */, - 0AA6924E2C7F8EC700366192 /* DeleteWallet.command */, 0AA6924F2C7F8EC700366192 /* InstallBrew.command */, 0AA692502C7F8EC700366192 /* InstallXcode.command */, 0AA692512C7F8EC700366192 /* IsProcessRunning.command */, @@ -324,6 +325,8 @@ 593A89202CE28400001504F0 /* LaunchIncreaseGapLimit.command */, 593A89242CE519B3001504F0 /* LaunchObWatcher.command */, 593A89262CE51A35001504F0 /* ObWatcher.command */, + 0AC92C2A2CFE5F4600F10EC6 /* UpdateLightning.command */, + 0AC92C2C2CFE5FC300F10EC6 /* LaunchUpdateLightning.command */, ); path = Scripts; sourceTree = ""; @@ -413,12 +416,12 @@ 0AA692422C7F831F00366192 /* Preview Assets.xcassets in Resources */, 0AA692632C7F8EC700366192 /* IsProcessRunning.command in Resources */, 0AA692672C7F8EC700366192 /* LaunchVerifier.command in Resources */, + 0AC92C2D2CFE5FC300F10EC6 /* LaunchUpdateLightning.command in Resources */, 593A89272CE51A35001504F0 /* ObWatcher.command in Resources */, 0AA692612C7F8EC700366192 /* InstallBrew.command in Resources */, 0AA6926C2C7F8EC700366192 /* StopBitcoin.command in Resources */, 0AD7BE152CBD7AC100428D02 /* LaunchJMInstaller.command in Resources */, 0AA692642C7F8EC700366192 /* LaunchBrewInstall.command in Resources */, - 0AA692602C7F8EC700366192 /* DeleteWallet.command in Resources */, 0AA6926D2C7F8EC700366192 /* Strap.command in Resources */, 0AD7BE212CC2B1F100428D02 /* StartJm.command in Resources */, 0AA6926B2C7F8EC700366192 /* StartBitcoin.command in Resources */, @@ -446,6 +449,7 @@ 0AA6925E2C7F8EC700366192 /* CheckForBitcoinCore.command in Resources */, 0A573E312CB577D100899F84 /* GetRune.command in Resources */, 0AA692682C7F8EC700366192 /* LaunchXcodeInstall.command in Resources */, + 0AC92C2B2CFE5F4600F10EC6 /* UpdateLightning.command in Resources */, 0AA692652C7F8EC700366192 /* LaunchInstaller.command in Resources */, 0A5CE8E02C8A2ADE00534A8D /* CheckForLightning.command in Resources */, ); @@ -661,6 +665,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CODE_SIGN_ENTITLEMENTS = "FullyNoded-Server/FullyNoded_Server.entitlements"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; @@ -702,6 +707,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CODE_SIGN_ENTITLEMENTS = "FullyNoded-Server/FullyNoded_Server.entitlements"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; diff --git a/FullyNoded-Server.xcodeproj/project.xcworkspace/xcuserdata/fontaine.xcuserdatad/UserInterfaceState.xcuserstate b/FullyNoded-Server.xcodeproj/project.xcworkspace/xcuserdata/fontaine.xcuserdatad/UserInterfaceState.xcuserstate index 9e0326d2c2cc27d9ba2439d944fdceef70593fd8..bdf30b46fee848028b7193873456320299b20843 100644 GIT binary patch literal 163781 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 Z|NYy)F8P1|_}?r3-#`BUzYkAO`9BJ;f5ZR) literal 42591 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

{ZE3?q(*1No58xX-qnk!DKR7Og59F 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�cmdrt4UvFFP@KXJvb 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 YUDhpdtw)tj*RGGe$GJ!Te|1;>4;aM8%m4rY diff --git a/FullyNoded-Server.xcworkspace/xcuserdata/fontaine.xcuserdatad/UserInterfaceState.xcuserstate b/FullyNoded-Server.xcworkspace/xcuserdata/fontaine.xcuserdatad/UserInterfaceState.xcuserstate index 6dc40899609a7fd1bff692597407f2e8f541377a..85dfe617304a10da1385f401ebc9a312063b9867 100644 GIT binary patch literal 173994 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 J|2w(Q^$!Xv+^_%u diff --git a/FullyNoded-Server/Assets.xcassets/1024.imageset/1024.png b/FullyNoded-Server/Assets.xcassets/1024.imageset/1024.png deleted file mode 100644 index 1052ab5b167bbc300f85626204800d62c78434c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45290 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 hOkez$-}APd?|I%uS^QBJ#@86+|E)ptvLU6tt?I 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 literal 0 HcmV?d00001 diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/128-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/128-mac.png new file mode 100644 index 0000000000000000000000000000000000000000..45b1963d8110e0876041764b0047870ea602ba2d GIT binary patch literal 4296 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 literal 0 HcmV?d00001 diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/16-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/16-mac.png new file mode 100644 index 0000000000000000000000000000000000000000..7c506e6a690469bfaa0b991050d501c3530d919f GIT binary patch literal 296 zcmV+@0oVRgNk&E>0RRA3MM6+kP&il$0000G0000F000jF06|PpNM8T|00D3l+qSD5 zZ$DQbBQIBfaKcc6$(Qqc5+Y&(FmoY{3&9y(E1%H$1+WIMP2GnLU_tw)4jhod_)zsG z$RPo!J~^ZS*(YbPV0=>t0UW_;Q`Ih90DhtKkMe%r)#rto09H^qAesOG0FVLzodGHk z01yBHKqe)m02Au=AHmY9&piB6HGlyA`wVB!8{Kp~WGF&E4M`IenDVr-CgWOs<2+Sd zFG|0rS1xb4)URKjZfHd5!yEH%2LD{+H6{gWKZtZsv~FC}d!PDAHfEq{hv%BtH{8yA uIXVRJy+HiOT6HV>RKcnWzICeZRDRQyHKS41!R7g#Vdh^q*gXssh#&yVH+UZa literal 0 HcmV?d00001 diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/256-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/256-mac.png new file mode 100644 index 0000000000000000000000000000000000000000..8847b31f93a01056de5bb6ceedd53823457d2396 GIT binary patch literal 11016 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 C)vs&- literal 0 HcmV?d00001 diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/32-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/32-mac.png new file mode 100644 index 0000000000000000000000000000000000000000..9b73b161d9f2ba9d637a93f261b6f19d87a0ad6a GIT binary patch literal 734 zcmV<40wMiUNk&H20ssJ4MM6+kP&il$0000G0000V0018V06|PpNE87801c30TidcN z=emD)kKX?oX#9UHS%OAqAPj-3*{9%8N!s0cxt|MpmmxhOCV)S5z@=3v8^{R*2m}~R z79-cGaQxW%SRm?6`SSGoRY&$@g%lI(N9Inwk^ys-N&?jZ2K(^Y69xwI1l1Tu zG?WRdgQd#@i8+RF&|Em+=ru!O1373d2OCcl7#u^UOELN7I}ictLS~>CK>W2 z0ERW=)94RieHtL%vV|{`{-^v*$uq zUT04I{@0o`kGqj5*13x57o3h{Q}h!7cW!gjb;(Wu|pX$1T{{24C z;vM^c|HpZ}-Dcfl?anaIt{KU~!+Afe4rD(24pPq+sy)CZ3JP$W$`dUC(fKVwe>;EM zg5(_MJ9nTjDo|+)s`rx|?G2R_pP5?D`0h$%wzf5do^Y3ofbseB|MkMcy1ex$8puEZ04z6GqyPW_ literal 0 HcmV?d00001 diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/512-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/512-mac.png new file mode 100644 index 0000000000000000000000000000000000000000..a6a15242adfc6c49b97758b97b6a38d6df427252 GIT binary patch literal 23548 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 D?!)th literal 0 HcmV?d00001 diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/64-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/64-mac.png new file mode 100644 index 0000000000000000000000000000000000000000..19f98dbbf20394e1124457eaf1cb97920dbb3a0b GIT binary patch literal 1606 zcmV-M2D$lCNk&FK1^@t8MM6+kP&il$0000G0000#002J#06|PpNag_m00E%1ZJS}c zdaEk7os4bUc4oOUvh8G+neCZz%xzAOZTmN*tJnJ;t=he+4`&fE0r-#6HgndP?2NIl znJtAwq%JE9n6X<=-+ubVmtK0gtgNi8qOxd3Sy@@x%P+n3;xl*7Y@gr&n~6iS9q&;w zezdnGTm}v!-<9MO|EFn&{!bGx>7(&*O>&t3L`h1DR0&CuX`*x)ToWutJy9Z&Dmh7c z6(+)lq4|4CL@G*BUZ1vx331q^M5H1mmFN&$2<-bxMMX;%^jQl8T8x)SMNCrDV2e5I zkdMu4KbnP{Q=-TdU4<)Va8I6b(d#ix$P4kMdKJNCN)>sk>aeOj)P>dNp+2lW4|Tb# z{oAX_UG?8yW$tQoSO5P~-QQkq?rL&Zox7?$)PUBun0HUCHVp=vJ|Aqf|m}!py_LWkeK?k#6G3;%Q|E` z`07uJ@|T;#k*$FlxbD((4X?fZPUdgF*7(BZ4TCLAHZTCtqH~WveKYUVvvW%TFv#2( zgOVF#P-;_B{0jwEP&gnm1ONcg5&)e6DnI~006uLrlSiZ@A)zK3tFV9#iD>{8;-AX< zH}9{<_ok%AN}uKZgnsAV%(Fsc_rFp#Ukt~`chmmCpUJs!|Ll6L+2E!pmHclJ&ihKR0P5x*R#MQn4N@0vZihpmKg1Nth{3&Y1G^@ z8lq-kyYe6$ti@`lG-CNwP$bYr&;S7b>oUMM+zUzjQ5HN}E2>wEF)n|Oc^Xyjk%VCS z##nY2iCBSU?;`SJUy}Hf(-e((h~(IE*wugVHSF=L#w2SLV>gHNKy8_()|FqhRoXA$ zRrU;z4B+Lzu!zn~LP>COgY^@Qz3#rrC&C3+-`*cM$V4}N2tH4JjY0-9&Jq<)W4(D% ztZbaA*xfJBmp~fH(`JjoShr_G={7lfmFRz`S>vliCZ49h1L=bY{X5zMpI?|f#31dS zvOLB>^qizZ1H=F|-}cfhOlN#X+sv{Wo|F67-ME>&Cah4UK9 z=9YSamKIbgcRCQ3ZTOXQ#Mv1jtP*KnoztomJhl{&Gtd$xfR+8?E@3F2L0>A{#Hsxc z2uXzzD+gv!G9^j|bdpA9K;4Ct@1~tq!TYe%OC~xU16Gz#r;V-_H@2wO1(OI`+6q_Q z&p;U+Ltm=Q&5L8V2a9hpf9O{|=>@(rlvJmjRW0DI^!we6V`ZSIsiL=0`X#-v zIcw?5nni#%zzMG+e?$bm4^`=~i7h9<9h{~#A7J0p6(N5zv?G9kh+s|>ORS;Jomq|J z32NFJ+X{ixV*K2CIMD@JQ-(OWHmu=cU;O<3_w(;>)xId2{s%fe?ofrk)gz&r^W*y( z`uh0Af-(QhPv*R72u7D~w+1h^x#n!A<4=FV%s)bMmf>3_kH1@#Io4gQNk93R@=n|} zixS+Kh7?|0hZ!=(^LeHy=Xt9E$`Zk z+)U|jk=4l>hSCy{&G9X2m_pkP6Fd&-BR48M$1HUp6CSf Void) { - createDirectory("/Users/\(NSUserName())/.fullynoded", completion: completion) - - if writeFile("/Users/\(NSUserName())/.fullynoded/fullynoded.log", "") { + createDirectory(fnServerDir, completion: completion) + if writeFile("\(fnServerDir)/fullynoded.log", "") { createBitcoinCoreDirectory(completion: completion) } else { completion((false)) @@ -131,7 +132,7 @@ class CreateFNDirConfigureCore { } class func createBitcoinCoreDirectory(completion: @escaping (Bool) -> Void) { - let path = "/Users/\(NSUserName())/.fullynoded/BitcoinCore" + let path = "\(fnServerDir)/BitcoinCore" do { let fileManager = FileManager.default if fileManager.fileExists(atPath: path) { diff --git a/FullyNoded-Server/Helpers/Script.swift b/FullyNoded-Server/Helpers/Script.swift index 7717993c..3b1a356e 100644 --- a/FullyNoded-Server/Helpers/Script.swift +++ b/FullyNoded-Server/Helpers/Script.swift @@ -8,6 +8,8 @@ import Foundation public enum SCRIPT: String { + case launchUpdateLightning + case updateLightning case obWatcher case launchObWatcher case launchIncreaseGapLimit @@ -40,14 +42,18 @@ public enum SCRIPT: String { case checkForBitcoin case installBitcoin case checkXcodeSelect - case getStrapped - case launchStrap - case isBitcoinOn - case deleteWallet + //case getStrapped + //case launchStrap + //case isBitcoinOn + //case deleteWallet case startBitcoin var stringValue:String { switch self { + case .launchUpdateLightning: + return "LaunchUpdateLightning" + case .updateLightning: + return "UpdateLightning" case .obWatcher: return "ObWatcher" case .launchObWatcher: @@ -108,14 +114,14 @@ public enum SCRIPT: String { return "InstallBitcoin" case .checkXcodeSelect: return "CheckXCodeSelect" - case .getStrapped: - return "Strap" - case .launchStrap: - return "LaunchStrap" - case .isBitcoinOn: - return "IsBitcoinOn" - case .deleteWallet: - return "DeleteWallet" +// case .getStrapped: +// return "Strap" +// case .launchStrap: +// return "LaunchStrap" +// case .isBitcoinOn: +// return "IsBitcoinOn" +// case .deleteWallet: +// return "DeleteWallet" case .startBitcoin: return "StartBitcoin" } @@ -162,7 +168,12 @@ public enum ScriptUtil { let errData = stdErr.fileHandleForReading.readDataToEndOfFile() let output = String(data: data, encoding: .utf8) let errorOutput = String(data: errData, encoding: .utf8) - completion((output, data, errorOutput)) + if errorOutput == "" { + completion((output, data, nil)) + } else { + completion((output, data, errorOutput)) + } + } } } diff --git a/FullyNoded-Server/Scripts/CheckForBitcoinCore.command b/FullyNoded-Server/Scripts/CheckForBitcoinCore.command index 5664b76c..c165e74e 100755 --- a/FullyNoded-Server/Scripts/CheckForBitcoinCore.command +++ b/FullyNoded-Server/Scripts/CheckForBitcoinCore.command @@ -1,8 +1,7 @@ #!/bin/sh - if [ -d ~/.fullynoded/BitcoinCore ]; then - sudo -u $(whoami) ~/.fullynoded/BitcoinCore/$PREFIX/bin/bitcoind -version + sudo -u $(whoami) "/Users/$(whoami)/.fullynoded/BitcoinCore/$PREFIX/bin/bitcoind" -version else echo "Bitcoin not installed" fi diff --git a/FullyNoded-Server/Scripts/DeleteWallet.command b/FullyNoded-Server/Scripts/DeleteWallet.command deleted file mode 100755 index 780e0123..00000000 --- a/FullyNoded-Server/Scripts/DeleteWallet.command +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/sh - - -MAINNET_DEFAULT="$DATADIR"/wallets/"$WALLET" -TESTNET_DEFAULT="$DATADIR"/testnet3/"$WALLET" -TESTNET_POSSIBLE="$DATADIR"/testnet3/wallets/"$WALLET" -SIGNET_POSSIBLE="$DATADIR"/signet/wallets/"$WALLET" - -function deleteDefault () { - - if [ -d "$MAINNET_DEFAULT" ]; then - sudo -u $(whoami) /bin/rm -R "$MAINNET_DEFAULT" - echo ""$MAINNET_DEFAULT" deleted" - exit 1 - else - echo "Error, that wallet does not seem to exist in your data directory, since you are customizing things to custom locations please delete it manually" 1>&2 - exit 64 - fi - -} - -function deleteSignetPossible () { - - if [ -d "$SIGNET_POSSIBLE" ]; then - sudo -u $(whoami) /bin/rm -R "$SIGNET_POSSIBLE" - echo ""$SIGNET_POSSIBLE" deleted" - exit 1 - else - deleteDefault - fi - -} - -function deleteTestnetDefault () { - - if [ -d "$TESTNET_DEFAULT" ]; then - sudo -u $(whoami) /bin/rm -R "$TESTNET_DEFAULT" - echo ""$TESTNET_DEFAULT" deleted" - exit 1 - else - deleteSignetPossible - fi - -} - -function deleteTestnetPossible () { - - if [ -d "$TESTNET_POSSIBLE" ]; then - sudo -u $(whoami) /bin/rm -R "$TESTNET_POSSIBLE" - echo ""$TESTNET_POSSIBLE" deleted" - exit 1 - else - deleteTestnetDefault - fi - -} - -deleteTestnetPossible diff --git a/FullyNoded-Server/Scripts/LaunchInstaller.command b/FullyNoded-Server/Scripts/LaunchInstaller.command index b6b02d16..ccc97e45 100755 --- a/FullyNoded-Server/Scripts/LaunchInstaller.command +++ b/FullyNoded-Server/Scripts/LaunchInstaller.command @@ -1,6 +1,5 @@ #!/bin/sh - INSTALL_SCRIPT_PATH="/Users/$(whoami)/.fullynoded/installBitcoin.sh" LOG="/Users/$(whoami)/.fullynoded/fullynoded.log" touch $INSTALL_SCRIPT_PATH diff --git a/FullyNoded-Server/Scripts/LaunchUpdateLightning.command b/FullyNoded-Server/Scripts/LaunchUpdateLightning.command new file mode 100755 index 00000000..e15cde20 --- /dev/null +++ b/FullyNoded-Server/Scripts/LaunchUpdateLightning.command @@ -0,0 +1,14 @@ +#!/bin/sh + +# LaunchUpdateLightning.command +# FullyNoded-Server +# +# Created by Peter Denton on 12/2/24. +# +INSTALL_SCRIPT_PATH="/Users/$(whoami)/.fullynoded/updateLightning.sh" +LOG="/Users/$(whoami)/.fullynoded/fullynoded.log" +touch $INSTALL_SCRIPT_PATH +echo "\"$(cd "$(dirname "$0")"; pwd)/UpdateLightning.command\" $RPC_USER $RPC_PASSWORD $DATA_DIR $PREFIX $NETWORK | tee -a $LOG" > $INSTALL_SCRIPT_PATH +chmod +x $INSTALL_SCRIPT_PATH +open -a Terminal $INSTALL_SCRIPT_PATH +exit 1 diff --git a/FullyNoded-Server/Scripts/UpdateLightning.command b/FullyNoded-Server/Scripts/UpdateLightning.command new file mode 100755 index 00000000..e09e9f56 --- /dev/null +++ b/FullyNoded-Server/Scripts/UpdateLightning.command @@ -0,0 +1,9 @@ +#!/bin/sh + +# UpdateLightning.command +# FullyNoded-Server +# +# Created by Peter Denton on 12/2/24. +# +export BREW_PATH=/opt/homebrew/bin/brew +sudo -u $(whoami) $BREW_PATH upgrade core-lightning diff --git a/FullyNoded-Server/Views/BitcoinCore.swift b/FullyNoded-Server/Views/BitcoinCore.swift index bac86b52..4a5cef83 100644 --- a/FullyNoded-Server/Views/BitcoinCore.swift +++ b/FullyNoded-Server/Views/BitcoinCore.swift @@ -10,6 +10,7 @@ import SwiftUI struct BitcoinCore: View { + @State private var promptToRefreshRpcAuth = false @State private var rpcAuth = "" @State private var qrImage: NSImage? = nil @State private var startCheckingIfRunning = false @@ -204,7 +205,7 @@ struct BitcoinCore: View { } } Button { - refreshRPCAuth() + promptToRefreshRpcAuth = true } label: { Text("Refresh RPC Authentication") } @@ -244,6 +245,9 @@ struct BitcoinCore: View { } .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) + Text("Exports your onion (Tor) rpc hostname and rpc port (your nodes address) which is required for FN to connect. This QR does *NOT* include the FN-Server RPC credentials (it includes a dummy rpc user and password). You must export and authorize your rpc user from FN to FN-Server to complete your connection. To do this: In FN navigate to Node Manager > + > Scan QR > update the rpc password in Node Credentials > Save the node > Export the rpcauth text from FN and use the below button to authorize your FN rpc user.") + .foregroundStyle(.secondary) + .padding([.leading, .bottom, .trailing]) HStack() { Text("Authorize an additional RPC user:") @@ -273,13 +277,13 @@ struct BitcoinCore: View { } if let fullyNodedUrl = fullyNodedUrl { - Link("Connect Fully Noded", destination: URL(string: fullyNodedUrl)!) + Link("Connect Fully Noded (locally)", destination: URL(string: fullyNodedUrl)!) .padding([.leading]) .frame(maxWidth: .infinity, alignment: .leading) } if let unifyUrl = unifyUrl { - Link("Connect Unify", destination: URL(string: unifyUrl)!) + Link("Connect Unify (locally)", destination: URL(string: unifyUrl)!) .padding([.leading, .bottom]) .frame(maxWidth: .infinity, alignment: .leading) } @@ -309,11 +313,19 @@ struct BitcoinCore: View { .alert(message, isPresented: $showError) { Button("OK", role: .cancel) {} } - .alert("This action will delete the entire blockchain and download it again, are you sure you want to proceed? (it can take awhile..)", isPresented: $promptToReindex) { + .alert("This starts Bitcoin Core with the -reindex flag. This action will delete the entire existing blockchain and download it again, are you sure you want to proceed? (it can take a long time!)", isPresented: $promptToReindex) { Button("Reindex now", role: .destructive) { reindex() } + Button("Cancel", role: .cancel) {} } + .alert("This action updates your exisiting FullyNoded-Server rpcuser with a new rpc password as well as the Core Lightning config (if present) and Join Market config (if present). FN-Server will attempt to shut down Bitcoin Core so that the changes take effect. Do you wish to proceed?", isPresented: $promptToRefreshRpcAuth) { + Button("Refresh", role: .destructive) { + refreshRPCAuth() + } + Button("Cancel", role: .cancel) {} + } + } private func reindex() { @@ -408,6 +420,7 @@ struct BitcoinCore: View { } guard let conf = bitcoinConf() else { + showMessage(message: "Unable to get the existing bitcoin.conf file.") return } @@ -449,14 +462,13 @@ struct BitcoinCore: View { } ScriptUtil.runScript(script: .killBitcoind, env: env, args: nil) { (output, rawData, errorMessage) in guard errorMessage == nil else { - if errorMessage != "" { - showMessage(message: errorMessage!) - } else { - - } + showMessage(message: errorMessage!) + return + } + guard let output = output else { + showMessage(message: "No output when killing Bitcoin Core, you can probably ignore this error. RPC credentials should be updated, ensure Bitcoin Core restarts for the changes to take place.") return } - guard let output = output else { return } parseScriptResult(script: .killBitcoind, result: output) } } @@ -531,8 +543,8 @@ struct BitcoinCore: View { } DataManager.retrieve(entityName: .rpcCreds) { rpcCred in - guard let rpcCred = rpcCred, let encryptedPass = rpcCred["password"] as? Data else { - showMessage(message: "No rpc password saved.") + guard let _ = rpcCred else { + showMessage(message: "No rpc credentials saved.") return } @@ -759,25 +771,7 @@ struct BitcoinCore: View { isAnimating = false guard error == nil, let result = result as? [String: Any] else { if let error = error { - if !error.contains("Could not connect to the server") { - isRunning = true - switch error { - case _ where error.contains("Loading block index"), - _ where error.contains("Verifying blocks"), - _ where error.contains("Loading P2P addresses…"), - _ where error.contains("Pruning"), - _ where error.contains("Rewinding"), - _ where error.contains("Rescanning"), - _ where error.contains("Loading wallet"), - _ where error.contains("Looks like your rpc credentials"): - logOutput = error - default: - showMessage(message: error) - } - } else { - isRunning = false - logOutput = error - } + handleRPCError(error: error) } return } @@ -789,6 +783,28 @@ struct BitcoinCore: View { } } + private func handleRPCError(error: String) { + if !error.contains("Could not connect to the server") { + isRunning = true + switch error { + case _ where error.contains("Loading block index"), + _ where error.contains("Verifying blocks"), + _ where error.contains("Loading P2P addresses…"), + _ where error.contains("Pruning"), + _ where error.contains("Rewinding"), + _ where error.contains("Rescanning"), + _ where error.contains("Loading wallet"), + _ where error.contains("Looks like your rpc credentials"): + logOutput = error + default: + showMessage(message: error) + } + } else { + isRunning = false + logOutput = error + } + } + private func showMessage(message: String) { showError = true self.message = message @@ -804,7 +820,7 @@ struct BitcoinCore: View { parseDidBitcoinStart(result: result) case .killBitcoind: - if result.contains("Its dead") { + if result.contains("Its dead") || result.contains("Does not exist") { isRunning = false showMessage(message: "RPC Authentication refreshed, you need to start your node for the changes to take effect.") } diff --git a/FullyNoded-Server/Views/CoreLightning.swift b/FullyNoded-Server/Views/CoreLightning.swift index eb641eb4..ab13eb94 100644 --- a/FullyNoded-Server/Views/CoreLightning.swift +++ b/FullyNoded-Server/Views/CoreLightning.swift @@ -141,6 +141,11 @@ struct CoreLightning: View { } label: { Text("Log") } +// Button { +// ScriptUtil.runScript(script: .launchUpdateLightning, env: nil, args: nil) { (_, _, _) in } +// } label: { +// Text("Update") +// } } .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) @@ -258,14 +263,15 @@ struct CoreLightning: View { isLightningOn() checkIfPlasmaExists() }) + .alert(message, isPresented: $showError) { + Button("OK", role: .cancel) {} + } EmptyView() .onReceive(timerForStatus) { _ in isLightningOn() } - .alert(message, isPresented: $showError) { - Button("OK", role: .cancel) {} - } + } private func openFile(env: [String: String]?) { @@ -303,27 +309,25 @@ struct CoreLightning: View { private func startLightning() { isAnimating = true - DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { - ScriptUtil.runScript(script: .lightingRunning, env: nil, args: nil) { (output, rawData, errorMessage) in - guard errorMessage == nil else { - if errorMessage != "" { - showMessage(message: errorMessage!) - } else if let output = output { - parseLightningRunning(output: output) - } - return - } - guard let output = output else { return } - parseLightningRunning(output: output) - } - } + ScriptUtil.runScript(script: .startLightning, env: nil, args: nil) { (output, rawData, errorMessage) in guard errorMessage == nil else { - if errorMessage != "" { - showMessage(message: errorMessage!) - } + print("wtf") + isAnimating = false + showMessage(message: errorMessage!) return } + DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { + ScriptUtil.runScript(script: .lightingRunning, env: nil, args: nil) { (output, rawData, errorMessage) in + guard errorMessage == nil else { + isAnimating = false + showMessage(message: errorMessage!) + return + } + guard let output = output else { return } + parseLightningRunning(output: output) + } + } } } diff --git a/FullyNoded-Server/Views/JoinMarket.swift b/FullyNoded-Server/Views/JoinMarket.swift index eddb8acc..982ffaf2 100644 --- a/FullyNoded-Server/Views/JoinMarket.swift +++ b/FullyNoded-Server/Views/JoinMarket.swift @@ -213,7 +213,7 @@ struct JoinMarket: View { hideQrData() } if let url = url { - Link("Connect Fully Noded - Join Market", destination: URL(string: url)!) + Link("Connect Fully Noded - Join Market (locally)", destination: URL(string: url)!) .padding([.leading, .bottom]) .frame(maxWidth: .infinity, alignment: .leading) } @@ -426,20 +426,37 @@ struct JoinMarket: View { } private func startJoinMarket() { - let fm = FileManager.default - let path = "/Users/\(NSUserName())/Library/Application Support/joinmarket/wallets" - - if let wallets = try? fm.contentsOfDirectory(atPath: path) { - for wallet in wallets { - if wallet.hasSuffix(".lock") { - // Delete the .lock file - try? fm.removeItem(atPath: path + "/" + wallet) + isAnimating = true + // Ensure Bitcoin Core is running before starting JM. + BitcoinRPC.shared.command(method: "getblockchaininfo", params: [:]) { (result, error) in + guard error == nil, let result = result as? [String: Any] else { + if let error = error { + if error.contains("Could not connect to the server") { + isAnimating = false + showMessage(message: "Looks like Bitcoin Core is not running. Please start Bitcoin Core and try again.") + } else { + startNow() + } } + return } + startNow() } - isAnimating = true - env["TAG_NAME"] = UserDefaults.standard.string(forKey: "tagName") ?? "" + } + + private func startNow() { + removeLockFile() + setEnv() + launchJmStarter() + } + + private func setEnv() { + self.env["TAG_NAME"] = UserDefaults.standard.string(forKey: "tagName") ?? "" + } + + private func launchJmStarter() { ScriptUtil.runScript(script: .launchJmStarter, env: self.env, args: nil) { (output, rawData, errorMessage) in + isAnimating = false guard errorMessage == nil else { if errorMessage != "" { showMessage(message: errorMessage!) @@ -449,6 +466,22 @@ struct JoinMarket: View { } } + // If attempting to start JM daemon when a .lock file is present in /Users/you/Library/Application Support/joinmarket will result + // in an error. + private func removeLockFile() { + let fm = FileManager.default + let path = "/Users/\(NSUserName())/Library/Application Support/joinmarket/wallets" + + if let wallets = try? fm.contentsOfDirectory(atPath: path) { + for wallet in wallets { + if wallet.hasSuffix(".lock") { + // Delete the .lock file + try? fm.removeItem(atPath: path + "/" + wallet) + } + } + } + } + private func stopJoinMarket() { ScriptUtil.runScript(script: .stopJm, env: nil, args: nil) { (output, rawData, errorMessage) in guard errorMessage == nil else { diff --git a/FullyNoded-Server/Views/TaggedReleasesView.swift b/FullyNoded-Server/Views/TaggedReleasesView.swift index fca699f2..ce812ac1 100644 --- a/FullyNoded-Server/Views/TaggedReleasesView.swift +++ b/FullyNoded-Server/Views/TaggedReleasesView.swift @@ -10,6 +10,7 @@ import SwiftUI struct TaggedReleasesView: View { let timerForBitcoinInstall = Timer.publish(every: 3, on: .main, in: .common).autoconnect() + @State private var fnServerPath = "/Users/\(NSUserName())/.fullynoded" @State private var prune = false @State private var prunedAmount = "" @State private var bitcoinCoreInstallComplete = false @@ -82,8 +83,9 @@ struct TaggedReleasesView: View { .frame(maxWidth: .infinity, alignment: .leading) Text("Do not update the data directory unless you want to save your Bitcoin Core data in a custom location like an external hard drive.") - .padding([.leading]) + .padding([.bottom, .leading]) .foregroundStyle(.secondary) + .frame(maxWidth: .infinity, alignment: .leading) HStack() { Toggle("Prune", isOn: $prune) @@ -101,12 +103,17 @@ struct TaggedReleasesView: View { } if prune { TextField("", text: $prunedAmount) - Text("The amount in giga bytes the blockchain will consume.") - .foregroundStyle(.secondary) + } } .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) + if prune { + Text("The amount in giga bytes the blockchain will consume.") + .foregroundStyle(.secondary) + .padding([.leading, .trailing]) + .frame(maxWidth: .infinity, alignment: .leading) + } HStack() { if isAnimating { @@ -129,7 +136,7 @@ struct TaggedReleasesView: View { if startCheckingForBitcoinInstall { EmptyView() .onReceive(timerForBitcoinInstall) { _ in - let tempPath = "/Users/\(NSUserName())/.fullynoded/BitcoinCore/bitcoin-\(processedVersion)/bin/bitcoind" + let tempPath = "\(fnServerPath)/BitcoinCore/bitcoin-\(processedVersion)/bin/bitcoind" if FileManager.default.fileExists(atPath: tempPath) { bitcoinCoreInstallComplete = true // save new envValues! and update lightning config if it exists @@ -239,7 +246,7 @@ struct TaggedReleasesView: View { let urlSHA256SUMS = "https://bitcoincore.org/bin/bitcoin-core-\(processedVersion)/SHA256SUMS" description = "Downloading SHA256SUMS file from \(urlSHA256SUMS)" downloadTask(url: URL(string: urlSHA256SUMS)!) { data in - guard writeData(data: data, filePath: "Users/\(NSUserName())/.fullynoded/BitcoinCore/SHA256SUMS") else { return } + guard writeData(data: data, filePath: "\(fnServerPath)/BitcoinCore/SHA256SUMS") else { return } downloadSigs(processedVersion: processedVersion, arch: arch) } } @@ -248,7 +255,7 @@ struct TaggedReleasesView: View { let urlSigs = "https://bitcoincore.org/bin/bitcoin-core-\(processedVersion)/SHA256SUMS.asc" description = "Downloading the signed SHA256SUMS file from \(urlSigs)" downloadTask(url: URL(string: urlSigs)!) { data in - guard writeData(data: data, filePath: "/Users/\(NSUserName())/.fullynoded/BitcoinCore/SHA256SUMS.asc") else { return } + guard writeData(data: data, filePath: "\(fnServerPath)/BitcoinCore/SHA256SUMS.asc") else { return } let binaryName = "bitcoin-\(processedVersion)-\(arch)-apple-darwin.tar.gz" let binaryPrefix = "bitcoin-\(processedVersion)" installNow(binaryName: binaryName, version: processedVersion, prefix: binaryPrefix) @@ -287,7 +294,7 @@ struct TaggedReleasesView: View { if startDownload { isAnimating = true downloadTask(url: URL(string: macOSUrl)!) { data in - guard writeData(data: data, filePath: "Users/\(NSUserName())/.fullynoded/BitcoinCore/bitcoin-\(processedVersion)-\(arch)-apple-darwin.tar.gz") else { return } + guard writeData(data: data, filePath: "\(fnServerPath)/BitcoinCore/bitcoin-\(processedVersion)-\(arch)-apple-darwin.tar.gz") else { return } downloadSHA256SUMS(processedVersion: processedVersion, arch: arch) } } From dd19e04cb4421e7bc8127500684bfe795b3c8239 Mon Sep 17 00:00:00 2001 From: Fonta1n3 Date: Mon, 2 Dec 2024 16:46:35 -0600 Subject: [PATCH 19/22] fix: add accidentally removed icon --- .../Assets.xcassets/1024.imageset/1024.png | Bin 0 -> 45290 bytes .../1024.imageset/Contents.json | 21 ++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 FullyNoded-Server/Assets.xcassets/1024.imageset/1024.png create mode 100644 FullyNoded-Server/Assets.xcassets/1024.imageset/Contents.json diff --git a/FullyNoded-Server/Assets.xcassets/1024.imageset/1024.png b/FullyNoded-Server/Assets.xcassets/1024.imageset/1024.png new file mode 100644 index 0000000000000000000000000000000000000000..1052ab5b167bbc300f85626204800d62c78434c0 GIT binary patch literal 45290 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 hOkez$-} Date: Tue, 3 Dec 2024 12:34:27 -0600 Subject: [PATCH 20/22] fix: logo fix --- FullyNoded-Server.xcodeproj/project.pbxproj | 2 ++ .../AppIcon.appiconset/1024-mac.png | Bin 52270 -> 16082 bytes .../AppIcon.appiconset/128-mac.png | Bin 4296 -> 1810 bytes .../AppIcon.appiconset/16-mac.png | Bin 296 -> 238 bytes .../AppIcon.appiconset/256-mac.png | Bin 11016 -> 3712 bytes .../AppIcon.appiconset/32-mac.png | Bin 734 -> 530 bytes .../AppIcon.appiconset/512-mac.png | Bin 23548 -> 8100 bytes .../AppIcon.appiconset/64-mac.png | Bin 1606 -> 876 bytes 8 files changed, 2 insertions(+) diff --git a/FullyNoded-Server.xcodeproj/project.pbxproj b/FullyNoded-Server.xcodeproj/project.pbxproj index 8debdf2e..75a0304d 100644 --- a/FullyNoded-Server.xcodeproj/project.pbxproj +++ b/FullyNoded-Server.xcodeproj/project.pbxproj @@ -676,6 +676,7 @@ ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "FullyNoded-Server/Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = "Fully Noded - Server"; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; @@ -718,6 +719,7 @@ ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "FullyNoded-Server/Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = "Fully Noded - Server"; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/1024-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/1024-mac.png index 4a57d0ecea614ba858d7fee9cc5193834e58ffb1..6e2ecf7fc93993748edda7033e48fc535e90dfe6 100644 GIT binary patch literal 16082 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 PQhAPd?|I%uS^QBJ#@86+|E)ptvLU6tt?I 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 diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/128-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/128-mac.png index 45b1963d8110e0876041764b0047870ea602ba2d..2e9a12ba258864000ad877683eababe7fc76d883 100644 GIT binary patch literal 1810 zcmV+t2krP$Nk&Er2LJ$9MM6+kP&il$0000G0001g004gg06|PpNWudE00E#zYnvfS zdNZQfJ!{*xZQHhOHBPT>+qP}nwrwLL<9!!{$gGIHuI(^)d_8=k34ZrSA%Lbn*Rb*X*-!3oxc)7MNt;mo!-V!nwQyohv*w z*f$QH2C!AiGK_uvj}o2p3@vIHDTekgr{vC>7%-JFz!qOh&Xb}#o+7=Ie%KYT6|rbv zBIP8hNRnhO-8eFAB`n5zO3sT^L`nHvuTBbE0fTW~(=QaMsFG5yk0ygHEkoBc%0()= zq;kD6DolBo=@*fTFsWR(p=^t-Zq;mDamXcw-ujEBVn)3R2Dwr}1PEjr@+LY5J zrDT}=N0AW|Db4~D&f-8hQc-g{u?)0ck*A_guMb8>a~&QI zxJFLVFLWoucfBId*wO355kh4c_j@sVqJEhYSr~&k3Q-BrVlbhW6;t4~PPp~tQ&4Cd z*f18`s7Qg+?%{S!#lGQs#;eyKPt+(F6{cS!OM`%9$cu`DI< z-vEdH@5f>PYr=o_4*lEjkiY#7PToODVDePT0ZCvf`^o*q+c$Z8CvVSG92%}S6$gjg zSw#w*_77#SeJXmxZ7iRHLOZ~OT3Jki*G8c-EZ~&_YPoPz{3tSh%4b0q1{nQK`RLK> zlW`Edd8-OVztBU&1v5BOjFUE?Z{K}>rJLqURk#QpBbjAo4xoT?@Z2Co(>yoIYQ=J1YxzgjGM2lgP+Wa{6xl5o;*FKFaFv%TZ)Z zNYUx@4M%ODijC2hdQ>V%G8QCRNYAY_dK1;Gk2=e#KTCxt#m=Kh7F2QGT%$EmRWs7W z>)zod7KP`K#VS!8O7Fa+`!|_%WQz)SjWOM3SAVL(dS4W-GYjuE*e`F|cE&NgQEfB) zSW_+4d&v`@=IZeL^QW)abGd288o{FSwtLiZCYy7KwRhU@$P>;w@B9lctoQ{NoOjlV zNA17MdP~kd`M9GEvgpiO*YKl^G4^;9OgPa*6HhY9q}85e;)y1jaDws18FSPTx@zd? z%+wmqR=eF*`F6Y2Y}9Oq|2+m)P&gnW0{{SU833IDDu4ih06uLnl13yWA)zgm>u`V# ziD?bSAfH`!A#m5dce_o2nH94p;s_ zx_l(nll4OQr}aG;rEr-zc&Z6JKY)8ag6*g#9G_qhaTKyT~rW85Apz<}DC9V#v9CZBjUY9z8L01qal|EvXLL0>!j+g-QV9s>w?*K_j@bbT*_V<#kq{e_S$AP#x9cppc=}fr}SWb4kGvZ#og9o^F?R1{pKQ3=D z$LxykcL4P_u|Z&=3uGekFb36Zb7&SAcPogpob~)nk^sES)IG1N(GL5xO;l}+b*^&5 z&J$jj#2`Ir1Nj}Q(Brn)JO639uA5Azs!h1SVK`WpWqGN<8-4y}vL1~BR~HWSZGH)U zRz=PAu*2V=T|?1JQQ20u$5;c=90MUQ*cB`qV{026n6TJ<6z?p9pTii+KsFG73kGEr zdGsbKP?h>WGushqK7Esckefx-SMww=&V$KT5p4w_jH$7lesh%L{cp9}*jk6>KEu7` zI=|si_@% literal 4296 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 diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/16-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/16-mac.png index 7c506e6a690469bfaa0b991050d501c3530d919f..15992664a3b08efcc4f3dd5a324aee9a6535d1fc 100644 GIT binary patch literal 238 zcmWIYbaQ*gz`zjh>J$(bU=hIuWD5W>KNvas1bD;&d5i@zo|6`D$uD0a9P0%p(2O^h)KoS_dNr2R0JE2zzD zgmJf^!a~ZV+fc7&wsHrYtVEW$i zt>g*U1BQS9UfJw#_p7hjv99grXBnRQQ%(DF+g?Z9e;~D80RRA3MM6+kP&il$0000G0000F000jF06|PpNM8T|00D3l+qSD5 zZ$DQbBQIBfaKcc6$(Qqc5+Y&(FmoY{3&9y(E1%H$1+WIMP2GnLU_tw)4jhod_)zsG z$RPo!J~^ZS*(YbPV0=>t0UW_;Q`Ih90DhtKkMe%r)#rto09H^qAesOG0FVLzodGHk z01yBHKqe)m02Au=AHmY9&piB6HGlyA`wVB!8{Kp~WGF&E4M`IenDVr-CgWOs<2+Sd zFG|0rS1xb4)URKjZfHd5!yEH%2LD{+H6{gWKZtZsv~FC}d!PDAHfEq{hv%BtH{8yA uIXVRJy+HiOT6HV>RKcnWzICeZRDRQyHKS41!R7g#Vdh^q*gXssh#&yVH+UZa diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/256-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/256-mac.png index 8847b31f93a01056de5bb6ceedd53823457d2396..a7e79a64fd145c903b9ed3d3bba98965773ff9a4 100644 GIT binary patch literal 3712 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 C)vs&- diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/32-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/32-mac.png index 9b73b161d9f2ba9d637a93f261b6f19d87a0ad6a..d0337a82ddf84bcfaed9f590bb205ce3666f0d95 100644 GIT binary patch literal 530 zcmV+t0`2`$Nk&Er0ssJ4MM6+kP&il$0000G0000V0018V06|PpNC^P|01c2M+qP;e zbM5c$q5t^zKtqMdBFM;T2u&c>*t_76y5{a&_F3q;?-LP5#02nagaZy-G!&MQgVu7e{3L|5!= z>VSpyTYed`=%n=_fXL?y4y%=;=s7a-wJj4yRVIwC5ryQ;!e&Dkt`f<>_4_2C=Ge(q z+J|nPLIxbqkFV^^4n?O{P?=yGyp#q=$$vPwXsKm7H7QyHaGhjZyn9?!Y#eaZDQA(fHA zlZSY`%1i#Hm)vfuXi2ElIe-P)_Zp5!E`%y3*Y;MZU2#1=HYr3=40Oja;Ck> UCdhWjAgwm&p?T>o$@g%lI(N9Inwk^ys-N&?jZ2K(^Y69xwI1l1Tu zG?WRdgQd#@i8+RF&|Em+=ru!O1373d2OCcl7#u^UOELN7I}ictLS~>CK>W2 z0ERW=)94RieHtL%vV|{`{-^v*$uq zUT04I{@0o`kGqj5*13x57o3h{Q}h!7cW!gjb;(Wu|pX$1T{{24C z;vM^c|HpZ}-Dcfl?anaIt{KU~!+Afe4rD(24pPq+sy)CZ3JP$W$`dUC(fKVwe>;EM zg5(_MJ9nTjDo|+)s`rx|?G2R_pP5?D`0h$%wzf5do^Y3ofbseB|MkMcy1ex$8puEZ04z6GqyPW_ diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/512-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/512-mac.png index a6a15242adfc6c49b97758b97b6a38d6df427252..b31fb46654546faad1bed54f8a24c97f64ae31c7 100644 GIT binary patch literal 8100 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 D?!)th diff --git a/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/64-mac.png b/FullyNoded-Server/Assets.xcassets/AppIcon.appiconset/64-mac.png index 19f98dbbf20394e1124457eaf1cb97920dbb3a0b..02867535ffa20687b47e45e9b53dbd670b669288 100644 GIT binary patch literal 876 zcmV-y1C#txNk&Fw0{{S5MM6+kP&il$0000G0000#002J#06|PpNYeoT00E%8{l95D z`mVKN+evNPw$tTFW!p)Y&UR-znVD;}W83~4ve!P}Z*|t)d!1ny5fgy_7;PhGO&-R& zMm7(JNL^MIFe5h}zy9du8*jc@R#sM49#~dZR`%wbZ@hYZJ+T8QhX*T=aSf6Y?y+RAmT$OQ|AHRTEZG3bkQ1C0F}@OwHe3?f*+P ze|yy>S5?sW||WRE-<6X|sru9(F% zF*a&0Y%!qCwut|?S7RZUGKpu`VU?AM?OrvU^Z^Hn7(&*O>&t3L`h1DR0&CuX`*x)ToWutJy9Z&Dmh7c z6(+)lq4|4CL@G*BUZ1vx331q^M5H1mmFN&$2<-bxMMX;%^jQl8T8x)SMNCrDV2e5I zkdMu4KbnP{Q=-TdU4<)Va8I6b(d#ix$P4kMdKJNCN)>sk>aeOj)P>dNp+2lW4|Tb# z{oAX_UG?8yW$tQoSO5P~-QQkq?rL&Zox7?$)PUBun0HUCHVp=vJ|Aqf|m}!py_LWkeK?k#6G3;%Q|E` z`07uJ@|T;#k*$FlxbD((4X?fZPUdgF*7(BZ4TCLAHZTCtqH~WveKYUVvvW%TFv#2( zgOVF#P-;_B{0jwEP&gnm1ONcg5&)e6DnI~006uLrlSiZ@A)zK3tFV9#iD>{8;-AX< zH}9{<_ok%AN}uKZgnsAV%(Fsc_rFp#Ukt~`chmmCpUJs!|Ll6L+2E!pmHclJ&ihKR0P5x*R#MQn4N@0vZihpmKg1Nth{3&Y1G^@ z8lq-kyYe6$ti@`lG-CNwP$bYr&;S7b>oUMM+zUzjQ5HN}E2>wEF)n|Oc^Xyjk%VCS z##nY2iCBSU?;`SJUy}Hf(-e((h~(IE*wugVHSF=L#w2SLV>gHNKy8_()|FqhRoXA$ zRrU;z4B+Lzu!zn~LP>COgY^@Qz3#rrC&C3+-`*cM$V4}N2tH4JjY0-9&Jq<)W4(D% ztZbaA*xfJBmp~fH(`JjoShr_G={7lfmFRz`S>vliCZ49h1L=bY{X5zMpI?|f#31dS zvOLB>^qizZ1H=F|-}cfhOlN#X+sv{Wo|F67-ME>&Cah4UK9 z=9YSamKIbgcRCQ3ZTOXQ#Mv1jtP*KnoztomJhl{&Gtd$xfR+8?E@3F2L0>A{#Hsxc z2uXzzD+gv!G9^j|bdpA9K;4Ct@1~tq!TYe%OC~xU16Gz#r;V-_H@2wO1(OI`+6q_Q z&p;U+Ltm=Q&5L8V2a9hpf9O{|=>@(rlvJmjRW0DI^!we6V`ZSIsiL=0`X#-v zIcw?5nni#%zzMG+e?$bm4^`=~i7h9<9h{~#A7J0p6(N5zv?G9kh+s|>ORS;Jomq|J z32NFJ+X{ixV*K2CIMD@JQ-(OWHmu=cU;O<3_w(;>)xId2{s%fe?ofrk)gz&r^W*y( z`uh0Af-(QhPv*R72u7D~w+1h^x#n!A<4=FV%s)bMmf>3_kH1@#Io4gQNk93R@=n|} zixS+Kh7?|0hZ!=(^LeHy=Xt9E$`Zk z+)U|jk=4l>hSCy{&G9X2m_pkP6Fd&-BR48M$1HUp6CSf Date: Tue, 3 Dec 2024 17:24:12 -0600 Subject: [PATCH 21/22] fix: remove text from main UI for Quick Connect and put a help button instead. --- FullyNoded-Server/Views/BitcoinCore.swift | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/FullyNoded-Server/Views/BitcoinCore.swift b/FullyNoded-Server/Views/BitcoinCore.swift index 4a5cef83..dda43296 100644 --- a/FullyNoded-Server/Views/BitcoinCore.swift +++ b/FullyNoded-Server/Views/BitcoinCore.swift @@ -236,18 +236,26 @@ struct BitcoinCore: View { ) VStack() { - Label("Quick Connect", systemImage: "qrcode") - .padding([.leading]) - .frame(maxWidth: .infinity, alignment: .leading) + HStack() { + Label("Quick Connect", systemImage: "qrcode") + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .leading) + Spacer() + Button { + showMessage(message: "The Quick Connect QR exports your rpc hostname (an onion or localhost) and the rpc port (combined these make up your nodes rpc address) which is required for FN to connect.\n\nThis QR does *NOT* include the FN-Server RPC credentials (it includes a dummy rpc user and password for security).\n\nYou must export and authorize your rpc user from FN mobile apps to FN-Server to complete your connection.\n\nTo do this: In FN navigate to Node Manager > + > Scan QR > update the rpc password in Node Credentials > Save the node > Export the rpcauth text from FN and use the below text field to add it to your bitcoin.conf.") + } label: { + Image(systemName: "questionmark.circle") + } + .padding([.trailing]) + } + Button("Connect Fully Noded", systemImage: "qrcode") { connectFN() } .padding([.leading, .trailing]) .frame(maxWidth: .infinity, alignment: .leading) - Text("Exports your onion (Tor) rpc hostname and rpc port (your nodes address) which is required for FN to connect. This QR does *NOT* include the FN-Server RPC credentials (it includes a dummy rpc user and password). You must export and authorize your rpc user from FN to FN-Server to complete your connection. To do this: In FN navigate to Node Manager > + > Scan QR > update the rpc password in Node Credentials > Save the node > Export the rpcauth text from FN and use the below button to authorize your FN rpc user.") - .foregroundStyle(.secondary) - .padding([.leading, .bottom, .trailing]) + HStack() { Text("Authorize an additional RPC user:") From a1bd48a955c3198834c2249f2116a1fabe656da1 Mon Sep 17 00:00:00 2001 From: Fonta1n3 Date: Wed, 4 Dec 2024 13:01:41 -0600 Subject: [PATCH 22/22] feat: set mainnet to default, add help view --- FullyNoded-Server.xcodeproj/project.pbxproj | 12 ++++-- FullyNoded-Server/Views/BitcoinCore.swift | 6 +-- FullyNoded-Server/Views/ContentView.swift | 20 +++++++-- FullyNoded-Server/Views/Help.swift | 41 +++++++++++++++++++ FullyNoded-Server/Views/JoinMarket.swift | 4 +- .../Views/JoinMarketTaggedReleases.swift | 5 +-- 6 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 FullyNoded-Server/Views/Help.swift diff --git a/FullyNoded-Server.xcodeproj/project.pbxproj b/FullyNoded-Server.xcodeproj/project.pbxproj index 75a0304d..ea02d8f5 100644 --- a/FullyNoded-Server.xcodeproj/project.pbxproj +++ b/FullyNoded-Server.xcodeproj/project.pbxproj @@ -76,6 +76,7 @@ 0AD7BE212CC2B1F100428D02 /* StartJm.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AD7BE202CC2B1F100428D02 /* StartJm.command */; }; 0AD7BE232CC2B47400428D02 /* LaunchJMStarter.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AD7BE222CC2B47400428D02 /* LaunchJMStarter.command */; }; 0AD7BE252CC2BCEF00428D02 /* StopJm.command in Resources */ = {isa = PBXBuildFile; fileRef = 0AD7BE242CC2BCEF00428D02 /* StopJm.command */; }; + 0AF736212D00D0900026FE0A /* Help.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF736202D00D0900026FE0A /* Help.swift */; }; 593A891F2CE28334001504F0 /* IncreaseGapLimit.command in Resources */ = {isa = PBXBuildFile; fileRef = 593A891E2CE28334001504F0 /* IncreaseGapLimit.command */; }; 593A89212CE28400001504F0 /* LaunchIncreaseGapLimit.command in Resources */ = {isa = PBXBuildFile; fileRef = 593A89202CE28400001504F0 /* LaunchIncreaseGapLimit.command */; }; 593A89232CE511F8001504F0 /* FNIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 593A89222CE511F8001504F0 /* FNIcon.swift */; }; @@ -158,6 +159,7 @@ 0AD7BE202CC2B1F100428D02 /* StartJm.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = StartJm.command; sourceTree = ""; }; 0AD7BE222CC2B47400428D02 /* LaunchJMStarter.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = LaunchJMStarter.command; sourceTree = ""; }; 0AD7BE242CC2BCEF00428D02 /* StopJm.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = StopJm.command; sourceTree = ""; }; + 0AF736202D00D0900026FE0A /* Help.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Help.swift; sourceTree = ""; }; 1B8BA5D0924A1AE2EC951616 /* Pods-FullyNoded-Server.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FullyNoded-Server.debug.xcconfig"; path = "Target Support Files/Pods-FullyNoded-Server/Pods-FullyNoded-Server.debug.xcconfig"; sourceTree = ""; }; 593A891E2CE28334001504F0 /* IncreaseGapLimit.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = IncreaseGapLimit.command; sourceTree = ""; }; 593A89202CE28400001504F0 /* LaunchIncreaseGapLimit.command */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = LaunchIncreaseGapLimit.command; sourceTree = ""; }; @@ -192,6 +194,7 @@ 0AD7BE0E2CB980D500428D02 /* JoinMarketTaggedReleases.swift */, 0AD7BE162CBD8DA000428D02 /* JoinMarket.swift */, 593A89222CE511F8001504F0 /* FNIcon.swift */, + 0AF736202D00D0900026FE0A /* Help.swift */, ); path = Views; sourceTree = ""; @@ -506,6 +509,7 @@ files = ( 0A573E1F2CADC5CF00899F84 /* Torrc.swift in Sources */, 0AD7BE0F2CB980D500428D02 /* JoinMarketTaggedReleases.swift in Sources */, + 0AF736212D00D0900026FE0A /* Help.swift in Sources */, 0AD7BE192CBD919600428D02 /* JMRPC.swift in Sources */, 0AA6924B2C7F89E800366192 /* Script.swift in Sources */, 0AD7BE0D2CB97F4100428D02 /* LatestJoinMarketRelease.swift in Sources */, @@ -676,7 +680,7 @@ ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "FullyNoded-Server/Info.plist"; - INFOPLIST_KEY_CFBundleDisplayName = "Fully Noded - Server"; + INFOPLIST_KEY_CFBundleDisplayName = "FN Server - v0.0.1 Beta"; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; @@ -691,7 +695,7 @@ LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 0.0.1; PRODUCT_BUNDLE_IDENTIFIER = "com.dentonllc.FullyNoded-Server"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; @@ -719,7 +723,7 @@ ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "FullyNoded-Server/Info.plist"; - INFOPLIST_KEY_CFBundleDisplayName = "Fully Noded - Server"; + INFOPLIST_KEY_CFBundleDisplayName = "FN Server - v0.0.1 Beta"; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; @@ -734,7 +738,7 @@ LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 0.0.1; PRODUCT_BUNDLE_IDENTIFIER = "com.dentonllc.FullyNoded-Server"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; diff --git a/FullyNoded-Server/Views/BitcoinCore.swift b/FullyNoded-Server/Views/BitcoinCore.swift index dda43296..0403f48e 100644 --- a/FullyNoded-Server/Views/BitcoinCore.swift +++ b/FullyNoded-Server/Views/BitcoinCore.swift @@ -514,7 +514,7 @@ struct BitcoinCore: View { } private func initialLoad() { - selectedChain = UserDefaults.standard.string(forKey: "chain") ?? "signet" + selectedChain = UserDefaults.standard.string(forKey: "chain") ?? "main" DataManager.retrieve(entityName: .bitcoinEnv) { env in guard let env = env else { return } let envValues = BitcoinEnvValues(dictionary: env) @@ -535,7 +535,7 @@ struct BitcoinCore: View { return } var onionHost = "" - let chain = UserDefaults.standard.string(forKey: "chain") ?? "signet" + let chain = UserDefaults.standard.string(forKey: "chain") ?? "main" switch chain { case "main": @@ -569,7 +569,7 @@ struct BitcoinCore: View { let url = "http://xxx:xxx@\(onionHost)" qrImage = url.qrQode - let port = UserDefaults.standard.object(forKey: "port") as? String ?? "38332" + let port = UserDefaults.standard.object(forKey: "port") as? String ?? "8332" self.fullyNodedUrl = "btcrpc://xxx:xxx@localhost:\(port)" self.unifyUrl = "unify://xxx:xxx@localhost:\(port)" } diff --git a/FullyNoded-Server/Views/ContentView.swift b/FullyNoded-Server/Views/ContentView.swift index c75d1b96..f1ca705b 100644 --- a/FullyNoded-Server/Views/ContentView.swift +++ b/FullyNoded-Server/Views/ContentView.swift @@ -57,6 +57,7 @@ struct ContentView: View { private let coreLightning = Service(name: "Core Lightning", id: UUID()) private let joinMarket = Service(name: "Join Market", id: UUID()) private let tor = Service(name: "Tor", id: UUID()) + private let help = Service(name: "Help", id: UUID()) var body: some View { @@ -144,6 +145,8 @@ struct ContentView: View { } .frame(maxWidth: .infinity, alignment: .leading) Spacer() + } else if service.name == "Help" { + Help() } } label: { HStack() { @@ -230,7 +233,18 @@ struct ContentView: View { self.torRunning = TorClient.sharedInstance.state == .connected } } - Text(service.name) + + if service.name == "Help" { + Image(systemName: "questionmark.circle") + .foregroundStyle(.secondary) + Text(service.name) + .foregroundStyle(.secondary) + } else { + Text(service.name) + } + + + } } @@ -389,7 +403,7 @@ struct ContentView: View { "CHAIN": self.bitcoinEnvValues.chain ] - services = [bitcoinCore, coreLightning, joinMarket, tor] + services = [bitcoinCore, coreLightning, joinMarket, tor, help] checkForBitcoin() } @@ -407,7 +421,7 @@ struct ContentView: View { "CHAIN": self.bitcoinEnvValues.chain ] - services = [bitcoinCore, coreLightning, joinMarket, tor] + services = [bitcoinCore, coreLightning, joinMarket, tor, help] checkForBitcoin() } } diff --git a/FullyNoded-Server/Views/Help.swift b/FullyNoded-Server/Views/Help.swift new file mode 100644 index 00000000..44cceaaa --- /dev/null +++ b/FullyNoded-Server/Views/Help.swift @@ -0,0 +1,41 @@ +// +// Help.swift +// FullyNoded-Server +// +// Created by Peter Denton on 12/4/24. +// + +import SwiftUI + +struct Help: View { + var body: some View { + VStack() { + Text("Need support?") + .frame(maxWidth: .infinity, alignment: .topLeading) + .padding([.leading, .top]) + Link("Let us know about an issue, bug, feature request or general comments here.", destination: URL(string: "https://github.com/Fonta1n3/FullyNoded-Server/issues/new")!) + .padding([.leading, .bottom]) + .frame(maxWidth: .infinity, alignment: .topLeading) + Text("Visit our website") + .frame(maxWidth: .infinity, alignment: .topLeading) + .padding([.leading]) + Link("www.FullyNoded.app", destination: URL(string: "https://www.FullyNoded.app")!) + .padding([.leading, .bottom]) + .frame(maxWidth: .infinity, alignment: .topLeading) + Text("Come chat") + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .topLeading) + Link("Join the Telegram", destination: URL(string: "https://t.me/FullyNoded")!) + .padding([.leading]) + .frame(maxWidth: .infinity, alignment: .topLeading) + Link("Join the Discord", destination: URL(string: "https://discord.gg/TVf2zb9x")!) + .frame(maxWidth: .infinity, alignment: .topLeading) + .padding([.leading]) + Spacer() + } + } +} + +#Preview { + Help() +} diff --git a/FullyNoded-Server/Views/JoinMarket.swift b/FullyNoded-Server/Views/JoinMarket.swift index 982ffaf2..69fe9f7f 100644 --- a/FullyNoded-Server/Views/JoinMarket.swift +++ b/FullyNoded-Server/Views/JoinMarket.swift @@ -312,8 +312,8 @@ struct JoinMarket: View { } private func configureJm() { - var chain = UserDefaults.standard.object(forKey: "chain") as? String ?? "signet" - let port = UserDefaults.standard.object(forKey: "port") as? String ?? "38332" + var chain = UserDefaults.standard.object(forKey: "chain") as? String ?? "main" + let port = UserDefaults.standard.object(forKey: "port") as? String ?? "8332" switch chain { case "main": chain = "mainnet" case "regtest": chain = "testnet" diff --git a/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift b/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift index 1578c671..746d25a0 100644 --- a/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift +++ b/FullyNoded-Server/Views/JoinMarketTaggedReleases.swift @@ -115,9 +115,8 @@ struct JoinMarketTaggedReleasesView: View { private func configureJm() { - print("configureJm") - var chain = UserDefaults.standard.object(forKey: "chain") as? String ?? "signet" - let port = UserDefaults.standard.object(forKey: "port") as? String ?? "38332" + var chain = UserDefaults.standard.object(forKey: "chain") as? String ?? "main" + let port = UserDefaults.standard.object(forKey: "port") as? String ?? "8332" switch chain { case "main": chain = "mainnet" case "regtest": chain = "testnet"