Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions Bitkit/BitkitApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,30 @@
import SwiftUI

class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
UNUserNotificationCenter.current().delegate = self
return true
}
}

extension AppDelegate : UNUserNotificationCenterDelegate {
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
{
let userInfo = notification.request.content.userInfo

Logger.debug(userInfo, context: "push notification received while app is in the foreground")

//If we want to display the native notification to the user while the app is open we need to call this with options
//Unlikely we will need to as the background operation would have been aborted and we would have nothint to show
// If we want to display the native notification to the user while the app is open we need to call this with options
// Unlikely we will need to as the background operation would have been aborted and we would have nothint to show
completionHandler([])
// completionHandler([[.banner, .badge, .sound]])
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Task {
//If this fails we can try again later as the token is cached here
// If this fails we can try again later as the token is cached here
try? await BlocktankService.shared.registerDevice(deviceToken: deviceToken.map { String(format: "%02hhx", $0) }.joined())
}
}
Expand All @@ -43,7 +44,7 @@ extension AppDelegate : UNUserNotificationCenterDelegate {
let userInfo = response.notification.request.content.userInfo

Logger.debug(userInfo, context: "app opened from push notification")
//TODO: if user tapped on an incoming tx we should open it on that tx view
// TODO: if user tapped on an incoming tx we should open it on that tx view
completionHandler()
}
}
Expand Down
37 changes: 19 additions & 18 deletions Bitkit/Constants/Env.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,31 @@
// Created by Jason van den Berg on 2024/07/01.
//

import Foundation
import BitcoinDevKit
import Foundation

