Skip to content

Commit 8aceec6

Browse files
committed
feat: Add kyoto example and logging
1 parent 7507fe7 commit 8aceec6

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

examples/build.gradle.kts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ repositories {
1515
dependencies {
1616
implementation(project(":lib"))
1717
testImplementation(kotlin("test"))
18+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
19+
implementation("org.slf4j:slf4j-api:2.0.16")
20+
implementation("ch.qos.logback:logback-classic:1.5.13")
1821
}
1922

2023
tasks.test {
@@ -39,11 +42,21 @@ tasks.register<JavaExec>("WalletSetupBip32") {
3942
description = "Runs the main function in the WalletSetupBip32 example"
4043
mainClass.set("org.bitcoindevkit.WalletSetupBip32Kt")
4144
classpath = sourceSets["main"].runtimeClasspath
45+
workingDir = project.rootDir
4246
}
4347

4448
tasks.register<JavaExec>("MultisigTransaction") {
4549
group = "application"
4650
description = "Runs the main function in the MultisigTransaction example"
4751
mainClass.set("org.bitcoindevkit.MultisigTransactionKt")
4852
classpath = sourceSets["main"].runtimeClasspath
53+
workingDir = project.rootDir
54+
}
55+
56+
tasks.register<JavaExec>("Kyoto") {
57+
group = "application"
58+
description = "Runs the main function in the Kyoto example"
59+
mainClass.set("org.bitcoindevkit.KyotoKt")
60+
classpath = sourceSets["main"].runtimeClasspath
61+
workingDir = project.rootDir
4962
}

examples/src/main/kotlin/Kyoto.kt

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package org.bitcoindevkit
2+
3+
import kotlinx.coroutines.CoroutineScope
4+
import kotlinx.coroutines.cancelAndJoin
5+
import kotlinx.coroutines.launch
6+
import kotlinx.coroutines.runBlocking
7+
import java.nio.file.Files
8+
import java.nio.file.Paths
9+
import org.slf4j.Logger
10+
import org.slf4j.LoggerFactory
11+
12+
13+
14+
fun main() {
15+
// Regtest environment must have Compact block filter enabled to run this
16+
// Setup your environment according to the https://github.com/thunderbiscuit/podman-regtest-infinity-pro documentation.
17+
18+
// Add your regtest IP address
19+
val ip: IpAddress = IpAddress.fromIpv4(127u, 0u, 0u, 1u)
20+
val peer: Peer = Peer(ip, 18444u, false)
21+
val peers: List<Peer> = listOf(peer)
22+
val currentPath = Paths.get("examples/data").toAbsolutePath().normalize()
23+
println("Current path: $currentPath")
24+
val persistenceFilePath = Files.createTempDirectory(currentPath, "kyoto-data_")
25+
26+
val wallet = getNewWallet(ActiveWalletScriptType.P2WPKH, Network.REGTEST)
27+
val address = wallet.revealNextAddress(KeychainKind.EXTERNAL)
28+
29+
// Fund this address. Send coins from your regtest to this address
30+
println("Receiving address. Send funds to this address: ${address.address}")
31+
32+
// Wait 70 seconds for funds to arrive before syncing
33+
// Ensure you mine a block after sending funds to the address. This enables kyoto pickup the transaction.
34+
println("Waiting 70 seconds for funds to arrive here ${address.address} before kyoto (compact block filter syncing) ...")
35+
Thread.sleep(70000)
36+
37+
// Create CBF node and client
38+
runBlocking {
39+
val lightClient = CbfBuilder()
40+
.peers(peers)
41+
.connections(1u)
42+
.scanType(ScanType.New)
43+
.dataDir(persistenceFilePath.toString())
44+
.build(wallet)
45+
val client = lightClient.client
46+
val node = lightClient.node
47+
48+
val logJob = launchLogCollector(this, client::nextLog, "LOG")
49+
val logWarningJob = launchLogCollector(this, client::nextWarning, "WARNING")
50+
val logInfoJob = launchLogCollector(this, client::nextInfo, "INFO")
51+
52+
//Start CBF node
53+
node.run()
54+
println("Node running")
55+
56+
//Update wallet
57+
val update: Update = client.update()
58+
wallet.applyUpdate(update)
59+
println("Wallet balance: ${wallet.balance().total.toSat()} sats")
60+
61+
if(wallet.balance().total.toSat() > 0uL) {
62+
println("Wallet is synced and ready for use!")
63+
println("Test completed successfully")
64+
}else{
65+
println("Wallet balance is 0. Try sending funds to ${address.address} and try again.")
66+
}
67+
logJob.cancelAndJoin()
68+
logWarningJob.cancelAndJoin()
69+
logInfoJob.cancelAndJoin()
70+
client.shutdown()
71+
}
72+
}
73+
74+
fun <T> launchLogCollector(scope: CoroutineScope, collector: suspend () -> T, logType: String) = scope.launch {
75+
val logger: Logger = LoggerFactory.getLogger("LogCollector")
76+
77+
while (true) {
78+
val log = collector()
79+
when (logType) {
80+
"LOG" -> logger.info("$log")
81+
"WARNING" -> logger.warn("$log")
82+
"INFO" -> logger.info("$log")
83+
else -> logger.debug("[$logType]: $log")
84+
}
85+
}
86+
}
87+

0 commit comments

Comments
 (0)