Skip to content

Commit

Permalink
Use ldk-node instead of BDK (#13)
Browse files Browse the repository at this point in the history
* Include LDK Node package, skeleton manager class

* WIP

* make Node published, move build to start()

* Create node in new flow, listen for node to switch to home

* Sync when homescreen opens

* Remove unused blocksocket

* Sync on dispatchQueue

* TEMP: save node seed in keychain and check on start

* Use ldknode for onchain address

* Use ldknode for total and spendable onchain balance

* Remove bdkmanager, ldkmanager

* Remove bdk-swift package

* Move extractNodeSeed to backupmanager

* Tweak temp spacing

* Refactor

* Refactor

* Refactor listeningAddress to one default

* Replace default url

* Use local branch of ldk-node to allow 0conf channels

lightningdevkit/ldk-node#69

* Test Voltage wrapped invoice creation, new file LSP.swift

* Print node id and original invoice for debugging

* Replace request QR code with UnifiedQRCode

* Use amount in lightning invoice (not yet for onchain as it needs conversion)

* Include onchain amount in unified request, extensions for converting from sats to bitcoin

* Replace with official LDKNode package

* Use static file directory path, previous caused errors

* Reduce invoice expiry time to less than 10 minutes set by Voltage

* Refactor BackupManager, use mnemonic with ldkNode (not working)

* Revert to filemanager path

* Update readme
  • Loading branch information
danielnordh authored Jul 13, 2023
1 parent ba74a93 commit 815e2b8
Show file tree
Hide file tree
Showing 24 changed files with 446 additions and 471 deletions.
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,17 @@ Intended as a good starting point for new bitcoin wallet projects.
This is WORK IN PROGRESS.

### Dependencies
- Bitcoin Development Kit - to interact with the bitcoin blockchain via Electrum or Esplora APIs
- Lightning Development Kit - not yet implemented
- LDK Node - to handle both onchain and lightning bitcoin needs
- KeychainAccess - to store encrypted data in keychain

### Implemented features
- Create new HD segwit/bech32 wallets with BIP84 derivation paths (12 word recovery-phrase, no pass-phrase)
- Import wallet from recovery phrase (12 or 24 word recovery-phrase, no pass-phrase)
- Backup encrypted key info to iOS keychain
- Create new LDK Node started from mnemonic (12 words, no pass-phrase)
- Backup encrypted mnemonic info to iOS keychain
- Start from said backup if present

### Wallet types
Currently only supports single key HD segwit/bech32 wallets with BIP84 derivation paths
Descriptors created by the app will look like: `wpkh([extended private key]/84'/1'/0'/0/*)`

### Backup schemes
Currently only encrypted backup to the iOS keychain is supported. At the moment it uses a static encryption key, but the plan is to replace this with a per-user generated encryption key based on their apple account.
Other schemes will be considered in the future.
Currently only encrypted backup to the iOS keychain is supported. At the moment it uses a static encryption key.
71 changes: 29 additions & 42 deletions dailywallet.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
6523F6762A01132200CE31C3 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6523F6752A01132200CE31C3 /* Extensions.swift */; };
6541A524282E69600051B2B0 /* DailyWalletApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6541A523282E69600051B2B0 /* DailyWalletApp.swift */; };
6541A526282E69600051B2B0 /* StartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6541A525282E69600051B2B0 /* StartView.swift */; };
6541A528282E69620051B2B0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6541A527282E69620051B2B0 /* Assets.xcassets */; };
Expand All @@ -17,16 +18,15 @@
6541A544282E71B60051B2B0 /* CreateWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6541A541282E71B60051B2B0 /* CreateWalletView.swift */; };
6541A545282E71B60051B2B0 /* ImportWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6541A542282E71B60051B2B0 /* ImportWalletView.swift */; };
6541A546282E71B60051B2B0 /* AdvancedCreateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6541A543282E71B60051B2B0 /* AdvancedCreateView.swift */; };
6541A5512837E84E0051B2B0 /* LDKManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6541A5502837E84E0051B2B0 /* LDKManager.swift */; };
658FA38828CB5CEF00196EF9 /* WalletUI in Frameworks */ = {isa = PBXBuildFile; productRef = 658FA38728CB5CEF00196EF9 /* WalletUI */; };
658FA38A28CB924F00196EF9 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658FA38928CB924F00196EF9 /* SettingsView.swift */; };
658FA38C28CB931300196EF9 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658FA38B28CB931200196EF9 /* HomeView.swift */; };
658FA38E28CB950A00196EF9 /* ActivityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 658FA38D28CB950A00196EF9 /* ActivityView.swift */; };
65A47D972A4EE88F00D57EF9 /* LDKNode in Frameworks */ = {isa = PBXBuildFile; productRef = 65A47D962A4EE88F00D57EF9 /* LDKNode */; };
65A85E6628F01D8A00845AE2 /* RequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65A85E6528F01D8A00845AE2 /* RequestView.swift */; };
65A85E6828F01F5600845AE2 /* SendView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65A85E6728F01F5500845AE2 /* SendView.swift */; };
65C336C528410A2C0087B77D /* BlockSocket in Frameworks */ = {isa = PBXBuildFile; productRef = 65C336C428410A2C0087B77D /* BlockSocket */; };
65FFFAFF29644B9600C7E8F9 /* BDKManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65FFFAFE29644B9600C7E8F9 /* BDKManager.swift */; };
65FFFB02296451AA00C7E8F9 /* BitcoinDevKit in Frameworks */ = {isa = PBXBuildFile; productRef = 65FFFB01296451AA00C7E8F9 /* BitcoinDevKit */; };
65E0D8EA29FFD8BF003F45C8 /* LSP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E0D8E929FFD8BF003F45C8 /* LSP.swift */; };
65EA783529F1431E00384706 /* LDKNodeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EA783429F1431E00384706 /* LDKNodeManager.swift */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
Expand All @@ -43,6 +43,7 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
6523F6752A01132200CE31C3 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
6541A520282E69600051B2B0 /* Daily Wallet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Daily Wallet.app"; sourceTree = BUILT_PRODUCTS_DIR; };
6541A523282E69600051B2B0 /* DailyWalletApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyWalletApp.swift; sourceTree = "<group>"; };
6541A525282E69600051B2B0 /* StartView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartView.swift; sourceTree = "<group>"; };
Expand All @@ -55,23 +56,22 @@
6541A541282E71B60051B2B0 /* CreateWalletView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateWalletView.swift; sourceTree = "<group>"; };
6541A542282E71B60051B2B0 /* ImportWalletView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletView.swift; sourceTree = "<group>"; };
6541A543282E71B60051B2B0 /* AdvancedCreateView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdvancedCreateView.swift; sourceTree = "<group>"; };
6541A5502837E84E0051B2B0 /* LDKManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LDKManager.swift; sourceTree = "<group>"; };
658FA38928CB924F00196EF9 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
658FA38B28CB931200196EF9 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = "<group>"; };
658FA38D28CB950A00196EF9 /* ActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityView.swift; sourceTree = "<group>"; };
65A85E6528F01D8A00845AE2 /* RequestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestView.swift; sourceTree = "<group>"; };
65A85E6728F01F5500845AE2 /* SendView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendView.swift; sourceTree = "<group>"; };
65FFFAFE29644B9600C7E8F9 /* BDKManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BDKManager.swift; sourceTree = "<group>"; };
65E0D8E929FFD8BF003F45C8 /* LSP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LSP.swift; sourceTree = "<group>"; };
65EA783429F1431E00384706 /* LDKNodeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LDKNodeManager.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
6541A51D282E69600051B2B0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
65FFFB02296451AA00C7E8F9 /* BitcoinDevKit in Frameworks */,
65A47D972A4EE88F00D57EF9 /* LDKNode in Frameworks */,
6541A53E282E70C20051B2B0 /* KeychainAccess in Frameworks */,
65C336C528410A2C0087B77D /* BlockSocket in Frameworks */,
658FA38828CB5CEF00196EF9 /* WalletUI in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -82,6 +82,7 @@
6541A517282E69600051B2B0 = {
isa = PBXGroup;
children = (
65E7B48929F65EA800E3A672 /* Packages */,
6541A534282E6A960051B2B0 /* README.md */,
6541A535282E6B710051B2B0 /* .gitignore */,
6541A522282E69600051B2B0 /* dailywallet */,
Expand All @@ -104,8 +105,7 @@
6541A531282E69DD0051B2B0 /* App */,
6541A532282E69EE0051B2B0 /* Views */,
6541A539282E6FE50051B2B0 /* Backup */,
65FFFAFD29644B7E00C7E8F9 /* BDK */,
6541A54F2837E8320051B2B0 /* LDK */,
6541A54F2837E8320051B2B0 /* Bitcoin */,
6541A533282E69FF0051B2B0 /* Resources */,
6541A529282E69620051B2B0 /* Preview Content */,
);
Expand Down Expand Up @@ -168,12 +168,14 @@
path = Onboarding;
sourceTree = "<group>";
};
6541A54F2837E8320051B2B0 /* LDK */ = {
6541A54F2837E8320051B2B0 /* Bitcoin */ = {
isa = PBXGroup;
children = (
6541A5502837E84E0051B2B0 /* LDKManager.swift */,
65EA783429F1431E00384706 /* LDKNodeManager.swift */,
65E0D8E929FFD8BF003F45C8 /* LSP.swift */,
6523F6752A01132200CE31C3 /* Extensions.swift */,
);
path = LDK;
path = Bitcoin;
sourceTree = "<group>";
};
6541A5522837E91F0051B2B0 /* Frameworks */ = {
Expand All @@ -192,12 +194,11 @@
path = Payments;
sourceTree = "<group>";
};
65FFFAFD29644B7E00C7E8F9 /* BDK */ = {
65E7B48929F65EA800E3A672 /* Packages */ = {
isa = PBXGroup;
children = (
65FFFAFE29644B9600C7E8F9 /* BDKManager.swift */,
);
path = BDK;
name = Packages;
sourceTree = "<group>";
};
/* End PBXGroup section */
Expand All @@ -219,9 +220,8 @@
name = dailywallet;
packageProductDependencies = (
6541A53D282E70C20051B2B0 /* KeychainAccess */,
65C336C428410A2C0087B77D /* BlockSocket */,
658FA38728CB5CEF00196EF9 /* WalletUI */,
65FFFB01296451AA00C7E8F9 /* BitcoinDevKit */,
65A47D962A4EE88F00D57EF9 /* LDKNode */,
);
productName = dailywallet;
productReference = 6541A520282E69600051B2B0 /* Daily Wallet.app */;
Expand Down Expand Up @@ -253,9 +253,8 @@
mainGroup = 6541A517282E69600051B2B0;
packageReferences = (
6541A53C282E70C20051B2B0 /* XCRemoteSwiftPackageReference "KeychainAccess" */,
65C336C328410A2C0087B77D /* XCRemoteSwiftPackageReference "blocksocket-swift" */,
658FA38628CB5CEF00196EF9 /* XCRemoteSwiftPackageReference "WalletUI" */,
65FFFB00296451AA00C7E8F9 /* XCRemoteSwiftPackageReference "bdk-swift" */,
65A47D952A4EE88E00D57EF9 /* XCRemoteSwiftPackageReference "ldk-node" */,
);
productRefGroup = 6541A521282E69600051B2B0 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -285,14 +284,15 @@
files = (
658FA38C28CB931300196EF9 /* HomeView.swift in Sources */,
6541A526282E69600051B2B0 /* StartView.swift in Sources */,
6541A5512837E84E0051B2B0 /* LDKManager.swift in Sources */,
65FFFAFF29644B9600C7E8F9 /* BDKManager.swift in Sources */,
6541A53B282E70590051B2B0 /* BackupManager.swift in Sources */,
658FA38A28CB924F00196EF9 /* SettingsView.swift in Sources */,
6541A546282E71B60051B2B0 /* AdvancedCreateView.swift in Sources */,
6541A544282E71B60051B2B0 /* CreateWalletView.swift in Sources */,
6541A524282E69600051B2B0 /* DailyWalletApp.swift in Sources */,
65E0D8EA29FFD8BF003F45C8 /* LSP.swift in Sources */,
65EA783529F1431E00384706 /* LDKNodeManager.swift in Sources */,
65A85E6628F01D8A00845AE2 /* RequestView.swift in Sources */,
6523F6762A01132200CE31C3 /* Extensions.swift in Sources */,
6541A545282E71B60051B2B0 /* ImportWalletView.swift in Sources */,
6541A540282E718D0051B2B0 /* PaymentsView.swift in Sources */,
65A85E6828F01F5600845AE2 /* SendView.swift in Sources */,
Expand Down Expand Up @@ -427,7 +427,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"dailywallet/Preview Content\"";
DEVELOPMENT_TEAM = 8DAB7BVU34;
DEVELOPMENT_TEAM = V9277T6GRS;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
Expand Down Expand Up @@ -459,7 +459,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"dailywallet/Preview Content\"";
DEVELOPMENT_TEAM = 8DAB7BVU34;
DEVELOPMENT_TEAM = V9277T6GRS;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
Expand Down Expand Up @@ -523,22 +523,14 @@
kind = branch;
};
};
65C336C328410A2C0087B77D /* XCRemoteSwiftPackageReference "blocksocket-swift" */ = {
65A47D952A4EE88E00D57EF9 /* XCRemoteSwiftPackageReference "ldk-node" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/bdgwallet/blocksocket-swift";
repositoryURL = "https://github.com/lightningdevkit/ldk-node";
requirement = {
branch = main;
kind = branch;
};
};
65FFFB00296451AA00C7E8F9 /* XCRemoteSwiftPackageReference "bdk-swift" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/bitcoindevkit/bdk-swift";
requirement = {
kind = exactVersion;
version = 0.26.0;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
Expand All @@ -552,15 +544,10 @@
package = 658FA38628CB5CEF00196EF9 /* XCRemoteSwiftPackageReference "WalletUI" */;
productName = WalletUI;
};
65C336C428410A2C0087B77D /* BlockSocket */ = {
isa = XCSwiftPackageProductDependency;
package = 65C336C328410A2C0087B77D /* XCRemoteSwiftPackageReference "blocksocket-swift" */;
productName = BlockSocket;
};
65FFFB01296451AA00C7E8F9 /* BitcoinDevKit */ = {
65A47D962A4EE88F00D57EF9 /* LDKNode */ = {
isa = XCSwiftPackageProductDependency;
package = 65FFFB00296451AA00C7E8F9 /* XCRemoteSwiftPackageReference "bdk-swift" */;
productName = BitcoinDevKit;
package = 65A47D952A4EE88E00D57EF9 /* XCRemoteSwiftPackageReference "ldk-node" */;
productName = LDKNode;
};
/* End XCSwiftPackageProductDependency section */
};
Expand Down
26 changes: 10 additions & 16 deletions dailywallet/App/DailyWalletApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,25 @@
//

import SwiftUI
import BitcoinDevKit
import LDKNode

@main
struct DailyWalletApp: App {
@ObservedObject var bdkManager: BDKManager
@ObservedObject var ldkNodeManager: LDKNodeManager
@ObservedObject var backupManager: BackupManager

init() {
bdkManager = BDKManager(network: Network.testnet)
ldkNodeManager = LDKNodeManager(network: Network.testnet)

// Initialize BackupManager
let encryptionKey = "d5a423f64b607ea7c65b311d855dc48f36114b227bd0c7a3d403f6158a9e4412" // Use your own unique 256-bit / 64 character string
backupManager = BackupManager.init(encryptionKey: encryptionKey, enableCloudBackup: true)

// WARNING!!
// While testing, remove key backup on every restart
//backupManager.deletePrivateKey()
// WARNING!!

// Check if use already has a private key
if backupManager.keyInfo != nil {
// If they do, get descriptor and load wallet in bdkManager
// Check if use already has a node seed
if backupManager.backupInfo != nil {
// If they do, start node
do {
let descriptor = try Descriptor(descriptor: backupManager.keyInfo!.descriptor, network: bdkManager.network)
bdkManager.loadWallet(descriptor: descriptor)
try ldkNodeManager.start(mnemonic: backupManager.backupInfo!.mnemonic, passphrase: nil)
} catch let error {
debugPrint(error)
}
Expand All @@ -39,13 +33,13 @@ struct DailyWalletApp: App {

var body: some Scene {
WindowGroup {
if bdkManager.wallet == nil {
if ldkNodeManager.node == nil {
StartView()
.environmentObject(bdkManager)
.environmentObject(ldkNodeManager)
.environmentObject(backupManager)
} else {
HomeView()
.environmentObject(bdkManager)
.environmentObject(ldkNodeManager)
.environmentObject(backupManager)
}
}
Expand Down
Loading

0 comments on commit 815e2b8

Please sign in to comment.