diff --git a/.gitignore b/.gitignore index 55bac571..ccb4d482 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ xcuserdata .idea/ .editorconfig bdk.kt +kyotodata/ # Swift related /.build @@ -35,4 +36,4 @@ bdk.swift Info.plist # Python related -__pycache__ \ No newline at end of file +__pycache__ diff --git a/bdk-android/gradle.properties b/bdk-android/gradle.properties index e5dd05f8..976061d4 100644 --- a/bdk-android/gradle.properties +++ b/bdk-android/gradle.properties @@ -2,4 +2,4 @@ org.gradle.jvmargs=-Xmx1536m android.useAndroidX=true android.enableJetifier=true kotlin.code.style=official -libraryVersion=1.0.0-alpha.12-SNAPSHOT +libraryVersion=1.0.0-alpha.13-KYOTO diff --git a/bdk-android/lib/build.gradle.kts b/bdk-android/lib/build.gradle.kts index 96d960ae..65c7743b 100644 --- a/bdk-android/lib/build.gradle.kts +++ b/bdk-android/lib/build.gradle.kts @@ -56,11 +56,13 @@ java { dependencies { implementation("net.java.dev.jna:jna:5.14.0@aar") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") implementation("androidx.appcompat:appcompat:1.4.0") implementation("androidx.core:core-ktx:1.7.0") api("org.slf4j:slf4j-api:1.7.30") androidTestImplementation("com.github.tony19:logback-android:2.0.0") + testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") androidTestImplementation("androidx.test.ext:junit:1.1.3") androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0") androidTestImplementation("org.jetbrains.kotlin:kotlin-test:1.6.10") diff --git a/bdk-android/lib/src/androidTest/kotlin/org/bitcoindevkit/KyotoTest.kt b/bdk-android/lib/src/androidTest/kotlin/org/bitcoindevkit/KyotoTest.kt new file mode 100644 index 00000000..27379d00 --- /dev/null +++ b/bdk-android/lib/src/androidTest/kotlin/org/bitcoindevkit/KyotoTest.kt @@ -0,0 +1,24 @@ +package org.bitcoindevkit + +import org.junit.Test +import androidx.test.ext.junit.runners.AndroidJUnit4 +import kotlinx.coroutines.runBlocking +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class KyotoTest { + private val descriptor: Descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.SIGNET) + private val changeDescriptor: Descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/1/*)", Network.SIGNET) + + @Test + fun testKyoto() { + // val wallet: Wallet = Wallet(descriptor, changeDescriptor, Network.SIGNET) + runBlocking { + println("Running test Kyoto") + val (node, client) = buildKyotoClient() + runNode(node) + client.update() + println("Done running test Kyoto") + } + } +} diff --git a/bdk-ffi/Cargo.lock b/bdk-ffi/Cargo.lock index a789c7c3..263c4399 100644 --- a/bdk-ffi/Cargo.lock +++ b/bdk-ffi/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "ahash" version = "0.8.11" @@ -50,7 +65,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -60,7 +75,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -122,12 +137,38 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base58ck" version = "0.1.0" @@ -173,10 +214,12 @@ dependencies = [ "bdk_bitcoind_rpc", "bdk_electrum", "bdk_esplora", + "bdk_kyoto", "bdk_sqlite", "bdk_wallet", "bitcoin-internals 0.2.0", "thiserror", + "tokio", "uniffi", ] @@ -222,6 +265,15 @@ dependencies = [ "miniscript", ] +[[package]] +name = "bdk_kyoto" +version = "0.1.0" +source = "git+https://github.com/ValuedMammal/bdk-kyoto.git?rev=31507d5b5361b0d8753ad16722eb5245a3f4a4b9#31507d5b5361b0d8753ad16722eb5245a3f4a4b9" +dependencies = [ + "bdk_wallet", + "kyoto", +] + [[package]] name = "bdk_sqlite" version = "0.2.0" @@ -482,6 +534,18 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +[[package]] +name = "dns-lookup" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5766087c2235fec47fafa4cfecc81e494ee679d0fd4a59887ea0919bfb0e4fc" +dependencies = [ + "cfg-if", + "libc", + "socket2", + "windows-sys 0.48.0", +] + [[package]] name = "electrum-client" version = "0.20.0" @@ -543,6 +607,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + [[package]] name = "glob" version = "0.3.1" @@ -584,6 +654,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "hex-conservative" version = "0.2.1" @@ -632,6 +708,21 @@ dependencies = [ "serde_json", ] +[[package]] +name = "kyoto" +version = "0.1.0" +source = "git+https://github.com/rustaceanrob/kyoto?rev=24e08d6b443558e2a29a8a6d639f36f662537084#24e08d6b443558e2a29a8a6d639f36f662537084" +dependencies = [ + "async-trait", + "bitcoin", + "bitcoin_hashes 0.14.0", + "dns-lookup", + "rand", + "rusqlite", + "thiserror", + "tokio", +] + [[package]] name = "libc" version = "0.2.155" @@ -694,6 +785,15 @@ dependencies = [ "serde", ] +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + [[package]] name = "minreq" version = "2.11.2" @@ -710,6 +810,17 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + [[package]] name = "nom" version = "7.1.3" @@ -720,6 +831,25 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -732,6 +862,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + [[package]] name = "pkg-config" version = "0.3.30" @@ -810,7 +946,7 @@ dependencies = [ "libc", "spin", "untrusted", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -827,6 +963,12 @@ dependencies = [ "smallvec", ] +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + [[package]] name = "rustls" version = "0.21.12" @@ -996,6 +1138,16 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "spin" version = "0.9.8" @@ -1075,6 +1227,34 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "toml" version = "0.5.11" @@ -1360,13 +1540,37 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -1375,28 +1579,46 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.5" @@ -1409,24 +1631,48 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.5" diff --git a/bdk-ffi/Cargo.toml b/bdk-ffi/Cargo.toml index a15accba..2f677b2e 100644 --- a/bdk-ffi/Cargo.toml +++ b/bdk-ffi/Cargo.toml @@ -24,11 +24,14 @@ bdk_esplora = { version = "0.15.0", default-features = false, features = ["std", # of bdk in which the bdk_electrum library uses the electrum-client with the use-rustls-ring feature. bdk_electrum = { git = "https://github.com/thunderbiscuit/bdk/", package = "bdk_electrum", branch = "feature/electrum-client-ring-ffi-alpha13", default-features = false, features = ["use-rustls-ring"] } # bdk_electrum = { version = "0.15.0" } +bdk_kyoto = { git = "https://github.com/ValuedMammal/bdk-kyoto.git", rev = "31507d5b5361b0d8753ad16722eb5245a3f4a4b9", default-features = false } +#bdk_kyoto = { path = "../../bdk-kyoto" } bdk_sqlite = { version = "0.2.0" } bdk_bitcoind_rpc = { version = "0.12.0" } bitcoin-internals = { version = "0.2.0", features = ["alloc"] } uniffi = { version = "=0.28.0" } +tokio = { version = "1", default-features = false, features = [ "rt-multi-thread", "sync" ] } thiserror = "1.0.58" [build-dependencies] diff --git a/bdk-ffi/src/bdk.udl b/bdk-ffi/src/bdk.udl index bacb8756..ca999409 100644 --- a/bdk-ffi/src/bdk.udl +++ b/bdk-ffi/src/bdk.udl @@ -1,4 +1,8 @@ -namespace bdk {}; +namespace bdk { + NodePair build_light_client(Wallet wallet, sequence peers, u8 connections, u32? recovery_height, string data_dir, NodeMessageHandler? logger); + + void run_node(LightNode node); +}; // ------------------------------------------------------------------------ // bdk crate - error module @@ -726,3 +730,41 @@ dictionary TxIn { u32 sequence; sequence> witness; }; + +interface LightClient { + [Async] + Update? update(); +}; + +interface LightNode { + [Async] + void run(); +}; + +dictionary NodePair { + LightNode node; + LightClient client; +}; + +[Enum] +interface Peer { + V4(u8 q1, u8 q2, u8 q3, u8 q4); + V6(string addr); +}; + +[Trait, WithForeign] +interface NodeMessageHandler { + void handle_dialog(string dialog); + + void handle_warning(string warning); + + void handle_state_change(NodeState state); +}; + +enum NodeState { + "Behind", + "HeadersSynced", + "FilterHeadersSynced", + "FiltersSynced", + "TransactionsSynced" +}; diff --git a/bdk-ffi/src/kyoto.rs b/bdk-ffi/src/kyoto.rs new file mode 100644 index 00000000..cfa9812f --- /dev/null +++ b/bdk-ffi/src/kyoto.rs @@ -0,0 +1,102 @@ +use bdk_kyoto::builder::LightClientBuilder; +use bdk_kyoto::logger::{NodeMessageHandler, PrintLogger}; +use bdk_kyoto::Node; +use bdk_kyoto::{Client, TrustedPeer}; +use bdk_wallet::KeychainKind; +use std::net::{IpAddr, Ipv4Addr}; +use std::path::PathBuf; +use std::str::FromStr; +use std::sync::Arc; +use tokio::sync::Mutex; + +use crate::wallet::Update; +use crate::wallet::Wallet; + +pub struct LightClient { + client: Mutex>, +} + +pub struct LightNode { + node: Mutex, +} + +pub struct NodePair { + pub node: Arc, + pub client: Arc, +} + +pub fn build_light_client( + wallet: Arc, + peers: Vec, + connections: u8, + recovery_height: Option, + data_dir: String, + logger: Option>, +) -> NodePair { + let peers = peers + .into_iter() + .map(|ip| match ip { + Peer::V4 { q1, q2, q3, q4 } => IpAddr::V4(Ipv4Addr::new(q1, q2, q3, q4)), + Peer::V6 { addr } => IpAddr::V6(addr.parse().unwrap()), + }) + .map(TrustedPeer::from_ip) + .collect::>(); + + let wallet = wallet.get_wallet(); + let logger = logger.unwrap_or(Arc::new(PrintLogger::new())); + + let mut builder = LightClientBuilder::new(&wallet) + .connections(connections) + .logger(logger) + .data_dir(PathBuf::from_str(&data_dir).unwrap()) + .peers(peers); + + if let Some(recovery) = recovery_height { + builder = builder.scan_after(recovery) + } + + let (node, bdk_kyoto_client) = builder.build(); + + let node = LightNode { + node: Mutex::new(node), + }; + + let client = LightClient { + client: Mutex::new(bdk_kyoto_client), + }; + + NodePair { + node: Arc::new(node), + client: Arc::new(client), + } +} + +pub fn run_node(node: Arc) { + std::thread::spawn(|| { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() + .block_on(async move { + node.as_ref().run().await; + }) + }); +} + +impl LightClient { + pub async fn update(&self) -> Option> { + let update = self.client.lock().await.update().await; + update.map(|update| Arc::new(Update(update.into()))) + } +} + +impl LightNode { + pub async fn run(&self) { + let _ = self.node.lock().await.run().await; + } +} + +pub enum Peer { + V4 { q1: u8, q2: u8, q3: u8, q4: u8 }, + V6 { addr: String }, +} diff --git a/bdk-ffi/src/lib.rs b/bdk-ffi/src/lib.rs index 9d66cd83..2fa605f2 100644 --- a/bdk-ffi/src/lib.rs +++ b/bdk-ffi/src/lib.rs @@ -4,6 +4,7 @@ mod electrum; mod error; mod esplora; mod keys; +mod kyoto; mod store; mod types; mod wallet; @@ -47,6 +48,12 @@ use crate::keys::DerivationPath; use crate::keys::DescriptorPublicKey; use crate::keys::DescriptorSecretKey; use crate::keys::Mnemonic; +use crate::kyoto::build_light_client; +use crate::kyoto::run_node; +use crate::kyoto::LightClient; +use crate::kyoto::LightNode; +use crate::kyoto::NodePair; +use crate::kyoto::Peer; use crate::store::SqliteStore; use crate::types::AddressInfo; use crate::types::Balance; @@ -70,4 +77,7 @@ use bdk_wallet::keys::bip39::WordCount; use bdk_wallet::wallet::tx_builder::ChangeSpendPolicy; use bdk_wallet::KeychainKind; +use bdk_kyoto::logger::NodeMessageHandler; +use bdk_kyoto::logger::NodeState; + uniffi::include_scaffolding!("bdk"); diff --git a/bdk-ffi/src/wallet.rs b/bdk-ffi/src/wallet.rs index 130c8d15..b5893295 100644 --- a/bdk-ffi/src/wallet.rs +++ b/bdk-ffi/src/wallet.rs @@ -63,7 +63,7 @@ impl Wallet { } pub(crate) fn get_wallet(&self) -> MutexGuard { - self.inner_mutex.lock().expect("wallet") + self.inner_mutex.lock().unwrap() } pub fn reveal_next_address(&self, keychain_kind: KeychainKind) -> AddressInfo { diff --git a/bdk-jvm/justfile b/bdk-jvm/justfile index d29b97b9..e6174007 100644 --- a/bdk-jvm/justfile +++ b/bdk-jvm/justfile @@ -1,8 +1,8 @@ default: just --list -build: - ./gradlew buildJvmLib +build-macos: + bash ./scripts/build-macos-aarch64.sh clean: rm -rf ../bdk-ffi/target/ @@ -20,4 +20,4 @@ test-offline: ./gradlew test -P excludeConnectedTests test-specific TEST: - ./gradlew test --tests {{TEST}} \ No newline at end of file + ./gradlew test --tests {{TEST}} diff --git a/bdk-jvm/lib/build.gradle.kts b/bdk-jvm/lib/build.gradle.kts index 8c226d79..5c51aeab 100644 --- a/bdk-jvm/lib/build.gradle.kts +++ b/bdk-jvm/lib/build.gradle.kts @@ -58,12 +58,14 @@ tasks.withType { dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom")) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") implementation("net.java.dev.jna:jna:5.14.0") api("org.slf4j:slf4j-api:1.7.30") // testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.1") // testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.1") // testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.8.2") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") testImplementation("ch.qos.logback:logback-classic:1.2.3") testImplementation("ch.qos.logback:logback-core:1.2.3") } diff --git a/bdk-jvm/lib/src/test/kotlin/org/bitcoindevkit/KyotoTest.kt b/bdk-jvm/lib/src/test/kotlin/org/bitcoindevkit/KyotoTest.kt new file mode 100644 index 00000000..8b40e117 --- /dev/null +++ b/bdk-jvm/lib/src/test/kotlin/org/bitcoindevkit/KyotoTest.kt @@ -0,0 +1,56 @@ +package org.bitcoindevkit + +import kotlinx.coroutines.runBlocking +import kotlin.test.Test + +class KyotoTest { + private val descriptor: Descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.SIGNET) + private val changeDescriptor: Descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/1/*)", Network.SIGNET) + + @Test + fun testKyoto() { + val wallet: Wallet = Wallet(descriptor, changeDescriptor, Network.SIGNET) + val peers: List = listOf( + Peer.V4(23u, 137u, 57u, 100u) + ) + val logger = KotlinKyotoLogger() + + val (node, client) = buildLightClient( + wallet = wallet, + peers = peers, + connections = 1u, + recoveryHeight = 170000u, + dataDir = "./kyotodata/", + logger = logger + ) + runNode(node) + + runBlocking { + println("Starting the sync") + val update = client.update() + require(update != null) { "Update should not be null" } + println("Applying update") + wallet.applyUpdate(update) + val balance = wallet.balance().total.toSat() + println("Balance: $balance") + val transactions = wallet.transactions().take(3) + for (tx in transactions) { + println("Transaction: ${tx.transaction.computeTxid()}") + } + } + } +} + +class KotlinKyotoLogger: NodeMessageHandler { + override fun handleDialog(dialog: String) { + // println("Here's a dialog bud: $dialog") + } + + override fun handleStateChange(state: NodeState) { + println("Here's a state change bud: $state") + } + + override fun handleWarning(warning: String) { + println("Here's a warning bud: $warning") + } +} diff --git a/bdk-jvm/scripts/build-macos-aarch64.sh b/bdk-jvm/scripts/build-macos-aarch64.sh new file mode 100644 index 00000000..2ee9a4b3 --- /dev/null +++ b/bdk-jvm/scripts/build-macos-aarch64.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Move to the Rust library directory +cd ../bdk-ffi/ + +# Build the Rust library +cargo build --profile release-smaller --target aarch64-apple-darwin + +# Generate Kotlin bindings using uniffi-bindgen +cargo run --bin uniffi-bindgen generate --library ./target/aarch64-apple-darwin/release-smaller/libbdkffi.dylib --language kotlin --out-dir ../bdk-jvm/lib/src/main/kotlin/ --no-format + +# Copy the binary to the Android resources directory +cp ./target/aarch64-apple-darwin/release-smaller/libbdkffi.dylib ../bdk-jvm/lib/src/main/resources/darwin-aarch64/libbdkffi.dylib diff --git a/bdk-python/scripts/generate-linux.sh b/bdk-python/scripts/generate-linux.sh index c8d5e713..275f4fe0 100644 --- a/bdk-python/scripts/generate-linux.sh +++ b/bdk-python/scripts/generate-linux.sh @@ -1,11 +1,6 @@ #!/usr/bin/env bash -set -euo pipefail -${PYBIN}/python --version -${PYBIN}/pip install -r requirements.txt - cd ../bdk-ffi/ -rustup default 1.77.1 echo "Generating native binaries..." cargo build --profile release-smaller @@ -16,4 +11,12 @@ cargo run --bin uniffi-bindgen generate --library ./target/release-smaller/libbd echo "Copying linux libbdkffi.so..." cp ./target/release-smaller/libbdkffi.so ../bdk-python/src/bdkpython/libbdkffi.so -echo "All done!" +cd ../bdk-python + +echo "Building wheel" + +python3 setup.py --verbose bdist_wheel + +echo "Installing BDK Python" + +pip3 install ./dist/bdkpython-1.0.0a12.dev0-cp310-cp310-linux_x86_64.whl --force-reinstall \ No newline at end of file