Rename bdk-kotlin companion project, fix gradle warnings

This commit is contained in:
Steve Myers 2021-06-14 13:59:56 -07:00
parent a37bae5b9d
commit e266634560
21 changed files with 323 additions and 63 deletions

2
.gitignore vendored
View File

@ -2,7 +2,7 @@ target
build build
Cargo.lock Cargo.lock
*.h *.h
/local.properties /bdk-kotlin/local.properties
.gradle .gradle
wallet_db wallet_db
bdk_ffi_test bdk_ffi_test

View File

@ -1,5 +1,5 @@
[package] [package]
name = "bdk_ffi" name = "bdk-ffi"
version = "0.1.0" version = "0.1.0"
authors = ["Steve Myers <steve@notmandatory.org>"] authors = ["Steve Myers <steve@notmandatory.org>"]
edition = "2018" edition = "2018"

6
bdk-kotlin/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/target
.idea
.gradle
local.properties
build
*.so

View File

@ -0,0 +1,73 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'maven-publish'
android {
compileSdkVersion 30
buildToolsVersion "29.0.3"
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
//task buildRust(type: Exec) {
// workingDir '../'
// commandLine './build.sh'
//}
afterEvaluate {
// android.libraryVariants.all { variant ->
// variant.javaCompileProvider.get().dependsOn(buildRust)
// }
publishing {
publications {
// Creates a Maven publication called "release".
release(MavenPublication) {
// Applies the component for the release build variant.
from components.release
// You can then customize attributes of the publication as shown below.
groupId = 'org.bitcoindevkit.bdkffi'
artifactId = 'bdk'
version = '0.0.1-dev'
}
// Creates a Maven publication called debug.
debug(MavenPublication) {
// Applies the component for the debug build variant.
from components.debug
groupId = 'org.bitcoindevkit.bdkffi'
artifactId = 'bdk-debug'
version = '0.0.1-dev'
}
}
}
}
dependencies {
implementation project(':jar')
api 'net.java.dev.jna:jna:5.8.0@aar'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.core:core-ktx:1.5.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1'
}

View File

26
bdk-kotlin/aar/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,26 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
# for JNA
-dontwarn java.awt.*
-keep class com.sun.jna.* { *; }
-keepclassmembers class * extends com.sun.jna.* { public *; }

View File

@ -0,0 +1,147 @@
package org.bitcoindevkit.bdk
import android.util.Log
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
import org.junit.Before
//import org.bitcoindevkit.bdkjni.Types.Network
//import org.bitcoindevkit.bdkjni.Types.WalletConstructor
//import org.bitcoindevkit.bdkjni.Types.WalletPtr
import org.junit.Ignore
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
companion object {
init {
System.loadLibrary("bdk_jni")
}
}
private lateinit var wallet: WalletPtr
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("org.bitcoindevkit.bdkjni.test", appContext.packageName)
}
@Before
fun constructor() {
val dir = createTempDir()
val descriptor = "wpkh(tprv8ZgxMBicQKsPexGYyaFwnAsCXCjmz2FaTm6LtesyyihjbQE3gRMfXqQBXKM43DvC1UgRVv1qom1qFxNMSqVAs88qx9PhgFnfGVUdiiDf6j4/0/*)"
val electrum = "tcp://electrum.blockstream.info:60001"
wallet = Lib().constructor(WalletConstructor("testnet", Network.regtest, dir.toString(), descriptor, null, electrum, null))
Lib().sync(wallet)
}
@Test
fun newAddress() {
val address = Lib().get_new_address(wallet)
assertFalse(address.isEmpty())
}
@Test
fun sync() {
Lib().sync(wallet, 100)
val balance = Lib().get_balance(wallet)
assertFalse(balance == 0L)
}
// TODO need to figure out why this passes when testing with a localhost node but fails when using blockstream.info
@Ignore
@Test
fun multiThreadBalance() {
runBlocking {
val flow1 = newBalanceFlow(1).flowOn(Dispatchers.IO)
val flow2 = newBalanceFlow(2).flowOn(Dispatchers.IO)
flow1.flatMapMerge(concurrency = 2) { flow2 }.collect()
//flow1.collect()
}
}
private fun newBalanceFlow(id: Int): Flow<Pair<Int, Long>> {
return (1..10).asFlow()
//.onStart { Log.d("BAL_FLOW", "start flow $id") }
//.onCompletion { Log.d("BAL_FLOW", "complete flow $id") }
//.onEach { Log.d("BAL_FLOW", "flow $id, iteration $it") }
.map {
val balance = Lib().get_balance(wallet)
Pair(it, balance)
}
.catch { e ->
Log.e("BAL_FLOW", "failed flow $id with exception: $e")
fail()
}
.onEach {
//Log.d("BAL_FLOW", "verifying flow $id, iteration ${it.first}")
assertFalse(it.second == 0L)
//Log.d("BAL_FLOW", "finished flow $id iteration ${it.first}")
}
}
@Test
fun balance() {
val balance = Lib().get_balance(wallet)
assertFalse(balance == 0L)
}
@Test
fun unspent() {
val unspent = Lib().list_unspent(wallet)
assertFalse(unspent.isEmpty())
}
@Test
fun transactions() {
val transactions = Lib().list_transactions(wallet)
assertFalse(transactions.isEmpty())
}
@Test
fun generate_key() {
val keys = Lib().generate_extended_key(Network.testnet, 24, "test123")
assertNotNull(keys)
assertEquals(24, keys.mnemonic.split(' ').size)
assertEquals("tprv", keys.xprv.substring(0,4))
}
@Test
fun restore_key() {
val mnemonic = "shell bid diary primary focus average truly secret lonely circle radar fall tank action place body wedding sponsor embody glue swing gauge shop penalty"
val keys = Lib().restore_extended_key(Network.testnet, mnemonic, null)
assertNotNull(keys)
assertEquals(mnemonic, keys.mnemonic)
assertEquals("tprv8ZgxMBicQKsPeh5nd4nCDLGh9dLfhqGfUoiQsbThkttjX9oroRY2j5vpEGwkiKiKtzdU7u4eqH2yFicGvz19rMVVXfY8XB9fdoeXWJ7SgVE", keys.xprv)
}
@Test
fun restore_key_password() {
val mnemonic = "shell bid diary primary focus average truly secret lonely circle radar fall tank action place body wedding sponsor embody glue swing gauge shop penalty"
val keys = Lib().restore_extended_key(Network.testnet, mnemonic, "test123")
assertNotNull(keys)
assertEquals(mnemonic, keys.mnemonic)
assertEquals("tprv8ZgxMBicQKsPebcVXyErMuuv2rgE34m2SLMBhy4hURbSEAWQ1VsWVVmMnD7FKiAuRrxzAETFnUaSvFNQ5SAS5tYEwsM1KHDpUhLLQgd6yG1", keys.xprv)
}
@After
fun destructor() {
Lib().destructor(wallet)
}
}