struct Env {
enum Env {
static let isPreview = ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1"
static let isTestFlight = Bundle.main.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt"
static let isUnitTest = ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"] != nil

//{Team ID}.{Keychain Group}
// {Team ID}.{Keychain Group}
static let keychainGroup = "KYH47R284B.to.bitkit"

#if targetEnvironment(simulator)
static let isSim = true
#else
static let isSim = false
#endif
#if targetEnvironment(simulator)
static let isSim = true
#else
static let isSim = false
#endif

#if DEBUG
static let isDebug = true
#else
static let isDebug = false
#endif
#if DEBUG
static let isDebug = true
#else
static let isDebug = false
#endif

//MARK: wallet services
// MARK: wallet services

static let network: WalletNetwork = .regtest
static let defaultWalletWordCount: WordCount = .words12
static let onchainWalletStopGap = UInt64(20)
Expand All @@ -37,8 +38,8 @@ struct Env {
switch network {
case .regtest:
return "https://electrs-regtest.synonym.to"
//cargo run --release --bin electrs -- -vvv --jsonrpc-import --daemon-rpc-addr 127.0.0.1:18443 --cookie polaruser:polarpass
//return "http://127.0.0.1:3000"
// cargo run --release --bin electrs -- -vvv --jsonrpc-import --daemon-rpc-addr 127.0.0.1:18443 --cookie polaruser:polarpass
// return "http://127.0.0.1:3000"
case .bitcoin:
fatalError("Bitcoin network not implemented")
case .testnet:
Expand All @@ -49,7 +50,7 @@ struct Env {
}

static var appStorageUrl: URL {
//App group so files can be shared with extensions
// App group so files can be shared with extensions
guard let documentsDirectory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.bitkit") else {
fatalError("Could not find documents directory")
}
Expand Down Expand Up @@ -108,7 +109,7 @@ struct Env {
switch network {
case .regtest:
return [
//Staging Blocktank node
// Staging Blocktank node
.init(nodeId: "03b9a456fb45d5ac98c02040d39aec77fa3eeb41fd22cf40b862b393bcfc43473a", address: "35.233.47.252:9400")
]
case .bitcoin:
Expand Down
4 changes: 2 additions & 2 deletions Bitkit/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import SwiftUI

struct ContentView: View {
@StateObject var viewModel = ViewModel.shared

var body: some View {
VStack {
if viewModel.walletExists == nil {
Expand All @@ -29,7 +29,7 @@ struct ContentView: View {
.onAppear {
viewModel.setWalletExistsState()
}
.handleLightningStateOnScenePhaseChange() //Will stop and start LN node as needed
.handleLightningStateOnScenePhaseChange() // Will stop and start LN node as needed
}
}

Expand Down
4 changes: 2 additions & 2 deletions Bitkit/Extensions/HexBytes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ extension Data {
extension StringProtocol {
var hexaData: Data { .init(hexa) }
var hexaBytes: [UInt8] { .init(hexa) }

private var hexa: UnfoldSequence<UInt8, Index> {
sequence(state: startIndex) { startIndex in
guard startIndex < endIndex else { return nil }
let endIndex = index(startIndex, offsetBy: 2, limitedBy: endIndex) ?? endIndex
defer { startIndex = endIndex }
return UInt8(self[startIndex..<endIndex], radix: 16)
return UInt8(self[startIndex ..< endIndex], radix: 16)
}
}
}
8 changes: 4 additions & 4 deletions Bitkit/Models/LnPeer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ import Foundation
struct LnPeer {
let nodeId: String
let address: String

init(nodeId: String, address: String) {
self.nodeId = nodeId
self.address = address
}

init(connection: String) throws {
let parts = connection.split(separator: "@")
guard parts.count == 2 else {
// throw LnPeerError.invalidConnection
//TODO throw custom error
// TODO: throw custom error
fatalError("Invalid connection")
}

nodeId = String(parts[0])
address = String(parts[1])
}
Expand Down
8 changes: 4 additions & 4 deletions Bitkit/Models/WalletNetwork.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
// Created by Jason van den Berg on 2024/07/01.
//

import BitcoinDevKit
import Foundation
import LDKNode
import BitcoinDevKit

enum WalletNetwork {
case regtest
case bitcoin
case testnet
case signet

var displayName: String {
switch self {
case .regtest:
Expand All @@ -27,7 +27,7 @@ enum WalletNetwork {
return "Signet"
}
}

var ldkNetwork: LDKNode.Network {
switch self {
case .regtest:
Expand All @@ -40,7 +40,7 @@ enum WalletNetwork {
return .signet
}
}

var bdkNetwork: BitcoinDevKit.Network {
switch self {
case .regtest:
Expand Down
17 changes: 9 additions & 8 deletions Bitkit/Services/BlocktankService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class BlocktankService {
private init() {}

func registerDevice(deviceToken: String) async throws {
UserDefaults.standard.setValue(deviceToken, forKey: "deviceToken") //Token cached so we can retry registration if there are any issues
UserDefaults.standard.setValue(deviceToken, forKey: "deviceToken") // Token cached so we can retry registration if there are any issues

guard let nodeId = LightningService.shared.nodeId else {
throw AppError(serviceError: .nodeNotStarted)
Expand All @@ -26,8 +26,8 @@ class BlocktankService {
let signature = try await LightningService.shared.sign(message: messageToSign)

let publicKey = "03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f"
//TODO: use real public key like below to enable decryption of the push notification payload so we know which node event to wait for
//https://github.com/SeverinAlexB/ln-verifymessagejs/blob/master/src/shared_secret.ts
// TODO: use real public key like below to enable decryption of the push notification payload so we know which node event to wait for
// https://github.com/SeverinAlexB/ln-verifymessagejs/blob/master/src/shared_secret.ts

let params = [
"deviceToken": deviceToken,
Expand All @@ -38,13 +38,13 @@ class BlocktankService {
"nodeId": nodeId,
"isoTimestamp": isoTimestamp,
"signature": signature
] as [String : Any]
] as [String: Any]

let result = try await postRequest("notifications/api/device", params)
Logger.info("Device registered: \(String(data: result, encoding: .utf8) ?? "")")
}

//TODO: token is cached above so occasionally check the status of the device with Blocktank. If not registered but we have a token then retry registration.
// TODO: token is cached above so occasionally check the status of the device with Blocktank. If not registered but we have a token then retry registration.

func selfTest() async throws {
guard let deviceToken = UserDefaults.standard.string(forKey: "deviceToken") else {
Expand All @@ -59,7 +59,7 @@ class BlocktankService {
"type": "incomingHtlc",
"payload": ["secretMessage": "hello"]
]
] as [String : Any]
] as [String: Any]

let result = try await postRequest("notifications/api/device/\(deviceToken)/test-notification", params)
Logger.info("Notification sent to self: \(String(data: result, encoding: .utf8) ?? "")")
Expand Down Expand Up @@ -91,7 +91,7 @@ extension BlocktankService {
Logger.error(responseBody)
}

throw BlocktankError.invalidResponse //TODO: add error status code
throw BlocktankError.invalidResponse // TODO: add error status code
}

return data
Expand All @@ -109,7 +109,8 @@ extension BlocktankService {
let (data, response) = try await URLSession.shared.data(for: request)

guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
(200...299).contains(httpResponse.statusCode)
else {
throw BlocktankError.invalidResponse
}

Expand Down
Loading