View File

@ -0,0 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.bitcoindevkit.bdk" >
<uses-permission android:name="android.permission.INTERNET" />
</manifest>

View File

@ -1,18 +1,18 @@
buildscript { buildscript {
ext.kotlin_version = '1.5.10' ext.kotlin_version = '1.5.10'
repositories { repositories {
//google() google()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
//classpath 'com.android.tools.build:gradle:3.6.4' classpath 'com.android.tools.build:gradle:4.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
allprojects { allprojects {
repositories { repositories {
//google() google()
mavenCentral() mavenCentral()
} }
} }

View File

@ -1,5 +1,6 @@
#Thu Jun 10 21:43:37 PDT 2021
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View File

@ -0,0 +1,42 @@
plugins {
id 'org.jetbrains.kotlin.jvm'
id 'java-library'
id 'maven-publish'
}
test {
environment "LD_LIBRARY_PATH", file("${projectDir}/../../target/debug").absolutePath
// testLogging {
// events "PASSED", "SKIPPED", "FAILED", "STANDARD_OUT", "STANDARD_ERROR"
// }
}
task buildRust(type: Exec) {
workingDir '../'
commandLine './build.sh'
}
dependencies {
implementation platform('org.jetbrains.kotlin:kotlin-bom')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "net.java.dev.jna:jna:5.8.0"
testImplementation 'org.jetbrains.kotlin:kotlin-test'
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
}
publishing {
publications {
maven(MavenPublication) {
groupId = 'org.bitcoindevkit'
artifactId = 'bdk-debug'
version = '0.0.1-dev'
from components.java
}
}
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

View File

@ -1,7 +1,6 @@
package org.bitcoindevkit.bdkjni package org.bitcoindevkit.bdk
import com.sun.jna.* import com.sun.jna.*
import com.sun.jna.ptr.PointerByReference
interface Lib : Library { interface Lib : Library {

View File

@ -1,7 +1,6 @@
package org.bitcoindevkit.bdkjni package org.bitcoindevkit.bdk
import com.sun.jna.Native import com.sun.jna.Native
import com.sun.jna.NativeLong
import org.junit.Test import org.junit.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

View File

@ -0,0 +1,3 @@
rootProject.name = 'bdk-kotlin'
include 'jar'

View File

@ -1,13 +1,14 @@
# rust # rust
cargo build cargo build
cargo test --features c-headers -- generate_headers cargo test --features c-headers -- generate_headers
export LD_LIBRARY_PATH=`pwd`/target/debug
# cc # cc
cc bdk_ffi_test.c -o bdk_ffi_test -L target/debug -l bdk_ffi -l pthread -l dl -l m export LD_LIBRARY_PATH=`pwd`/target/debug
#valgrind --leak-check=full ./bdk_ffi_test cc cc/bdk_ffi_test.c -o cc/bdk_ffi_test -L target/debug -l bdk_ffi -l pthread -l dl -l m
./bdk_ffi_test #valgrind --leak-check=full cc/bdk_ffi_test
cc/bdk_ffi_test
# jvm # bdk-kotlin
mkdir -p jvm/build/jniLibs/x86_64_linux mkdir -p bdk-kotlin/jar/libs/x86_64_linux
cp target/debug/libbdk_ffi.so jvm/build/jniLibs/x86_64_linux cp target/debug/libbdk_ffi.so bdk-kotlin/jar/libs/x86_64_linux
(cd bdk-kotlin && gradle test)

View File

@ -1,40 +0,0 @@
plugins {
id 'org.jetbrains.kotlin.jvm' // version '1.3.71'
id 'java-library'
id 'maven-publish'
}
test {
systemProperty "java.library.path", file("${buildDir}/jniLibs/x86_64_linux").absolutePath
environment "LD_LIBRARY_PATH", file("${buildDir}/jniLibs/x86_64_linux").absolutePath
testLogging {
events "PASSED", "SKIPPED", "FAILED", "STANDARD_OUT", "STANDARD_ERROR"
}
}
task buildRust(type: Exec) {
workingDir '../'
commandLine './build.sh'
}
dependencies {
implementation platform('org.jetbrains.kotlin:kotlin-bom')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.10"
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.+"
implementation "net.java.dev.jna:jna:5.8.0"
testImplementation 'org.jetbrains.kotlin:kotlin-test'
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
}
publishing {
publications {
maven(MavenPublication) {
groupId = 'org.bitcoindevkit.bdkffi'
artifactId = 'bdk-jvm-debug'
version = '0.2.1-dev'
from components.java
}
}
}

View File

@ -1,3 +0,0 @@
rootProject.name = 'bdk_ffi'
include 'jvm'

View File

@ -7,6 +7,6 @@ mod wallet;
#[test] #[test]
fn generate_headers() -> ::std::io::Result<()> { fn generate_headers() -> ::std::io::Result<()> {
::safer_ffi::headers::builder() ::safer_ffi::headers::builder()
.to_file("bdk_ffi.h")? .to_file("cc/bdk_ffi.h")?
.generate() .generate()
} }