From 290db0105f007112a0ccf5391fd761bb82f80735 Mon Sep 17 00:00:00 2001 From: Steve Myers Date: Tue, 12 Oct 2021 15:24:11 -0700 Subject: [PATCH] [WIP] reorganize and remove old stuff --- .gitignore | 2 +- Cargo.toml | 2 +- README.md | 6 +- bdk-kotlin/.gitignore | 7 - bdk-kotlin/android/build.gradle | 71 --- bdk-kotlin/android/consumer-rules.pro | 0 bdk-kotlin/android/proguard-rules.pro | 26 - .../src/androidTest/assets/logback.xml | 14 - .../org/bitcoindevkit/bdk/AndroidLibTest.kt | 21 - .../android/src/main/AndroidManifest.xml | 6 - bdk-kotlin/build.gradle | 22 - bdk-kotlin/jvm/build.gradle | 37 -- .../kotlin/org/bitcoindevkit/bdk/FfiError.kt | 45 -- .../org/bitcoindevkit/bdk/FfiException.kt | 14 - .../kotlin/org/bitcoindevkit/bdk/LibBase.kt | 9 - .../kotlin/org/bitcoindevkit/bdk/LibJna.kt | 407 ------------ .../bitcoindevkit/bdk/types/StringResult.kt | 31 - .../bitcoindevkit/bdk/types/UInt64Result.kt | 31 - .../org/bitcoindevkit/bdk/types/VoidResult.kt | 31 - .../bdk/wallet/BlockchainConfig.kt | 26 - .../bdk/wallet/DatabaseConfig.kt | 26 - .../bdk/wallet/VecLocalUtxoResult.kt | 32 - .../bdk/wallet/VecTxDetailsResult.kt | 32 - .../org/bitcoindevkit/bdk/wallet/Wallet.kt | 65 -- .../bitcoindevkit/bdk/wallet/WalletResult.kt | 31 - .../org/bitcoindevkit/bdk/JvmLibTest.kt | 16 - bdk-kotlin/settings.gradle | 3 - bdk-kotlin/test-fixtures/build.gradle | 19 - .../kotlin/org/bitcoindevkit/bdk/LibTest.kt | 135 ---- bdk-swift/.gitignore | 7 - bdk-swift/bdk.swift/.gitignore | 7 - bdk-swift/bdk.swift/Package.resolved | 16 - bdk-swift/bdk.swift/Package.swift | 28 - bdk-swift/bdk.swift/README.md | 11 - .../Sources/bdk.swift/bdk_swift.swift | 8 - .../Tests/bdk.swiftTests/bdk_swiftTests.swift | 35 - .../bdk-kotlin}/build.gradle | 0 .../bdk-kotlin}/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 2 +- {bdk-kotlin => bindings/bdk-kotlin}/gradlew | 0 .../bdk-kotlin}/gradlew.bat | 0 .../src/main/kotlin/uniffi/bdk/bdk.kt | 0 .../src/test/kotlin/uniffi/bdk/LibTest.kt | 2 +- build.sh | 28 +- cc/bdk_ffi.h | 315 --------- cc/bdk_ffi_test.c | 199 ------ src/error.rs | 134 ---- src/types.rs | 40 -- src/uniffi/bdk/bdk.kt | 602 ------------------ src/wallet/blockchain.rs | 106 --- src/wallet/database.rs | 32 - src/wallet/mod.rs | 175 ----- src/wallet/transaction.rs | 124 ---- targets/kotlin/gradle.properties | 23 - 55 files changed, 21 insertions(+), 3040 deletions(-) delete mode 100644 bdk-kotlin/.gitignore delete mode 100644 bdk-kotlin/android/build.gradle delete mode 100644 bdk-kotlin/android/consumer-rules.pro delete mode 100644 bdk-kotlin/android/proguard-rules.pro delete mode 100644 bdk-kotlin/android/src/androidTest/assets/logback.xml delete mode 100644 bdk-kotlin/android/src/androidTest/kotlin/org/bitcoindevkit/bdk/AndroidLibTest.kt delete mode 100644 bdk-kotlin/android/src/main/AndroidManifest.xml delete mode 100644 bdk-kotlin/build.gradle delete mode 100644 bdk-kotlin/jvm/build.gradle delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/FfiError.kt delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/FfiException.kt delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/LibBase.kt delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/LibJna.kt delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/types/StringResult.kt delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/types/UInt64Result.kt delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/types/VoidResult.kt delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/BlockchainConfig.kt delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/DatabaseConfig.kt delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/VecLocalUtxoResult.kt delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/VecTxDetailsResult.kt delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/Wallet.kt delete mode 100644 bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/WalletResult.kt delete mode 100644 bdk-kotlin/jvm/src/test/kotlin/org/bitcoindevkit/bdk/JvmLibTest.kt delete mode 100644 bdk-kotlin/settings.gradle delete mode 100644 bdk-kotlin/test-fixtures/build.gradle delete mode 100644 bdk-kotlin/test-fixtures/src/main/kotlin/org/bitcoindevkit/bdk/LibTest.kt delete mode 100644 bdk-swift/.gitignore delete mode 100644 bdk-swift/bdk.swift/.gitignore delete mode 100644 bdk-swift/bdk.swift/Package.resolved delete mode 100644 bdk-swift/bdk.swift/Package.swift delete mode 100644 bdk-swift/bdk.swift/README.md delete mode 100644 bdk-swift/bdk.swift/Sources/bdk.swift/bdk_swift.swift delete mode 100644 bdk-swift/bdk.swift/Tests/bdk.swiftTests/bdk_swiftTests.swift rename {targets/kotlin => bindings/bdk-kotlin}/build.gradle (100%) rename {bdk-kotlin => bindings/bdk-kotlin}/gradle.properties (100%) rename {bdk-kotlin => bindings/bdk-kotlin}/gradle/wrapper/gradle-wrapper.jar (100%) rename {bdk-kotlin => bindings/bdk-kotlin}/gradle/wrapper/gradle-wrapper.properties (92%) rename {bdk-kotlin => bindings/bdk-kotlin}/gradlew (100%) rename {bdk-kotlin => bindings/bdk-kotlin}/gradlew.bat (100%) rename {targets/kotlin => bindings/bdk-kotlin}/src/main/kotlin/uniffi/bdk/bdk.kt (100%) rename {targets/kotlin => bindings/bdk-kotlin}/src/test/kotlin/uniffi/bdk/LibTest.kt (90%) delete mode 100644 cc/bdk_ffi.h delete mode 100644 cc/bdk_ffi_test.c delete mode 100644 src/error.rs delete mode 100644 src/types.rs delete mode 100644 src/uniffi/bdk/bdk.kt delete mode 100644 src/wallet/blockchain.rs delete mode 100644 src/wallet/database.rs delete mode 100644 src/wallet/mod.rs delete mode 100644 src/wallet/transaction.rs delete mode 100644 targets/kotlin/gradle.properties diff --git a/.gitignore b/.gitignore index 66ded16..2a8baf6 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ wallet_db bdk_ffi_test local.properties *.log -targets/kotlin/testdb \ No newline at end of file +*.dylib \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 35d42a7..f6dc768 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "uniffi_bdk" version = "0.1.0" -authors = ["Steve Myers "] +authors = ["Steve Myers ", ""] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/README.md b/README.md index 41a4d19..e363d70 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ UniFFI 1. cargo install uniffi_bindgen 2. cargo build -3. uniffi-bindgen generate --no-format --out-dir targets/kotlin/src/main/kotlin src/bdk.udl --language kotlin -4. cp target/debug/libuniffi_bdk.dylib targets/kotlin/src/main/resources/darwin-x86-64 -5. gradle build -Djna.debug_load=true -Djna.debug_load.jna +3. uniffi-bindgen generate --no-format --out-dir bindings/bdk-kotlin/src/main/kotlin src/bdk.udl --language kotlin +4. cp target/debug/libuniffi_bdk.dylib bindings/bdk-kotlin/src/main/resources/darwin-x86-64 +5. cd bindings/bdk-kotlin; gradle build -Djna.debug_load=true -Djna.debug_load.jna Setup Android build environment diff --git a/bdk-kotlin/.gitignore b/bdk-kotlin/.gitignore deleted file mode 100644 index 6501994..0000000 --- a/bdk-kotlin/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -/target -.idea -.gradle -local.properties -build -*.so -*.dylib \ No newline at end of file diff --git a/bdk-kotlin/android/build.gradle b/bdk-kotlin/android/build.gradle deleted file mode 100644 index f3bcdc8..0000000 --- a/bdk-kotlin/android/build.gradle +++ /dev/null @@ -1,71 +0,0 @@ -apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' -apply plugin: 'maven-publish' - -android { - compileSdkVersion 30 - - 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' - } - } -} - -afterEvaluate { - - 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' - artifactId = 'bdk' - version = '0.0.1-SNAPSHOT' - } - // Creates a Maven publication called “debug”. - debug(MavenPublication) { - // Applies the component for the debug build variant. - from components.debug - - groupId = 'org.bitcoindevkit' - artifactId = 'bdk-debug' - version = '0.0.1-SNAPSHOT' - } - } - } -} - -dependencies { - implementation(project(':jvm')) { - exclude group: 'net.java.dev.jna', module: 'jna' - } - - implementation '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' - api "org.slf4j:slf4j-api:1.7.30" - - androidTestImplementation 'com.github.tony19:logback-android:2.0.0' - androidTestImplementation(project(':test-fixtures')) { - exclude group: 'net.java.dev.jna', module: 'jna' - } - 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' -} diff --git a/bdk-kotlin/android/consumer-rules.pro b/bdk-kotlin/android/consumer-rules.pro deleted file mode 100644 index e69de29..0000000 diff --git a/bdk-kotlin/android/proguard-rules.pro b/bdk-kotlin/android/proguard-rules.pro deleted file mode 100644 index 172980c..0000000 --- a/bdk-kotlin/android/proguard-rules.pro +++ /dev/null @@ -1,26 +0,0 @@ -# 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 *; } diff --git a/bdk-kotlin/android/src/androidTest/assets/logback.xml b/bdk-kotlin/android/src/androidTest/assets/logback.xml deleted file mode 100644 index 8f7c81b..0000000 --- a/bdk-kotlin/android/src/androidTest/assets/logback.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - %logger{12} - - - [%-20thread] %msg - - - - - - - \ No newline at end of file diff --git a/bdk-kotlin/android/src/androidTest/kotlin/org/bitcoindevkit/bdk/AndroidLibTest.kt b/bdk-kotlin/android/src/androidTest/kotlin/org/bitcoindevkit/bdk/AndroidLibTest.kt deleted file mode 100644 index 9e1eec0..0000000 --- a/bdk-kotlin/android/src/androidTest/kotlin/org/bitcoindevkit/bdk/AndroidLibTest.kt +++ /dev/null @@ -1,21 +0,0 @@ -package org.bitcoindevkit.bdk - -import android.app.Application -import android.content.Context.MODE_PRIVATE -import androidx.test.core.app.ApplicationProvider -import androidx.test.ext.junit.runners.AndroidJUnit4 -import org.junit.runner.RunWith - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class AndroidLibTest : LibTest() { - override fun getTestDataDir(): String { - val context = ApplicationProvider.getApplicationContext() - return context.getDir("bdk-test", MODE_PRIVATE).toString() - } - -} diff --git a/bdk-kotlin/android/src/main/AndroidManifest.xml b/bdk-kotlin/android/src/main/AndroidManifest.xml deleted file mode 100644 index 2aee369..0000000 --- a/bdk-kotlin/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/bdk-kotlin/build.gradle b/bdk-kotlin/build.gradle deleted file mode 100644 index 1f08c7d..0000000 --- a/bdk-kotlin/build.gradle +++ /dev/null @@ -1,22 +0,0 @@ -buildscript { - ext.kotlin_version = '1.5.10' - repositories { - google() - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:4.2.1' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/build.gradle b/bdk-kotlin/jvm/build.gradle deleted file mode 100644 index 64d2c78..0000000 --- a/bdk-kotlin/jvm/build.gradle +++ /dev/null @@ -1,37 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' - id 'java-library' - id 'maven-publish' -} - -test { - testLogging { - events "PASSED", "SKIPPED", "FAILED", "STANDARD_OUT", "STANDARD_ERROR" - } -} - -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" - api "org.slf4j:slf4j-api:1.7.30" - testImplementation "ch.qos.logback:logback-classic:1.2.3" - testImplementation "ch.qos.logback:logback-core:1.2.3" - testImplementation(project(':test-fixtures')) -} - -publishing { - publications { - maven(MavenPublication) { - groupId = 'org.bitcoindevkit' - artifactId = 'bdk' - version = '0.0.1-SNAPSHOT' - - from components.java - } - } -} -java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/FfiError.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/FfiError.kt deleted file mode 100644 index d5738f9..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/FfiError.kt +++ /dev/null @@ -1,45 +0,0 @@ -package org.bitcoindevkit.bdk - -enum class FfiError { - None, - InvalidU32Bytes, - Generic, - ScriptDoesntHaveAddressForm, - SingleRecipientMultipleOutputs, - SingleRecipientNoInputs, - NoRecipients, - NoUtxosSelected, - OutputBelowDustLimit, - InsufficientFunds, - BnBTotalTriesExceeded, - BnBNoExactMatch, - UnknownUtxo, - TransactionNotFound, - TransactionConfirmed, - IrreplaceableTransaction, - FeeRateTooLow, - FeeTooLow, - MissingKeyOrigin, - Key, - ChecksumMismatch, - SpendingPolicyRequired, - InvalidPolicyPathError, - Signer, - InvalidProgressValue, - ProgressUpdateError, - InvalidOutpoint, - Descriptor, - AddressValidator, - Encode, - Miniscript, - Bip32, - Secp256k1, - Json, - Hex, - Psbt, - Electrum, - - // Esplora - // CompactFilters - Sled, -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/FfiException.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/FfiException.kt deleted file mode 100644 index 5fd6ba8..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/FfiException.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.bitcoindevkit.bdk - -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -class FfiException(val err: FfiError) : Exception() { - private val log: Logger = LoggerFactory.getLogger(FfiException::class.java) - - init { - log.error("JnaError: [{}] {}",err.ordinal, err.name) - } - - internal constructor(err: Short) : this(FfiError.values()[err.toInt()]) -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/LibBase.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/LibBase.kt deleted file mode 100644 index 03ebf78..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/LibBase.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.bitcoindevkit.bdk - -import com.sun.jna.Native - -abstract class LibBase { - - protected val libJna: LibJna - get() = Native.load("bdk_ffi", LibJna::class.java) -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/LibJna.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/LibJna.kt deleted file mode 100644 index 19d2e43..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/LibJna.kt +++ /dev/null @@ -1,407 +0,0 @@ -package org.bitcoindevkit.bdk - -import com.sun.jna.* - -interface LibJna : Library { - - // typedef struct { - // - // char * ok; - // - // FfiError_t err; - // - //} FfiResult_char_ptr_t; - open class FfiResult_char_ptr_t : Structure() { - class ByValue : FfiResult_char_ptr_t(), Structure.ByValue - class ByReference : FfiResult_char_ptr_t(), Structure.ByReference - - @JvmField - var ok: String? = null - - @JvmField - var err: Short? = null - - override fun getFieldOrder() = listOf("ok", "err") - } - - // void free_string_result ( - // FfiResult_char_ptr_t string_result); - fun free_string_result(string_result: FfiResult_char_ptr_t.ByValue) - - // typedef struct { - // - // FfiError_t err; - // - //} FfiResultVoid_t; - open class FfiResultVoid_t : Structure() { - class ByValue : FfiResultVoid_t(), Structure.ByValue - class ByReference : FfiResultVoid_t(), Structure.ByReference - - @JvmField - var err: Short? = null - - override fun getFieldOrder() = listOf("err") - } - - // void free_void_result ( - // FfiResultVoid_t void_result); - fun free_void_result(void_result: FfiResultVoid_t.ByValue) - - // void free_string ( - // char * string); - fun free_string(string: Pointer?) - - // typedef struct BlockchainConfig BlockchainConfig_t; - class BlockchainConfig_t : PointerType { - constructor() : super() - constructor(pointer: Pointer) : super(pointer) - } - - // BlockchainConfig_t * new_electrum_config ( - // char const * url, - // char const * socks5, - // int16_t retry, - // int16_t timeout, - // size_t stop_gap); - fun new_electrum_config( - url: String, - socks5: String?, - retry: Short, - timeout: Short, - stop_gap: Long, - ): BlockchainConfig_t - - // void free_blockchain_config ( - // BlockchainConfig_t * blockchain_config); - fun free_blockchain_config(blockchain_config: BlockchainConfig_t) - - // typedef struct DatabaseConfig DatabaseConfig_t; - class DatabaseConfig_t : PointerType { - constructor() : super() - constructor(pointer: Pointer) : super(pointer) - } - - // typedef struct OpaqueWallet OpaqueWallet_t; - class OpaqueWallet_t : PointerType { - constructor() : super() - constructor(pointer: Pointer) : super(pointer) - } - - // typedef struct { - // - // OpaqueWallet_t * ok; - // - // FfiError_t err; - // - // } FfiResult_OpaqueWallet_ptr_t; - open class FfiResult_OpaqueWallet_ptr_t : Structure() { - class ByValue : FfiResult_OpaqueWallet_ptr_t(), Structure.ByValue - class ByReference : FfiResult_OpaqueWallet_ptr_t(), Structure.ByReference - - @JvmField - var ok: OpaqueWallet_t? = null - - @JvmField - var err: Short? = null - - override fun getFieldOrder() = listOf("ok", "err") - } - - // FfiResult_OpaqueWallet_ptr_t new_wallet_result ( - // char const * descriptor, - // char const * change_descriptor, - // char const * network, - // BlockchainConfig_t const * blockchain_config, - // DatabaseConfig_t const * database_config); - fun new_wallet_result( - descriptor: String, - changeDescriptor: String?, - network: String, - blockchainConfig: BlockchainConfig_t, - databaseConfig: DatabaseConfig_t, - ): FfiResult_OpaqueWallet_ptr_t.ByValue - - // void free_wallet_result ( - // FfiResult_OpaqueWallet_ptr_t wallet_result); - fun free_wallet_result(wallet_result: FfiResult_OpaqueWallet_ptr_t.ByValue) - - // typedef struct { - // - // char * txid; - // - // uint32_t vout; - // - // } OutPoint_t; - open class OutPoint_t : Structure() { - class ByValue : OutPoint_t(), Structure.ByValue - - @JvmField - var txid: String? = null - - @JvmField - var vout: Int? = null - - override fun getFieldOrder() = listOf("txid", "vout") - } - - // typedef struct { - // - // uint64_t value; - // - // char * script_pubkey; - // - // } TxOut_t; - open class TxOut_t : Structure() { - class ByValue : TxOut_t(), Structure.ByValue - - @JvmField - var value: Long? = null - - @JvmField - var script_pubkey: String? = null - - override fun getFieldOrder() = listOf("value", "script_pubkey") - } - - // typedef struct { - // - // OutPoint_t outpoint; - // - // TxOut_t txout; - // - // uint16_t keychain; - // - // } LocalUtxo_t; - open class LocalUtxo_t : Structure() { - - class ByValue : LocalUtxo_t(), Structure.ByValue - class ByReference : LocalUtxo_t(), Structure.ByReference - - @JvmField - var outpoint: OutPoint_t? = null - - @JvmField - var txout: TxOut_t? = null - - @JvmField - var keychain: Short? = null - - override fun getFieldOrder() = listOf("outpoint", "txout", "keychain") - } - - // typedef struct { - // - // LocalUtxo_t * ptr; - // - // size_t len; - // - // size_t cap; - // - // } Vec_LocalUtxo_t; - open class Vec_LocalUtxo_t : Structure() { - - class ByReference : Vec_LocalUtxo_t(), Structure.ByReference - class ByValue : Vec_LocalUtxo_t(), Structure.ByValue - - @JvmField - var ptr: LocalUtxo_t.ByReference? = null - - @JvmField - var len: NativeLong? = null - - @JvmField - var cap: NativeLong? = null - - override fun getFieldOrder() = listOf("ptr", "len", "cap") - } - - // typedef struct { - // - // Vec_LocalUtxo_t ok; - // - // FfiError_t err; - // - // } FfiResult_Vec_LocalUtxo_t; - open class FfiResultVec_LocalUtxo_t : Structure() { - - class ByValue : FfiResultVec_LocalUtxo_t(), Structure.ByValue - class ByReference : FfiResultVec_LocalUtxo_t(), Structure.ByReference - - @JvmField - var ok: Vec_LocalUtxo_t? = null - - @JvmField - var err: Short? = null - - override fun getFieldOrder() = listOf("ok", "err") - } - - // void free_veclocalutxo_result ( - // FfiResult_Vec_LocalUtxo_t unspent_result); - fun free_veclocalutxo_result(unspent_result: FfiResultVec_LocalUtxo_t.ByValue) - - // typedef struct { - // - // uint64_t ok; - // - // FfiError_t err; - // - // } FfiResult_uint64_t; - open class FfiResult_uint64_t : Structure() { - - class ByValue : FfiResult_uint64_t(), Structure.ByValue - class ByReference : FfiResult_uint64_t(), Structure.ByReference - - @JvmField - var ok: Long? = null - - @JvmField - var err: Short? = null - - override fun getFieldOrder() = listOf("ok", "err") - } - - // void free_uint64_result ( - // FfiResult_uint64_t void_result); - fun free_uint64_result(unspent_result: FfiResult_uint64_t.ByValue) - - // FfiResultVoid_t sync_wallet ( - // OpaqueWallet_t const * opaque_wallet); - fun sync_wallet(opaque_wallet: OpaqueWallet_t): FfiResultVoid_t.ByValue - - // FfiResult_char_ptr_t new_address ( - // OpaqueWallet_t const * opaque_wallet); - fun new_address(opaque_wallet: OpaqueWallet_t): FfiResult_char_ptr_t.ByValue - - // FfiResult_Vec_LocalUtxo_t list_unspent ( - // OpaqueWallet_t const * opaque_wallet); - fun list_unspent(opaque_wallet: OpaqueWallet_t): FfiResultVec_LocalUtxo_t.ByValue - - // FfiResult_uint64_t balance ( - // OpaqueWallet_t const * opaque_wallet); - fun balance(opaque_wallet: OpaqueWallet_t): FfiResult_uint64_t.ByValue - - // DatabaseConfig_t * new_memory_config (void); - fun new_memory_config(): DatabaseConfig_t - - // DatabaseConfig_t * new_sled_config ( - // char const * path, - // char const * tree_name); - fun new_sled_config(path: String, tree_name: String): DatabaseConfig_t - - // void free_database_config ( - // DatabaseConfig_t * database_config); - fun free_database_config(database_config: DatabaseConfig_t) - - // typedef struct { - // uint32_t height; - // uint64_t timestamp; - // } ConfirmationTime_t; - open class ConfirmationTime_t : Structure() { - - class ByValue : ConfirmationTime_t(), Structure.ByValue - class ByReference : ConfirmationTime_t(), Structure.ByReference - - @JvmField - var height: Int? = null - - @JvmField - var timestamp: Long? = null - - override fun getFieldOrder() = listOf("height", "timestamp") - } - - // typedef struct { - // char * txid; - // uint64_t received; - // uint64_t sent; - // int64_t fee; - // bool is_confirmed; - // ConfirmationTime_t confirmation_time; - // bool verified; - // } TransactionDetails_t; - open class TransactionDetails_t : Structure() { - - class ByValue : TransactionDetails_t(), Structure.ByValue - class ByReference : TransactionDetails_t(), Structure.ByReference - - @JvmField - var txid: String? = null - - @JvmField - var received: Long? = null - - @JvmField - var sent: Long? = null - - @JvmField - var fee: Long? = null - - @JvmField - var is_confirmed: Boolean? = null - - @JvmField - var confirmation_time: ConfirmationTime_t? = null - - @JvmField - var verified: Boolean? = null - - override fun getFieldOrder() = listOf("txid", "received", "sent", "fee", "is_confirmed", "confirmation_time", "verified") - } - - // typedef struct { - // - // TransactionDetails_t * ptr; - // - // size_t len; - // - // size_t cap; - // - // } Vec_TransactionDetails_t; - open class Vec_TransactionDetails_t : Structure() { - - class ByReference : Vec_TransactionDetails_t(), Structure.ByReference - class ByValue : Vec_TransactionDetails_t(), Structure.ByValue - - @JvmField - var ptr: TransactionDetails_t.ByReference? = null - - @JvmField - var len: NativeLong? = null - - @JvmField - var cap: NativeLong? = null - - override fun getFieldOrder() = listOf("ptr", "len", "cap") - } - - // typedef struct { - // - // Vec_TransactionDetails_t ok; - // - // FfiError_t err; - // - // } FfiResult_Vec_TransactionDetails_t; - open class FfiResult_Vec_TransactionDetails_t : Structure() { - - class ByValue : FfiResult_Vec_TransactionDetails_t(), Structure.ByValue - class ByReference : FfiResult_Vec_TransactionDetails_t(), Structure.ByReference - - @JvmField - var ok: Vec_TransactionDetails_t? = null - - @JvmField - var err: Short? = null - - override fun getFieldOrder() = listOf("ok", "err") - } - - // FfiResult_Vec_TransactionDetails_t list_transactions ( - // OpaqueWallet_t const * opaque_wallet); - fun list_transactions(opaque_wallet: OpaqueWallet_t): FfiResult_Vec_TransactionDetails_t.ByValue - - - // void free_vectxdetails_result ( - // FfiResult_Vec_TransactionDetails_t txdetails_result); - fun free_vectxdetails_result(txdetails_result: FfiResult_Vec_TransactionDetails_t.ByValue) -} diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/types/StringResult.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/types/StringResult.kt deleted file mode 100644 index 2d7ac46..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/types/StringResult.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.bitcoindevkit.bdk.types - -import org.bitcoindevkit.bdk.FfiException -import org.bitcoindevkit.bdk.LibBase -import org.bitcoindevkit.bdk.LibJna -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -class StringResult constructor(private val ffiResultCharPtrT: LibJna.FfiResult_char_ptr_t.ByValue) : - LibBase() { - - private val log: Logger = LoggerFactory.getLogger(StringResult::class.java) - - fun value(): String { - val err = ffiResultCharPtrT.err!! - val ok = ffiResultCharPtrT.ok!! - when { - err > 0 -> { - throw FfiException(err) - } - else -> { - return ok - } - } - } - - protected fun finalize() { - libJna.free_string_result(ffiResultCharPtrT) - log.debug("$ffiResultCharPtrT freed") - } -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/types/UInt64Result.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/types/UInt64Result.kt deleted file mode 100644 index 1b4e6f8..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/types/UInt64Result.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.bitcoindevkit.bdk.types - -import org.bitcoindevkit.bdk.FfiException -import org.bitcoindevkit.bdk.LibBase -import org.bitcoindevkit.bdk.LibJna -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -class UInt64Result constructor(private val ffiResultUint64T: LibJna.FfiResult_uint64_t.ByValue) : - LibBase() { - - private val log: Logger = LoggerFactory.getLogger(UInt64Result::class.java) - - fun value(): Long { - val err = ffiResultUint64T.err!! - val ok = ffiResultUint64T.ok!! - when { - err > 0 -> { - throw FfiException(err) - } - else -> { - return ok - } - } - } - - protected fun finalize() { - libJna.free_uint64_result(ffiResultUint64T) - log.debug("$ffiResultUint64T freed") - } -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/types/VoidResult.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/types/VoidResult.kt deleted file mode 100644 index c50b328..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/types/VoidResult.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.bitcoindevkit.bdk.types - -import org.bitcoindevkit.bdk.FfiException -import org.bitcoindevkit.bdk.LibBase -import org.bitcoindevkit.bdk.LibJna -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -class VoidResult constructor(private val ffiResultVoidT: LibJna.FfiResultVoid_t.ByValue) : - LibBase() { - - private val log: Logger = LoggerFactory.getLogger(VoidResult::class.java) - - fun value(): Unit { - val err = ffiResultVoidT.err!! - - when { - err > 0 -> { - throw FfiException(err) - } - else -> { - return - } - } - } - - protected fun finalize() { - libJna.free_void_result(ffiResultVoidT) - log.debug("$ffiResultVoidT freed") - } -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/BlockchainConfig.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/BlockchainConfig.kt deleted file mode 100644 index 5a7f5db..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/BlockchainConfig.kt +++ /dev/null @@ -1,26 +0,0 @@ -package org.bitcoindevkit.bdk - -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -abstract class BlockchainConfig : LibBase() { - private val log: Logger = LoggerFactory.getLogger(BlockchainConfig::class.java) - abstract val blockchainConfigT: LibJna.BlockchainConfig_t - - protected fun finalize() { - libJna.free_blockchain_config(blockchainConfigT) - log.debug("$blockchainConfigT freed") - } -} - -class ElectrumConfig( - url: String, - socks5: String?, - retry: Short, - timeout: Short, - stopGap: Long, -) : BlockchainConfig() { - - private val log: Logger = LoggerFactory.getLogger(ElectrumConfig::class.java) - override val blockchainConfigT = libJna.new_electrum_config(url, socks5, retry, timeout, stopGap) -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/DatabaseConfig.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/DatabaseConfig.kt deleted file mode 100644 index f163ff0..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/DatabaseConfig.kt +++ /dev/null @@ -1,26 +0,0 @@ -package org.bitcoindevkit.bdk - -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -abstract class DatabaseConfig : LibBase() { - private val log: Logger = LoggerFactory.getLogger(DatabaseConfig::class.java) - abstract val databaseConfigT: LibJna.DatabaseConfig_t - - protected fun finalize() { - libJna.free_database_config(databaseConfigT) - log.debug("$databaseConfigT freed") - } -} - -class MemoryConfig : DatabaseConfig() { - - private val log: Logger = LoggerFactory.getLogger(MemoryConfig::class.java) - override val databaseConfigT = libJna.new_memory_config() -} - -class SledConfig(path: String, treeName: String) : DatabaseConfig() { - - private val log: Logger = LoggerFactory.getLogger(SledConfig::class.java) - override val databaseConfigT = libJna.new_sled_config(path, treeName) -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/VecLocalUtxoResult.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/VecLocalUtxoResult.kt deleted file mode 100644 index 8a005f3..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/VecLocalUtxoResult.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.bitcoindevkit.bdk.wallet - -import org.bitcoindevkit.bdk.FfiException -import org.bitcoindevkit.bdk.LibBase -import org.bitcoindevkit.bdk.LibJna -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -class VecLocalUtxoResult(private val ffiResultVecLocalUtxoT: LibJna.FfiResultVec_LocalUtxo_t.ByValue) : - LibBase() { - - private val log: Logger = LoggerFactory.getLogger(VecLocalUtxoResult::class.java) - - fun value(): Array { - val err = ffiResultVecLocalUtxoT.err!! - val ok = ffiResultVecLocalUtxoT.ok!! - when { - err > 0 -> { - throw FfiException(err) - } - else -> { - val first = ok.ptr!! - return first.toArray(ok.len!!.toInt()) as Array - } - } - } - - protected fun finalize() { - libJna.free_veclocalutxo_result(ffiResultVecLocalUtxoT) - log.debug("$ffiResultVecLocalUtxoT freed") - } -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/VecTxDetailsResult.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/VecTxDetailsResult.kt deleted file mode 100644 index abee9a2..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/VecTxDetailsResult.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.bitcoindevkit.bdk.wallet - -import org.bitcoindevkit.bdk.FfiException -import org.bitcoindevkit.bdk.LibBase -import org.bitcoindevkit.bdk.LibJna -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -class VecTxDetailsResult(private val ffiResultVecTransactionDetailsT: LibJna.FfiResult_Vec_TransactionDetails_t.ByValue) : - LibBase() { - - private val log: Logger = LoggerFactory.getLogger(VecTxDetailsResult::class.java) - - fun value(): Array { - val err = ffiResultVecTransactionDetailsT.err!! - val ok = ffiResultVecTransactionDetailsT.ok!! - when { - err > 0 -> { - throw FfiException(err) - } - else -> { - val first = ok.ptr!! - return first.toArray(ok.len!!.toInt()) as Array - } - } - } - - protected fun finalize() { - libJna.free_vectxdetails_result(ffiResultVecTransactionDetailsT) - log.debug("$ffiResultVecTransactionDetailsT freed") - } -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/Wallet.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/Wallet.kt deleted file mode 100644 index 57db810..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/Wallet.kt +++ /dev/null @@ -1,65 +0,0 @@ -package org.bitcoindevkit.bdk.wallet - -import org.bitcoindevkit.bdk.BlockchainConfig -import org.bitcoindevkit.bdk.DatabaseConfig -import org.bitcoindevkit.bdk.LibBase -import org.bitcoindevkit.bdk.LibJna -import org.bitcoindevkit.bdk.types.StringResult -import org.bitcoindevkit.bdk.types.UInt64Result -import org.bitcoindevkit.bdk.types.VoidResult -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -enum class Network { - Bitcoin, - Testnet, - Signet, - Regtest, -} - -class Wallet constructor( - descriptor: String, - changeDescriptor: String?, - network: Network, - blockchainConfig: BlockchainConfig, - databaseConfig: DatabaseConfig, -) : LibBase() { - - val log: Logger = LoggerFactory.getLogger(Wallet::class.java) - - private val walletResult = WalletResult( - libJna.new_wallet_result( - descriptor, - changeDescriptor, - network.toString().lowercase(), - blockchainConfig.blockchainConfigT, - databaseConfig.databaseConfigT - ) - ) - private val wallet = walletResult.value() - - fun sync() { - val voidResult = VoidResult(libJna.sync_wallet(wallet)) - return voidResult.value() - } - - fun getAddress(): String { - val stringResult = StringResult(libJna.new_address(wallet)) - return stringResult.value() - } - - fun listUnspent(): Array { - val vecLocalUtxoResult = VecLocalUtxoResult(libJna.list_unspent(wallet)) - return vecLocalUtxoResult.value() - } - - fun balance(): Long { - val longResult = UInt64Result(libJna.balance(wallet)) - return longResult.value() - } - - fun listTransactionDetails(): Array { - val vecTxDetailsResult = VecTxDetailsResult(libJna.list_transactions((wallet))) - return vecTxDetailsResult.value() - } -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/WalletResult.kt b/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/WalletResult.kt deleted file mode 100644 index c574f27..0000000 --- a/bdk-kotlin/jvm/src/main/kotlin/org/bitcoindevkit/bdk/wallet/WalletResult.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.bitcoindevkit.bdk.wallet - -import org.bitcoindevkit.bdk.FfiException -import org.bitcoindevkit.bdk.LibBase -import org.bitcoindevkit.bdk.LibJna -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -class WalletResult constructor(private val ffiResultOpaqueWalletPtrT: LibJna.FfiResult_OpaqueWallet_ptr_t.ByValue) : - LibBase() { - - private val log: Logger = LoggerFactory.getLogger(WalletResult::class.java) - - fun value(): LibJna.OpaqueWallet_t { - val err = ffiResultOpaqueWalletPtrT.err!! - val ok = ffiResultOpaqueWalletPtrT.ok - when { - err > 0 -> { - throw FfiException(err) - } - else -> { - return ok!! - } - } - } - - protected fun finalize() { - libJna.free_wallet_result(ffiResultOpaqueWalletPtrT) - log.debug("$ffiResultOpaqueWalletPtrT freed") - } -} \ No newline at end of file diff --git a/bdk-kotlin/jvm/src/test/kotlin/org/bitcoindevkit/bdk/JvmLibTest.kt b/bdk-kotlin/jvm/src/test/kotlin/org/bitcoindevkit/bdk/JvmLibTest.kt deleted file mode 100644 index ddb4fb7..0000000 --- a/bdk-kotlin/jvm/src/test/kotlin/org/bitcoindevkit/bdk/JvmLibTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.bitcoindevkit.bdk - -import java.nio.file.Paths - -/** - * Library test, which will execute on linux host. - * - */ -class JvmLibTest : LibTest() { - - override fun getTestDataDir(): String { - //return Files.createTempDirectory("bdk-test").toString() - return Paths.get(System.getProperty("java.io.tmpdir"), "bdk-test").toString() - } - -} diff --git a/bdk-kotlin/settings.gradle b/bdk-kotlin/settings.gradle deleted file mode 100644 index b44156b..0000000 --- a/bdk-kotlin/settings.gradle +++ /dev/null @@ -1,3 +0,0 @@ -rootProject.name = 'bdk-kotlin' - -include ':jvm', ':android', ':test-fixtures' \ No newline at end of file diff --git a/bdk-kotlin/test-fixtures/build.gradle b/bdk-kotlin/test-fixtures/build.gradle deleted file mode 100644 index 2853edb..0000000 --- a/bdk-kotlin/test-fixtures/build.gradle +++ /dev/null @@ -1,19 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' - id 'java-library' -} - -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" - implementation(project(':jvm')) - implementation "junit:junit:4.13.2" - //implementation "org.mockito.kotlin:mockito-kotlin:3.2.0" - api "org.slf4j:slf4j-api:1.7.30" -} - -java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 -} \ No newline at end of file diff --git a/bdk-kotlin/test-fixtures/src/main/kotlin/org/bitcoindevkit/bdk/LibTest.kt b/bdk-kotlin/test-fixtures/src/main/kotlin/org/bitcoindevkit/bdk/LibTest.kt deleted file mode 100644 index 24d9b20..0000000 --- a/bdk-kotlin/test-fixtures/src/main/kotlin/org/bitcoindevkit/bdk/LibTest.kt +++ /dev/null @@ -1,135 +0,0 @@ -package org.bitcoindevkit.bdk - -import org.bitcoindevkit.bdk.wallet.Network -import org.bitcoindevkit.bdk.wallet.Wallet -import org.junit.Assert.* -import org.junit.Test -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import java.io.File - -/** - * Library tests which will execute for jvm and android modules. - */ -abstract class LibTest : LibBase() { - - private val log: Logger = LoggerFactory.getLogger(LibTest::class.java) - - val name = "test_wallet" - val desc = - "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)" - val change = - "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)" - val network = Network.Testnet - - val blockchainConfig = ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5, 30, 100) - val databaseConfig = MemoryConfig() - - abstract fun getTestDataDir(): String - - fun cleanupTestDataDir() { - File(getTestDataDir()).deleteRecursively() - } - - @Test - fun walletResultError() { - val jnaException = assertThrows(FfiException::class.java) { - Wallet("bad", "bad", network, blockchainConfig, databaseConfig) - } - assertEquals(jnaException.err, FfiError.Descriptor) - } - -// @Test -// fun walletResultFinalize() { -// run { -// val desc = -// "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)" -// val change = -// "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)" -// -// val blockchainConfig = ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5, 30) -// val databaseConfig = MemoryConfig() -// val wallet = Wallet(desc, change, blockchainConfig, databaseConfig) -// wallet.sync() -// assertNotNull(wallet.getAddress()) -// } -// System.gc() -// Thread.sleep(2000) -// // The only way to verify wallets freed is by checking the log -// } - - @Test - fun walletSync() { - val blockchainConfig = ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5, 30, 100) - val testDataDir = getTestDataDir() - // log.debug("testDataDir = $testDataDir") - val databaseConfig = SledConfig(testDataDir, "steve-test") - val wallet = Wallet(desc, change, network, blockchainConfig, databaseConfig) - wallet.sync() - cleanupTestDataDir() - } - - @Test - fun walletNewAddress() { - val wallet = Wallet(desc, change, network, blockchainConfig, databaseConfig) - val address = wallet.getAddress() - assertNotNull(address) - // log.debug("address created from kotlin: $address") - assertEquals(address, "tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e") - } - - @Test - fun walletUnspent() { - val wallet = Wallet(desc, change, network, blockchainConfig, databaseConfig) - wallet.sync() - val unspent = wallet.listUnspent() - assertTrue(unspent.isNotEmpty()) - - unspent.iterator().forEach { - //log.debug("unspent.outpoint.txid: ${it.outpoint!!.txid}") - assertNotNull(it.outpoint?.txid) - //log.debug("unspent.outpoint.vout: ${it.outpoint?.vout}") - assertTrue(it.outpoint?.vout!! >= 0) - //log.debug("unspent.txout.value: ${it.txout?.value}") - assertTrue(it.txout?.value!! > 0) - //log.debug("unspent.txout.script_pubkey: ${it.txout?.script_pubkey}") - assertNotNull(it.txout?.script_pubkey) - //log.debug("unspent.keychain: ${it.keychain}") - assertTrue(it.keychain!! >= 0) - } - } - - @Test - fun walletBalance() { - val wallet = Wallet(desc, change, network, blockchainConfig, databaseConfig) - wallet.sync() - val balance = wallet.balance() - //log.debug("balance from kotlin: $balance") - assertTrue(balance > 0) - } - - @Test - fun walletTxDetails() { - val wallet = Wallet(desc, change, network, blockchainConfig, databaseConfig) - wallet.sync() - val txDetails = wallet.listTransactionDetails() - assertTrue(txDetails.isNotEmpty()) - - txDetails.iterator().forEach { - //log.debug("txDetails.txid: ${it.txid}") - assertNotNull(it.txid) - //log.debug("txDetails.received: ${it.received}") - //log.debug("txDetails.sent: ${it.sent}") - assertTrue(it.received!! > 0 || it.sent!! > 0) - //log.debug("txDetails.fee: ${it.fee}") - assertTrue(it.fee!! > 0) - //log.debug("txDetails.is_confirmed: ${it.is_confirmed}") - assertTrue(it.is_confirmed!!) - assertNotNull(it.confirmation_time!!) - //log.debug("txDetails.confirmation_time.timestamp: ${it.confirmation_time!!.timestamp}") - assertTrue(it.confirmation_time!!.timestamp!! > 0) - //log.debug("txDetails.confirmation_time.height: ${it.confirmation_time!!.height}") - assertTrue(it.confirmation_time!!.height!! > 0) - } - } -} diff --git a/bdk-swift/.gitignore b/bdk-swift/.gitignore deleted file mode 100644 index bb460e7..0000000 --- a/bdk-swift/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -.DS_Store -/.build -/Packages -/*.xcodeproj -xcuserdata/ -DerivedData/ -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata diff --git a/bdk-swift/bdk.swift/.gitignore b/bdk-swift/bdk.swift/.gitignore deleted file mode 100644 index bb460e7..0000000 --- a/bdk-swift/bdk.swift/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -.DS_Store -/.build -/Packages -/*.xcodeproj -xcuserdata/ -DerivedData/ -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata diff --git a/bdk-swift/bdk.swift/Package.resolved b/bdk-swift/bdk.swift/Package.resolved deleted file mode 100644 index e1a027b..0000000 --- a/bdk-swift/bdk.swift/Package.resolved +++ /dev/null @@ -1,16 +0,0 @@ -{ - "object": { - "pins": [ - { - "package": "Clibbdkffi", - "repositoryURL": "/home/steve/git/notmandatory/Clibbdkffi", - "state": { - "branch": null, - "revision": "9c96e359a3b1e1d5c0db61125147f6ef929bf567", - "version": "0.1.0" - } - } - ] - }, - "version": 1 -} diff --git a/bdk-swift/bdk.swift/Package.swift b/bdk-swift/bdk.swift/Package.swift deleted file mode 100644 index 3a7987b..0000000 --- a/bdk-swift/bdk.swift/Package.swift +++ /dev/null @@ -1,28 +0,0 @@ -// swift-tools-version:5.5 -// The swift-tools-version declares the minimum version of Swift required to build this package. - -import PackageDescription - -let package = Package( - name: "bdk.swift", - products: [ - // Products define the executables and libraries a package produces, and make them visible to other packages. - .library( - name: "bdk.swift", - targets: ["bdk.swift"]), - ], - dependencies: [ - // Dependencies declare other packages that this package depends on. - .package(url: "../../../Clibbdkffi", from: "0.1.0"), - ], - targets: [ - // Targets are the basic building blocks of a package. A target can define a module or a test suite. - // Targets can depend on other targets in this package, and on products in packages this package depends on. - .target( - name: "bdk.swift", - dependencies: ["Clibbdkffi"]), - .testTarget( - name: "bdk.swiftTests", - dependencies: ["bdk.swift"]), - ] -) diff --git a/bdk-swift/bdk.swift/README.md b/bdk-swift/bdk.swift/README.md deleted file mode 100644 index a678238..0000000 --- a/bdk-swift/bdk.swift/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# bdk.swift - -To build: -``` -swift build -Xlinker -L../../target/debug -``` - -To test: -``` -swift test -Xlinker -L../../target/debug -``` diff --git a/bdk-swift/bdk.swift/Sources/bdk.swift/bdk_swift.swift b/bdk-swift/bdk.swift/Sources/bdk.swift/bdk_swift.swift deleted file mode 100644 index 3f0ecc0..0000000 --- a/bdk-swift/bdk.swift/Sources/bdk.swift/bdk_swift.swift +++ /dev/null @@ -1,8 +0,0 @@ -import Clibbdkffi - -public struct bdk_swift { - public private(set) var text = "Hello, World!" - - public init() { - } -} diff --git a/bdk-swift/bdk.swift/Tests/bdk.swiftTests/bdk_swiftTests.swift b/bdk-swift/bdk.swift/Tests/bdk.swiftTests/bdk_swiftTests.swift deleted file mode 100644 index 8070cc6..0000000 --- a/bdk-swift/bdk.swift/Tests/bdk.swiftTests/bdk_swiftTests.swift +++ /dev/null @@ -1,35 +0,0 @@ -import XCTest -import Clibbdkffi - -@testable import bdk_swift - -final class bdk_swiftTests: XCTestCase { - func testExample() throws { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct - // results. - XCTAssertEqual(bdk_swift().text, "Hello, World!") - let desc = "wpkh([bf988dd3/84'/1'/0']tpubDD7bHVspyCSvvU8qEycydF664NAX6EAPjJ77j9E614GU2zVdXgnZZo6JJjKbDT6fUn8owMN6TCP9rZMznsNEhJbpkEwp6fAyyoSqy3DH2Qj/0/*)"; - let change = "wpkh([bf988dd3/84'/1'/0']tpubDD7bHVspyCSvvU8qEycydF664NAX6EAPjJ77j9E614GU2zVdXgnZZo6JJjKbDT6fUn8owMN6TCP9rZMznsNEhJbpkEwp6fAyyoSqy3DH2Qj/1/*)"; - let net = "testnet"; - let blocks = "ssl://electrum.blockstream.info:60002"; - - let bc_config = new_electrum_config(blocks, nil, 5, 30, 100) - let db_config = new_memory_config() - - let wallet_result = new_wallet_result(desc,change,net,bc_config,db_config) - - free_blockchain_config(bc_config) - free_database_config(db_config) - - let wallet = wallet_result.ok - let sync_result = sync_wallet(wallet) - assert(sync_result.err == FFI_ERROR_NONE) - free_void_result(sync_result) - - let address1_result = new_address(wallet).ok - let address1 = String(cString: address1_result!, encoding: .utf8) - //print("address1 = \(address1!)") - assert(address1! == "tb1qh4ajvhz9nd76tqddnl99l89hx4dat33hrjauzw") - } -} diff --git a/targets/kotlin/build.gradle b/bindings/bdk-kotlin/build.gradle similarity index 100% rename from targets/kotlin/build.gradle rename to bindings/bdk-kotlin/build.gradle diff --git a/bdk-kotlin/gradle.properties b/bindings/bdk-kotlin/gradle.properties similarity index 100% rename from bdk-kotlin/gradle.properties rename to bindings/bdk-kotlin/gradle.properties diff --git a/bdk-kotlin/gradle/wrapper/gradle-wrapper.jar b/bindings/bdk-kotlin/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from bdk-kotlin/gradle/wrapper/gradle-wrapper.jar rename to bindings/bdk-kotlin/gradle/wrapper/gradle-wrapper.jar diff --git a/bdk-kotlin/gradle/wrapper/gradle-wrapper.properties b/bindings/bdk-kotlin/gradle/wrapper/gradle-wrapper.properties similarity index 92% rename from bdk-kotlin/gradle/wrapper/gradle-wrapper.properties rename to bindings/bdk-kotlin/gradle/wrapper/gradle-wrapper.properties index 0f80bbf..05679dc 100644 --- a/bdk-kotlin/gradle/wrapper/gradle-wrapper.properties +++ b/bindings/bdk-kotlin/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/bdk-kotlin/gradlew b/bindings/bdk-kotlin/gradlew similarity index 100% rename from bdk-kotlin/gradlew rename to bindings/bdk-kotlin/gradlew diff --git a/bdk-kotlin/gradlew.bat b/bindings/bdk-kotlin/gradlew.bat similarity index 100% rename from bdk-kotlin/gradlew.bat rename to bindings/bdk-kotlin/gradlew.bat diff --git a/targets/kotlin/src/main/kotlin/uniffi/bdk/bdk.kt b/bindings/bdk-kotlin/src/main/kotlin/uniffi/bdk/bdk.kt similarity index 100% rename from targets/kotlin/src/main/kotlin/uniffi/bdk/bdk.kt rename to bindings/bdk-kotlin/src/main/kotlin/uniffi/bdk/bdk.kt diff --git a/targets/kotlin/src/test/kotlin/uniffi/bdk/LibTest.kt b/bindings/bdk-kotlin/src/test/kotlin/uniffi/bdk/LibTest.kt similarity index 90% rename from targets/kotlin/src/test/kotlin/uniffi/bdk/LibTest.kt rename to bindings/bdk-kotlin/src/test/kotlin/uniffi/bdk/LibTest.kt index 1e161cd..9c9dcfb 100644 --- a/targets/kotlin/src/test/kotlin/uniffi/bdk/LibTest.kt +++ b/bindings/bdk-kotlin/src/test/kotlin/uniffi/bdk/LibTest.kt @@ -19,7 +19,7 @@ class LibTest { val address = wallet.getNewAddress() println("address:" + address) assertNotNull(address) - // log.debug("address created from kotlin: $address") + // log.debug("address created from bdk-kotlin: $address") assertEquals(address, "bcrt1qzg4mckdh50nwdm9hkzq06528rsu73hjxytqkxs") } } diff --git a/build.sh b/build.sh index 2ccb2a7..32f6369 100755 --- a/build.sh +++ b/build.sh @@ -32,27 +32,27 @@ build_cc() { cc cc/bdk_ffi_test.c -o cc/bdk_ffi_test -L target/debug -l bdk_ffi -l pthread -l dl -l m } -## copy to bdk-kotlin +## copy to bdk-bdk-kotlin copy_lib_kotlin() { echo -n "Copy " case $OS in "Darwin") echo -n "darwin " - mkdir -p bdk-kotlin/jvm/src/main/resources/darwin-x86-64 - cp target/debug/libbdk_ffi.dylib bdk-kotlin/jvm/src/main/resources/darwin-x86-64 + mkdir -p bdk-bdk-kotlin/jvm/src/main/resources/darwin-x86-64 + cp target/debug/libbdk_ffi.dylib bdk-bdk-kotlin/jvm/src/main/resources/darwin-x86-64 ;; "Linux") echo -n "linux " - mkdir -p bdk-kotlin/jvm/src/main/resources/linux-x86-64 - cp target/debug/libbdk_ffi.so bdk-kotlin/jvm/src/main/resources/linux-x86-64 + mkdir -p bdk-bdk-kotlin/jvm/src/main/resources/linux-x86-64 + cp target/debug/libbdk_ffi.so bdk-bdk-kotlin/jvm/src/main/resources/linux-x86-64 ;; esac echo "libs to kotlin sub-project" } -## bdk-kotlin jar +## bdk-bdk-kotlin jar build_kotlin() { - (cd bdk-kotlin && ./gradlew :jvm:build && ./gradlew :jvm:publishToMavenLocal) + (cd bdk-bdk-kotlin && ./gradlew :jvm:build && ./gradlew :jvm:publishToMavenLocal) } ## rust android @@ -69,27 +69,27 @@ build_android() { # IMPORTANT: make sure every target is not a substring of a different one. We check for them with grep later on BUILD_TARGETS="${BUILD_TARGETS:-aarch64,armv7,x86_64,i686}" - mkdir -p bdk-kotlin/android/src/main/jniLibs/ bdk-kotlin/android/src/main/jniLibs/arm64-v8a bdk-kotlin/android/src/main/jniLibs/x86_64 bdk-kotlin/android/src/main/jniLibs/armeabi-v7a bdk-kotlin/android/src/main/jniLibs/x86 + mkdir -p bdk-bdk-kotlin/android/src/main/jniLibs/ bdk-bdk-kotlin/android/src/main/jniLibs/arm64-v8a bdk-bdk-kotlin/android/src/main/jniLibs/x86_64 bdk-bdk-kotlin/android/src/main/jniLibs/armeabi-v7a bdk-bdk-kotlin/android/src/main/jniLibs/x86 if echo $BUILD_TARGETS | grep "aarch64"; then CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="aarch64-linux-android21-clang" CC="aarch64-linux-android21-clang" cargo build --target=aarch64-linux-android - cp target/aarch64-linux-android/debug/libbdk_ffi.so bdk-kotlin/android/src/main/jniLibs/arm64-v8a + cp target/aarch64-linux-android/debug/libbdk_ffi.so bdk-bdk-kotlin/android/src/main/jniLibs/arm64-v8a fi if echo $BUILD_TARGETS | grep "x86_64"; then CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="x86_64-linux-android21-clang" CC="x86_64-linux-android21-clang" cargo build --target=x86_64-linux-android - cp target/x86_64-linux-android/debug/libbdk_ffi.so bdk-kotlin/android/src/main/jniLibs/x86_64 + cp target/x86_64-linux-android/debug/libbdk_ffi.so bdk-bdk-kotlin/android/src/main/jniLibs/x86_64 fi if echo $BUILD_TARGETS | grep "armv7"; then CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="armv7a-linux-androideabi21-clang" CC="armv7a-linux-androideabi21-clang" cargo build --target=armv7-linux-androideabi - cp target/armv7-linux-androideabi/debug/libbdk_ffi.so bdk-kotlin/android/src/main/jniLibs/armeabi-v7a + cp target/armv7-linux-androideabi/debug/libbdk_ffi.so bdk-bdk-kotlin/android/src/main/jniLibs/armeabi-v7a fi if echo $BUILD_TARGETS | grep "i686"; then CARGO_TARGET_I686_LINUX_ANDROID_LINKER="i686-linux-android21-clang" CC="i686-linux-android21-clang" cargo build --target=i686-linux-android - cp target/i686-linux-android/debug/libbdk_ffi.so bdk-kotlin/android/src/main/jniLibs/x86 + cp target/i686-linux-android/debug/libbdk_ffi.so bdk-bdk-kotlin/android/src/main/jniLibs/x86 fi - # bdk-kotlin aar - (cd bdk-kotlin && ./gradlew :android:build && ./gradlew :android:publishToMavenLocal) + # bdk-bdk-kotlin aar + (cd bdk-bdk-kotlin && ./gradlew :android:build && ./gradlew :android:publishToMavenLocal) } OS=$(uname) diff --git a/cc/bdk_ffi.h b/cc/bdk_ffi.h deleted file mode 100644 index ea76ad8..0000000 --- a/cc/bdk_ffi.h +++ /dev/null @@ -1,315 +0,0 @@ -/*! \file */ -/******************************************* - * * - * File auto-generated by `::safer_ffi`. * - * * - * Do not manually edit this file. * - * * - *******************************************/ - -#ifndef __RUST_BDK_FFI__ -#define __RUST_BDK_FFI__ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct DatabaseConfig DatabaseConfig_t; - -DatabaseConfig_t * new_memory_config (void); - -DatabaseConfig_t * new_sled_config ( - char const * path, - char const * tree_name); - -void free_database_config ( - DatabaseConfig_t * database_config); - - -#include -#include - -/** \remark Has the same ABI as `uint16_t` **/ -#ifdef DOXYGEN -typedef enum FfiError -#else -typedef uint16_t FfiError_t; enum -#endif -{ - /** . */ - FFI_ERROR_NONE, - /** . */ - FFI_ERROR_INVALID_U32_BYTES, - /** . */ - FFI_ERROR_GENERIC, - /** . */ - FFI_ERROR_SCRIPT_DOESNT_HAVE_ADDRESS_FORM, - /** . */ - FFI_ERROR_NO_RECIPIENTS, - /** . */ - FFI_ERROR_NO_UTXOS_SELECTED, - /** . */ - FFI_ERROR_OUTPUT_BELOW_DUST_LIMIT, - /** . */ - FFI_ERROR_INSUFFICIENT_FUNDS, - /** . */ - FFI_ERROR_BN_B_TOTAL_TRIES_EXCEEDED, - /** . */ - FFI_ERROR_BN_B_NO_EXACT_MATCH, - /** . */ - FFI_ERROR_UNKNOWN_UTXO, - /** . */ - FFI_ERROR_TRANSACTION_NOT_FOUND, - /** . */ - FFI_ERROR_TRANSACTION_CONFIRMED, - /** . */ - FFI_ERROR_IRREPLACEABLE_TRANSACTION, - /** . */ - FFI_ERROR_FEE_RATE_TOO_LOW, - /** . */ - FFI_ERROR_FEE_TOO_LOW, - /** . */ - FFI_ERROR_FEE_RATE_UNAVAILABLE, - /** . */ - FFI_ERROR_MISSING_KEY_ORIGIN, - /** . */ - FFI_ERROR_KEY, - /** . */ - FFI_ERROR_CHECKSUM_MISMATCH, - /** . */ - FFI_ERROR_SPENDING_POLICY_REQUIRED, - /** . */ - FFI_ERROR_INVALID_POLICY_PATH_ERROR, - /** . */ - FFI_ERROR_SIGNER, - /** . */ - FFI_ERROR_INVALID_NETWORK, - /** . */ - FFI_ERROR_INVALID_PROGRESS_VALUE, - /** . */ - FFI_ERROR_PROGRESS_UPDATE_ERROR, - /** . */ - FFI_ERROR_INVALID_OUTPOINT, - /** . */ - FFI_ERROR_DESCRIPTOR, - /** . */ - FFI_ERROR_ADDRESS_VALIDATOR, - /** . */ - FFI_ERROR_ENCODE, - /** . */ - FFI_ERROR_MINISCRIPT, - /** . */ - FFI_ERROR_BIP32, - /** . */ - FFI_ERROR_SECP256K1, - /** . */ - FFI_ERROR_JSON, - /** . */ - FFI_ERROR_HEX, - /** . */ - FFI_ERROR_PSBT, - /** . */ - FFI_ERROR_PSBT_PARSE, - /** . */ - FFI_ERROR_ELECTRUM, - /** . */ - FFI_ERROR_SLED, -} -#ifdef DOXYGEN -FfiError_t -#endif -; - -typedef struct { - - char * ok; - - FfiError_t err; - -} FfiResult_char_ptr_t; - -void free_string_result ( - FfiResult_char_ptr_t string_result); - -typedef struct { - - FfiError_t err; - -} FfiResultVoid_t; - -void free_void_result ( - FfiResultVoid_t void_result); - -typedef struct { - - uint64_t ok; - - FfiError_t err; - -} FfiResult_uint64_t; - -void free_uint64_result ( - FfiResult_uint64_t void_result); - -/** \brief - * Free a Rust-allocated string - */ -void free_string ( - char * string); - -typedef struct BlockchainConfig BlockchainConfig_t; - -typedef struct OpaqueWallet OpaqueWallet_t; - -typedef struct { - - OpaqueWallet_t * ok; - - FfiError_t err; - -} FfiResult_OpaqueWallet_ptr_t; - -FfiResult_OpaqueWallet_ptr_t new_wallet_result ( - char const * descriptor, - char const * change_descriptor, - char const * network, - BlockchainConfig_t const * blockchain_config, - DatabaseConfig_t const * database_config); - -void free_wallet_result ( - FfiResult_OpaqueWallet_ptr_t wallet_result); - -FfiResultVoid_t sync_wallet ( - OpaqueWallet_t const * opaque_wallet); - -FfiResult_char_ptr_t new_address ( - OpaqueWallet_t const * opaque_wallet); - -typedef struct { - - char * txid; - - uint32_t vout; - -} OutPoint_t; - -typedef struct { - - uint64_t value; - - char * script_pubkey; - -} TxOut_t; - -typedef struct { - - OutPoint_t outpoint; - - TxOut_t txout; - - uint16_t keychain; - -} LocalUtxo_t; - -/** \brief - * Same as [`Vec`][`rust::Vec`], but with guaranteed `#[repr(C)]` layout - */ -typedef struct { - - LocalUtxo_t * ptr; - - size_t len; - - size_t cap; - -} Vec_LocalUtxo_t; - -typedef struct { - - Vec_LocalUtxo_t ok; - - FfiError_t err; - -} FfiResult_Vec_LocalUtxo_t; - -FfiResult_Vec_LocalUtxo_t list_unspent ( - OpaqueWallet_t const * opaque_wallet); - -void free_veclocalutxo_result ( - FfiResult_Vec_LocalUtxo_t unspent_result); - -FfiResult_uint64_t balance ( - OpaqueWallet_t const * opaque_wallet); - - -#include - -typedef struct { - - uint32_t height; - - uint64_t timestamp; - -} ConfirmationTime_t; - -typedef struct { - - char * txid; - - uint64_t received; - - uint64_t sent; - - int64_t fee; - - bool is_confirmed; - - ConfirmationTime_t confirmation_time; - - bool verified; - -} TransactionDetails_t; - -/** \brief - * Same as [`Vec`][`rust::Vec`], but with guaranteed `#[repr(C)]` layout - */ -typedef struct { - - TransactionDetails_t * ptr; - - size_t len; - - size_t cap; - -} Vec_TransactionDetails_t; - -typedef struct { - - Vec_TransactionDetails_t ok; - - FfiError_t err; - -} FfiResult_Vec_TransactionDetails_t; - -FfiResult_Vec_TransactionDetails_t list_transactions ( - OpaqueWallet_t const * opaque_wallet); - -void free_vectxdetails_result ( - FfiResult_Vec_TransactionDetails_t txdetails_result); - -BlockchainConfig_t * new_electrum_config ( - char const * url, - char const * socks5, - int16_t retry, - int16_t timeout, - size_t stop_gap); - -void free_blockchain_config ( - BlockchainConfig_t * blockchain_config); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* __RUST_BDK_FFI__ */ diff --git a/cc/bdk_ffi_test.c b/cc/bdk_ffi_test.c deleted file mode 100644 index cc10627..0000000 --- a/cc/bdk_ffi_test.c +++ /dev/null @@ -1,199 +0,0 @@ -#include -#include -#include -#include -#include "bdk_ffi.h" - -int main (int argc, char const * const argv[]) -{ - - // shared consts - char const *desc = "wpkh([bf988dd3/84'/1'/0']tpubDD7bHVspyCSvvU8qEycydF664NAX6EAPjJ77j9E614GU2zVdXgnZZo6JJjKbDT6fUn8owMN6TCP9rZMznsNEhJbpkEwp6fAyyoSqy3DH2Qj/0/*)"; - char const *change = "wpkh([bf988dd3/84'/1'/0']tpubDD7bHVspyCSvvU8qEycydF664NAX6EAPjJ77j9E614GU2zVdXgnZZo6JJjKbDT6fUn8owMN6TCP9rZMznsNEhJbpkEwp6fAyyoSqy3DH2Qj/1/*)"; - char const *net = "testnet"; - char const *blocks = "ssl://electrum.blockstream.info:60002"; - - // test new wallet error - { - BlockchainConfig_t *bc_config = new_electrum_config(blocks, NULL, 5, 30, 100); - //DatabaseConfig_t *db_config = new_sled_config("/home/steve/.bdk", "test_wallet"); - DatabaseConfig_t *db_config = new_memory_config(); - - // new wallet with bad descriptor - FfiResult_OpaqueWallet_ptr_t wallet_result = new_wallet_result("bad","bad",net,bc_config,db_config); - assert(wallet_result.err == FFI_ERROR_DESCRIPTOR); - assert(wallet_result.ok == NULL); - - free_blockchain_config(bc_config); - free_database_config(db_config); - - free_wallet_result(wallet_result); - } - - // test new wallet - { - BlockchainConfig_t *bc_config = new_electrum_config(blocks, NULL, 5, 30, 100); - DatabaseConfig_t *db_config = new_memory_config(); - - // new wallet - FfiResult_OpaqueWallet_ptr_t wallet_result = new_wallet_result(desc,change,net,bc_config,db_config); - // printf("wallet_result.err = %d\n", wallet_result.err)); - assert(wallet_result.err == FFI_ERROR_NONE); - assert(wallet_result.ok != NULL); - - free_blockchain_config(bc_config); - free_database_config(db_config); - - OpaqueWallet_t *wallet = wallet_result.ok; - - // sync wallet - FfiResultVoid_t sync_result = sync_wallet(wallet); - assert(sync_result.err == FFI_ERROR_NONE); - free_void_result(sync_result); - - // new address - FfiResult_char_ptr_t address1_result = new_address(wallet); - assert(address1_result.ok != NULL); - assert(address1_result.err == FFI_ERROR_NONE); - //printf("address1 = %s\n", address1_result.ok); - assert( 0 == strcmp(address1_result.ok,"tb1qh4ajvhz9nd76tqddnl99l89hx4dat33hrjauzw")); - free_string_result(address1_result); - - FfiResult_char_ptr_t address2_result = new_address(wallet); - assert(address2_result.ok != NULL); - assert(address2_result.err == FFI_ERROR_NONE); - //printf("address2 = %s\n", address2_result.ok); - assert( 0 == strcmp(address2_result.ok,"tb1qr7pu0pech43hcjrc4pzxcen0qkslj7xk7s5w3m")); - free_string_result(address2_result); - - // free_wallet - free_wallet_result(wallet_result); - - // verify free_wallet after free_wallet fails (core dumped) - //// free_wallet_result(wallet_result); - - // verify sync_wallet after free_wallet fails (core dumped) - //// FfiResultVoid_t sync_result2 = sync_wallet(wallet); - } - - // test get unspent utxos - { - BlockchainConfig_t *bc_config = new_electrum_config(blocks, NULL, 5, 30, 100); - DatabaseConfig_t *db_config = new_memory_config(); - - // new wallet - FfiResult_OpaqueWallet_ptr_t wallet_result = new_wallet_result(desc,change,net,bc_config,db_config); - assert(wallet_result.err == FFI_ERROR_NONE); - assert(wallet_result.ok != NULL); - - free_blockchain_config(bc_config); - free_database_config(db_config); - - OpaqueWallet_t *wallet = wallet_result.ok; - - // sync wallet - FfiResultVoid_t sync_result = sync_wallet(wallet); - assert(sync_result.err == FFI_ERROR_NONE); - free_void_result(sync_result); - - // list unspent - FfiResult_Vec_LocalUtxo_t unspent_result = list_unspent(wallet); - assert(unspent_result.ok.len == 1); - assert(unspent_result.err == FFI_ERROR_NONE); - - LocalUtxo_t * unspent_ptr = unspent_result.ok.ptr; - for (int i = 0; i < unspent_result.ok.len; i++) { - // printf("%d: outpoint.txid: %s\n", i, unspent_ptr[i].outpoint.txid); - assert(unspent_ptr[i].outpoint.txid != NULL); - // printf("%d: outpoint.vout: %d\n", i, unspent_ptr[i].outpoint.vout); - assert(unspent_ptr[i].outpoint.vout >= 0); - // printf("%d: txout.value: %ld\n", i, unspent_ptr[i].txout.value); - assert(unspent_ptr[i].txout.value > 0); - // printf("%d: txout.script_pubkey: %s\n", i, unspent_ptr[i].txout.script_pubkey); - assert(unspent_ptr[i].txout.script_pubkey != NULL); - // printf("%d: keychain: %d\n", i, unspent_ptr[i].keychain); - assert(unspent_ptr[i].keychain >= 0); - } - - free_veclocalutxo_result(unspent_result); - free_wallet_result(wallet_result); - } - - // test balance - { - BlockchainConfig_t *bc_config = new_electrum_config(blocks, NULL, 5, 30, 100); - DatabaseConfig_t *db_config = new_memory_config(); - - // new wallet - FfiResult_OpaqueWallet_ptr_t wallet_result = new_wallet_result(desc,change,net,bc_config,db_config); - assert(wallet_result.err == FFI_ERROR_NONE); - assert(wallet_result.ok != NULL); - - free_blockchain_config(bc_config); - free_database_config(db_config); - - OpaqueWallet_t *wallet = wallet_result.ok; - - // sync wallet - FfiResultVoid_t sync_result = sync_wallet(wallet); - assert(sync_result.err == FFI_ERROR_NONE); - free_void_result(sync_result); - - // get balance - FfiResult_uint64_t balance_result = balance(wallet); - //printf("balance.err = %d\n", (balance_result.err)); - assert(balance_result.err == FFI_ERROR_NONE); - //printf("balance.ok = %ld\n", balance_result.ok); - assert(balance_result.ok > 0); - - // free balance and wallet results - free_uint64_result(balance_result); - free_wallet_result(wallet_result); - } - - // test get transaction details - { - BlockchainConfig_t *bc_config = new_electrum_config(blocks, NULL, 5, 30, 100); - DatabaseConfig_t *db_config = new_memory_config(); - - // new wallet - FfiResult_OpaqueWallet_ptr_t wallet_result = new_wallet_result(desc,change,net,bc_config,db_config); - assert(wallet_result.err == FFI_ERROR_NONE); - assert(wallet_result.ok != NULL); - - free_blockchain_config(bc_config); - free_database_config(db_config); - - OpaqueWallet_t *wallet = wallet_result.ok; - - // sync wallet - FfiResultVoid_t sync_result = sync_wallet(wallet); - assert(sync_result.err == FFI_ERROR_NONE); - free_void_result(sync_result); - - // list transactions - FfiResult_Vec_TransactionDetails_t txdetails_result = list_transactions(wallet); - assert(txdetails_result.ok.len > 0); - assert(txdetails_result.err == FFI_ERROR_NONE); - - TransactionDetails_t * txdetails_ptr = txdetails_result.ok.ptr; - for (int i = 0; i < txdetails_result.ok.len; i++) { - //printf("%d: txid: %s\n", i, txdetails_ptr[i].txid); - assert(txdetails_ptr[i].txid != NULL); - //printf("%d: timestamp: %ld\n", i, txdetails_ptr[i].timestamp); - assert(txdetails_ptr[i].is_confirmed); - //printf("%d: received: %ld\n", i, txdetails_ptr[i].received); - //printf("%d: sent: %ld\n", i, txdetails_ptr[i].sent); - assert(txdetails_ptr[i].received > 0 || txdetails_ptr[i].sent > 0); - //printf("%d: fees: %ld\n", i, txdetails_ptr[i].fees); - assert(txdetails_ptr[i].fee > 0); - //printf("%d: height: %d\n", i, txdetails_ptr[i].height); - assert(txdetails_ptr[i].confirmation_time.height > 0); - } - - free_vectxdetails_result(txdetails_result); - free_wallet_result(wallet_result); - } - - return EXIT_SUCCESS; -} diff --git a/src/error.rs b/src/error.rs deleted file mode 100644 index 737ff62..0000000 --- a/src/error.rs +++ /dev/null @@ -1,134 +0,0 @@ -use bdk::Error; -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum FfiError { - #[error("data store disconnected")] - None, - #[error("data store disconnected")] - InvalidU32Bytes, - #[error("data store disconnected")] - Generic, - #[error("data store disconnected")] - ScriptDoesntHaveAddressForm, - #[error("data store disconnected")] - NoRecipients, - #[error("data store disconnected")] - NoUtxosSelected, - #[error("data store disconnected")] - OutputBelowDustLimit, - #[error("data store disconnected")] - InsufficientFunds, - #[error("data store disconnected")] - BnBTotalTriesExceeded, - #[error("data store disconnected")] - BnBNoExactMatch, - #[error("data store disconnected")] - UnknownUtxo, - #[error("data store disconnected")] - TransactionNotFound, - #[error("data store disconnected")] - TransactionConfirmed, - #[error("data store disconnected")] - IrreplaceableTransaction, - #[error("data store disconnected")] - FeeRateTooLow, - #[error("data store disconnected")] - FeeTooLow, - #[error("data store disconnected")] - FeeRateUnavailable, - #[error("data store disconnected")] - MissingKeyOrigin, - #[error("data store disconnected")] - Key, - #[error("data store disconnected")] - ChecksumMismatch, - #[error("data store disconnected")] - SpendingPolicyRequired, - #[error("data store disconnected")] - InvalidPolicyPathError, - #[error("data store disconnected")] - Signer, - #[error("data store disconnected")] - InvalidNetwork, - #[error("data store disconnected")] - InvalidProgressValue, - #[error("data store disconnected")] - ProgressUpdateError, - #[error("data store disconnected")] - InvalidOutpoint, - #[error("data store disconnected")] - Descriptor, - #[error("data store disconnected")] - AddressValidator, - #[error("data store disconnected")] - Encode, - #[error("data store disconnected")] - Miniscript, - #[error("data store disconnected")] - Bip32, - #[error("data store disconnected")] - Secp256k1, - #[error("data store disconnected")] - Json, - #[error("data store disconnected")] - Hex, - #[error("data store disconnected")] - Psbt, - #[error("data store disconnected")] - PsbtParse, - #[error("data store disconnected")] - Electrum, - // Esplora, - // CompactFilters, - #[error("data store disconnected")] - Sled, -} - -impl From for FfiError { - fn from(error: bdk::Error) -> Self { - match error { - Error::InvalidU32Bytes(_) => FfiError::InvalidU32Bytes, - Error::Generic(_) => FfiError::Generic, - Error::ScriptDoesntHaveAddressForm => FfiError::ScriptDoesntHaveAddressForm, - Error::NoRecipients => FfiError::NoRecipients, - Error::NoUtxosSelected => FfiError::NoUtxosSelected, - Error::OutputBelowDustLimit(_) => FfiError::OutputBelowDustLimit, - Error::InsufficientFunds { .. } => FfiError::InsufficientFunds, - Error::BnBTotalTriesExceeded => FfiError::BnBTotalTriesExceeded, - Error::BnBNoExactMatch => FfiError::BnBNoExactMatch, - Error::UnknownUtxo => FfiError::UnknownUtxo, - Error::TransactionNotFound => FfiError::TransactionNotFound, - Error::TransactionConfirmed => FfiError::TransactionConfirmed, - Error::IrreplaceableTransaction => FfiError::IrreplaceableTransaction, - Error::FeeRateTooLow { .. } => FfiError::FeeRateTooLow, - Error::FeeTooLow { .. } => FfiError::FeeTooLow, - Error::FeeRateUnavailable => FfiError::FeeRateUnavailable, - Error::MissingKeyOrigin(_) => FfiError::MissingKeyOrigin, - Error::Key(_) => FfiError::Key, - Error::ChecksumMismatch => FfiError::ChecksumMismatch, - Error::SpendingPolicyRequired(_) => FfiError::SpendingPolicyRequired, - Error::InvalidPolicyPathError(_) => FfiError::InvalidPolicyPathError, - Error::Signer(_) => FfiError::Signer, - Error::InvalidNetwork { .. } => FfiError::InvalidNetwork, - Error::InvalidProgressValue(_) => FfiError::InvalidProgressValue, - Error::ProgressUpdateError => FfiError::ProgressUpdateError, - Error::InvalidOutpoint(_) => FfiError::InvalidOutpoint, - Error::Descriptor(_) => FfiError::Descriptor, - Error::AddressValidator(_) => FfiError::AddressValidator, - Error::Encode(_) => FfiError::Encode, - Error::Miniscript(_) => FfiError::Miniscript, - Error::Bip32(_) => FfiError::Bip32, - Error::Secp256k1(_) => FfiError::Secp256k1, - Error::Json(_) => FfiError::Json, - Error::Hex(_) => FfiError::Hex, - Error::Psbt(_) => FfiError::Psbt, - Error::PsbtParse(_) => FfiError::PsbtParse, - Error::Electrum(_) => FfiError::Electrum, - // Error::Esplora(_) => JniError::Esplora, - // Error::CompactFilters(_) => JniError::CompactFilters, - // Error::Rpc(_) => JniError::Rpc, - Error::Sled(_) => FfiError::Sled, - } - } -} diff --git a/src/types.rs b/src/types.rs deleted file mode 100644 index 241cb42..0000000 --- a/src/types.rs +++ /dev/null @@ -1,40 +0,0 @@ -use crate::error::FfiError; -use ::safer_ffi::prelude::*; -use safer_ffi::char_p::char_p_boxed; - -#[derive_ReprC] -#[repr(C)] -#[derive(Debug)] -pub struct FfiResult { - pub ok: T, - pub err: FfiError, -} - -#[derive_ReprC] -#[repr(C)] -#[derive(Debug)] -pub struct FfiResultVoid { - pub err: FfiError, -} - -#[ffi_export] -fn free_string_result(string_result: FfiResult) { - drop(string_result) -} - -#[ffi_export] -fn free_void_result(void_result: FfiResultVoid) { - drop(void_result) -} - -#[ffi_export] -fn free_uint64_result(void_result: FfiResult) { - drop(void_result) -} - -// TODO do we need this? remove? -/// Free a Rust-allocated string -#[ffi_export] -fn free_string(string: Option) { - drop(string) -} diff --git a/src/uniffi/bdk/bdk.kt b/src/uniffi/bdk/bdk.kt deleted file mode 100644 index eedd389..0000000 --- a/src/uniffi/bdk/bdk.kt +++ /dev/null @@ -1,602 +0,0 @@ -// This file was autogenerated by some hot garbage in the `uniffi` crate. -// Trust me, you don't want to mess with it! - -@file:Suppress("NAME_SHADOWING") - -package uniffi.bdk; - -// Common helper code. -// -// Ideally this would live in a separate .kt file where it can be unittested etc -// in isolation, and perhaps even published as a re-useable package. -// -// However, it's important that the detils of how this helper code works (e.g. the -// way that different builtin types are passed across the FFI) exactly match what's -// expected by the Rust code on the other side of the interface. In practice right -// now that means coming from the exact some version of `uniffi` that was used to -// compile the Rust component. The easiest way to ensure this is to bundle the Kotlin -// helpers directly inline like we're doing here. - -import com.sun.jna.Library -import com.sun.jna.Native -import com.sun.jna.Pointer -import com.sun.jna.Structure -import java.nio.ByteBuffer -import java.nio.ByteOrder -import java.util.concurrent.atomic.AtomicLong -import java.util.concurrent.atomic.AtomicBoolean -import java.util.concurrent.atomic.AtomicReference -import java.util.concurrent.locks.ReentrantLock -import kotlin.concurrent.withLock - -// This is a helper for safely working with byte buffers returned from the Rust code. -// A rust-owned buffer is represented by its capacity, its current length, and a -// pointer to the underlying data. - -@Structure.FieldOrder("capacity", "len", "data") -open class RustBuffer : Structure() { - @JvmField var capacity: Int = 0 - @JvmField var len: Int = 0 - @JvmField var data: Pointer? = null - - class ByValue : RustBuffer(), Structure.ByValue - class ByReference : RustBuffer(), Structure.ByReference - - companion object { - internal fun alloc(size: Int = 0) = rustCall() { status -> - _UniFFILib.INSTANCE.ffi_bdk_ed55_rustbuffer_alloc(size, status) - } - - internal fun free(buf: RustBuffer.ByValue) = rustCall() { status -> - _UniFFILib.INSTANCE.ffi_bdk_ed55_rustbuffer_free(buf, status) - } - - internal fun reserve(buf: RustBuffer.ByValue, additional: Int) = rustCall() { status -> - _UniFFILib.INSTANCE.ffi_bdk_ed55_rustbuffer_reserve(buf, additional, status) - } - } - - @Suppress("TooGenericExceptionThrown") - fun asByteBuffer() = - this.data?.getByteBuffer(0, this.len.toLong())?.also { - it.order(ByteOrder.BIG_ENDIAN) - } -} - -// This is a helper for safely passing byte references into the rust code. -// It's not actually used at the moment, because there aren't many things that you -// can take a direct pointer to in the JVM, and if we're going to copy something -// then we might as well copy it into a `RustBuffer`. But it's here for API -// completeness. - -@Structure.FieldOrder("len", "data") -open class ForeignBytes : Structure() { - @JvmField var len: Int = 0 - @JvmField var data: Pointer? = null - - class ByValue : ForeignBytes(), Structure.ByValue -} - - -// A helper for structured writing of data into a `RustBuffer`. -// This is very similar to `java.nio.ByteBuffer` but it knows how to grow -// the underlying `RustBuffer` on demand. -// -// TODO: we should benchmark writing things into a `RustBuffer` versus building -// up a bytearray and then copying it across. - -class RustBufferBuilder() { - var rbuf = RustBuffer.ByValue() - var bbuf: ByteBuffer? = null - - init { - val rbuf = RustBuffer.alloc(16) // Totally arbitrary initial size - rbuf.writeField("len", 0) - this.setRustBuffer(rbuf) - } - - internal fun setRustBuffer(rbuf: RustBuffer.ByValue) { - this.rbuf = rbuf - this.bbuf = this.rbuf.data?.getByteBuffer(0, this.rbuf.capacity.toLong())?.also { - it.order(ByteOrder.BIG_ENDIAN) - it.position(rbuf.len) - } - } - - fun finalize() : RustBuffer.ByValue { - val rbuf = this.rbuf - // Ensure that the JVM-level field is written through to native memory - // before turning the buffer, in case its recipient uses it in a context - // JNA doesn't apply its automatic synchronization logic. - rbuf.writeField("len", this.bbuf!!.position()) - this.setRustBuffer(RustBuffer.ByValue()) - return rbuf - } - - fun discard() { - val rbuf = this.finalize() - RustBuffer.free(rbuf) - } - - internal fun reserve(size: Int, write: (ByteBuffer) -> Unit) { - // TODO: this will perform two checks to ensure we're not overflowing the buffer: - // one here where we check if it needs to grow, and another when we call a write - // method on the ByteBuffer. It might be cheaper to use exception-driven control-flow - // here, trying the write and growing if it throws a `BufferOverflowException`. - // Benchmarking needed. - if (this.bbuf!!.position() + size > this.rbuf.capacity) { - rbuf.writeField("len", this.bbuf!!.position()) - this.setRustBuffer(RustBuffer.reserve(this.rbuf, size)) - } - write(this.bbuf!!) - } - - fun putByte(v: Byte) { - this.reserve(1) { bbuf -> - bbuf.put(v) - } - } - - fun putShort(v: Short) { - this.reserve(2) { bbuf -> - bbuf.putShort(v) - } - } - - fun putInt(v: Int) { - this.reserve(4) { bbuf -> - bbuf.putInt(v) - } - } - - fun putLong(v: Long) { - this.reserve(8) { bbuf -> - bbuf.putLong(v) - } - } - - fun putFloat(v: Float) { - this.reserve(4) { bbuf -> - bbuf.putFloat(v) - } - } - - fun putDouble(v: Double) { - this.reserve(8) { bbuf -> - bbuf.putDouble(v) - } - } - - fun put(v: ByteArray) { - this.reserve(v.size) { bbuf -> - bbuf.put(v) - } - } -} - -// Helpers for reading primitive data types from a bytebuffer. - -internal fun liftFromRustBuffer(rbuf: RustBuffer.ByValue, readItem: (ByteBuffer) -> T): T { - val buf = rbuf.asByteBuffer()!! - try { - val item = readItem(buf) - if (buf.hasRemaining()) { - throw RuntimeException("junk remaining in buffer after lifting, something is very wrong!!") - } - return item - } finally { - RustBuffer.free(rbuf) - } -} - -internal fun lowerIntoRustBuffer(v: T, writeItem: (T, RustBufferBuilder) -> Unit): RustBuffer.ByValue { - // TODO: maybe we can calculate some sort of initial size hint? - val buf = RustBufferBuilder() - try { - writeItem(v, buf) - return buf.finalize() - } catch (e: Throwable) { - buf.discard() - throw e - } -} - -// For every type used in the interface, we provide helper methods for conveniently -// lifting and lowering that type from C-compatible data, and for reading and writing -// values of that type in a buffer. - - - - -internal fun String.Companion.lift(rbuf: RustBuffer.ByValue): String { - try { - val byteArr = ByteArray(rbuf.len) - rbuf.asByteBuffer()!!.get(byteArr) - return byteArr.toString(Charsets.UTF_8) - } finally { - RustBuffer.free(rbuf) - } -} - -internal fun String.Companion.read(buf: ByteBuffer): String { - val len = buf.getInt() - val byteArr = ByteArray(len) - buf.get(byteArr) - return byteArr.toString(Charsets.UTF_8) -} - -internal fun String.lower(): RustBuffer.ByValue { - val byteArr = this.toByteArray(Charsets.UTF_8) - // Ideally we'd pass these bytes to `ffi_bytebuffer_from_bytes`, but doing so would require us - // to copy them into a JNA `Memory`. So we might as well directly copy them into a `RustBuffer`. - val rbuf = RustBuffer.alloc(byteArr.size) - rbuf.asByteBuffer()!!.put(byteArr) - return rbuf -} - -internal fun String.write(buf: RustBufferBuilder) { - val byteArr = this.toByteArray(Charsets.UTF_8) - buf.putInt(byteArr.size) - buf.put(byteArr) -} - - - - - - - - - - -@Synchronized -fun findLibraryName(componentName: String): String { - val libOverride = System.getProperty("uniffi.component.${componentName}.libraryOverride") - if (libOverride != null) { - return libOverride - } - return "uniffi_bdk" -} - -inline fun loadIndirect( - componentName: String -): Lib { - return Native.load(findLibraryName(componentName), Lib::class.java) -} - -// A JNA Library to expose the extern-C FFI definitions. -// This is an implementation detail which will be called internally by the public API. - -internal interface _UniFFILib : Library { - companion object { - internal val INSTANCE: _UniFFILib by lazy { - loadIndirect<_UniFFILib>(componentName = "bdk") - - - } - } - - fun ffi_bdk_ed55_OfflineWallet_object_free(ptr: Pointer, - uniffi_out_err: RustCallStatus - ): Unit - - fun bdk_ed55_OfflineWallet_new(descriptor: RustBuffer.ByValue, - uniffi_out_err: RustCallStatus - ): Pointer - - fun ffi_bdk_ed55_rustbuffer_alloc(size: Int, - uniffi_out_err: RustCallStatus - ): RustBuffer.ByValue - - fun ffi_bdk_ed55_rustbuffer_from_bytes(bytes: ForeignBytes.ByValue, - uniffi_out_err: RustCallStatus - ): RustBuffer.ByValue - - fun ffi_bdk_ed55_rustbuffer_free(buf: RustBuffer.ByValue, - uniffi_out_err: RustCallStatus - ): Unit - - fun ffi_bdk_ed55_rustbuffer_reserve(buf: RustBuffer.ByValue,additional: Int, - uniffi_out_err: RustCallStatus - ): RustBuffer.ByValue - - -} - -// A handful of classes and functions to support the generated data structures. -// This would be a good candidate for isolating in its own ffi-support lib. - - - -// Interface implemented by anything that can contain an object reference. -// -// Such types expose a `destroy()` method that must be called to cleanly -// dispose of the contained objects. Failure to call this method may result -// in memory leaks. -// -// The easiest way to ensure this method is called is to use the `.use` -// helper method to execute a block and destroy the object at the end. -interface Disposable { - fun destroy() -} - -inline fun T.use(block: (T) -> R) = - try { - block(this) - } finally { - try { - // N.B. our implementation is on the nullable type `Disposable?`. - this?.destroy() - } catch (e: Throwable) { - // swallow - } - } - -// The base class for all UniFFI Object types. -// -// This class provides core operations for working with the Rust `Arc` pointer to -// the live Rust struct on the other side of the FFI. -// -// There's some subtlety here, because we have to be careful not to operate on a Rust -// struct after it has been dropped, and because we must expose a public API for freeing -// the Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: -// -// * Each `FFIObject` instance holds an opaque pointer to the underlying Rust struct. -// Method calls need to read this pointer from the object's state and pass it in to -// the Rust FFI. -// -// * When an `FFIObject` is no longer needed, its pointer should be passed to a -// special destructor function provided by the Rust FFI, which will drop the -// underlying Rust struct. -// -// * Given an `FFIObject` instance, calling code is expected to call the special -// `destroy` method in order to free it after use, either by calling it explicitly -// or by using a higher-level helper like the `use` method. Failing to do so will -// leak the underlying Rust struct. -// -// * We can't assume that calling code will do the right thing, and must be prepared -// to handle Kotlin method calls executing concurrently with or even after a call to -// `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. -// -// * We must never allow Rust code to operate on the underlying Rust struct after -// the destructor has been called, and must never call the destructor more than once. -// Doing so may trigger memory unsafety. -// -// If we try to implement this with mutual exclusion on access to the pointer, there is the -// possibility of a race between a method call and a concurrent call to `destroy`: -// -// * Thread A starts a method call, reads the value of the pointer, but is interrupted -// before it can pass the pointer over the FFI to Rust. -// * Thread B calls `destroy` and frees the underlying Rust struct. -// * Thread A resumes, passing the already-read pointer value to Rust and triggering -// a use-after-free. -// -// One possible solution would be to use a `ReadWriteLock`, with each method call taking -// a read lock (and thus allowed to run concurrently) and the special `destroy` method -// taking a write lock (and thus blocking on live method calls). However, we aim not to -// generate methods with any hidden blocking semantics, and a `destroy` method that might -// block if called incorrectly seems to meet that bar. -// -// So, we achieve our goals by giving each `FFIObject` an associated `AtomicLong` counter to track -// the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` -// has been called. These are updated according to the following rules: -// -// * The initial value of the counter is 1, indicating a live object with no in-flight calls. -// The initial value for the flag is false. -// -// * At the start of each method call, we atomically check the counter. -// If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. -// If it is nonzero them we atomically increment it by 1 and proceed with the method call. -// -// * At the end of each method call, we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// * When `destroy` is called, we atomically flip the flag from false to true. -// If the flag was already true we silently fail. -// Otherwise we atomically decrement and check the counter. -// If it has reached zero then we destroy the underlying Rust struct. -// -// Astute readers may observe that this all sounds very similar to the way that Rust's `Arc` works, -// and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. -// -// The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been -// called *and* all in-flight method calls have completed, avoiding violating any of the expectations -// of the underlying Rust code. -// -// In the future we may be able to replace some of this with automatic finalization logic, such as using -// the new "Cleaner" functionaility in Java 9. The above scheme has been designed to work even if `destroy` is -// invoked by garbage-collection machinery rather than by calling code (which by the way, it's apparently also -// possible for the JVM to finalize an object while there is an in-flight call to one of its methods [1], -// so there would still be some complexity here). -// -// Sigh...all of this for want of a robust finalization mechanism. -// -// [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 -// -abstract class FFIObject( - protected val pointer: Pointer -): Disposable, AutoCloseable { - - val wasDestroyed = AtomicBoolean(false) - val callCounter = AtomicLong(1) - - open protected fun freeRustArcPtr() { - // To be overridden in subclasses. - } - - override fun destroy() { - // Only allow a single call to this method. - // TODO: maybe we should log a warning if called more than once? - if (this.wasDestroyed.compareAndSet(false, true)) { - // This decrement always matches the initial count of 1 given at creation time. - if (this.callCounter.decrementAndGet() == 0L) { - this.freeRustArcPtr() - } - } - } - - @Synchronized - override fun close() { - this.destroy() - } - - internal inline fun callWithPointer(block: (ptr: Pointer) -> R): R { - // Check and increment the call counter, to keep the object alive. - // This needs a compare-and-set retry loop in case of concurrent updates. - do { - val c = this.callCounter.get() - if (c == 0L) { - throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") - } - if (c == Long.MAX_VALUE) { - throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") - } - } while (! this.callCounter.compareAndSet(c, c + 1L)) - // Now we can safely do the method call without the pointer being freed concurrently. - try { - return block(this.pointer) - } finally { - // This decrement aways matches the increment we performed above. - if (this.callCounter.decrementAndGet() == 0L) { - this.freeRustArcPtr() - } - } - } -} - - - - - -// Public interface members begin here. -// Public facing enums -// Error definitions -@Structure.FieldOrder("code", "error_buf") -internal open class RustCallStatus : Structure() { - @JvmField var code: Int = 0 - @JvmField var error_buf: RustBuffer.ByValue = RustBuffer.ByValue() - - fun isSuccess(): Boolean { - return code == 0 - } - - fun isError(): Boolean { - return code == 1 - } - - fun isPanic(): Boolean { - return code == 2 - } -} - -class InternalException(message: String) : Exception(message) - -// Each top-level error class has a companion object that can lift the error from the call status's rust buffer -interface CallStatusErrorHandler { - fun lift(error_buf: RustBuffer.ByValue): E; -} - -// Helpers for calling Rust -// In practice we usually need to be synchronized to call this safely, so it doesn't -// synchronize itself - -// Call a rust function that returns a Result<>. Pass in the Error class companion that corresponds to the Err -private inline fun rustCallWithError(errorHandler: CallStatusErrorHandler, callback: (RustCallStatus) -> U): U { - var status = RustCallStatus(); - val return_value = callback(status) - if (status.isSuccess()) { - return return_value - } else if (status.isError()) { - throw errorHandler.lift(status.error_buf) - } else if (status.isPanic()) { - // when the rust code sees a panic, it tries to construct a rustbuffer - // with the message. but if that code panics, then it just sends back - // an empty buffer. - if (status.error_buf.len > 0) { - throw InternalException(String.lift(status.error_buf)) - } else { - throw InternalException("Rust panic") - } - } else { - throw InternalException("Unknown rust call status: $status.code") - } -} - -// CallStatusErrorHandler implementation for times when we don't expect a CALL_ERROR -object NullCallStatusErrorHandler: CallStatusErrorHandler { - override fun lift(error_buf: RustBuffer.ByValue): InternalException { - RustBuffer.free(error_buf) - return InternalException("Unexpected CALL_ERROR") - } -} - -// Call a rust function that returns a plain value -private inline fun rustCall(callback: (RustCallStatus) -> U): U { - return rustCallWithError(NullCallStatusErrorHandler, callback); -} - -// Public facing records - -// Namespace functions - - -// Objects - - -public interface OfflineWalletInterface { - -} - - -class OfflineWallet( - pointer: Pointer -) : FFIObject(pointer), OfflineWalletInterface { - constructor(descriptor: String ) : - this( - rustCall() { status -> - _UniFFILib.INSTANCE.bdk_ed55_OfflineWallet_new(descriptor.lower() ,status) -}) - - /** - * Disconnect the object from the underlying Rust object. - * - * It can be called more than once, but once called, interacting with the object - * causes an `IllegalStateException`. - * - * Clients **must** call this method once done with the object, or cause a memory leak. - */ - override protected fun freeRustArcPtr() { - rustCall() { status -> - _UniFFILib.INSTANCE.ffi_bdk_ed55_OfflineWallet_object_free(this.pointer, status) - } - } - - internal fun lower(): Pointer = callWithPointer { it } - - internal fun write(buf: RustBufferBuilder) { - // The Rust code always expects pointers written as 8 bytes, - // and will fail to compile if they don't fit. - buf.putLong(Pointer.nativeValue(this.lower())) - } - - - - companion object { - internal fun lift(ptr: Pointer): OfflineWallet { - return OfflineWallet(ptr) - } - - internal fun read(buf: ByteBuffer): OfflineWallet { - // The Rust code always writes pointers as 8 bytes, and will - // fail to compile if they don't fit. - return OfflineWallet.lift(Pointer(buf.getLong())) - } - - - } -} - - -// Callback Interfaces - - diff --git a/src/wallet/blockchain.rs b/src/wallet/blockchain.rs deleted file mode 100644 index 50742f8..0000000 --- a/src/wallet/blockchain.rs +++ /dev/null @@ -1,106 +0,0 @@ -use ::safer_ffi::prelude::*; -use bdk::blockchain::{AnyBlockchainConfig, ElectrumBlockchainConfig}; -use safer_ffi::boxed::Box; -use safer_ffi::char_p::char_p_ref; - -#[derive_ReprC] -#[ReprC::opaque] -#[derive(Debug)] -pub struct BlockchainConfig { - pub raw: AnyBlockchainConfig, -} - -#[ffi_export] -fn new_electrum_config( - url: char_p_ref, - socks5: Option, - retry: i16, - timeout: i16, - stop_gap: usize, -) -> Box { - let url = url.to_string(); - let socks5 = socks5.map(|s| s.to_string()); - let retry = short_to_u8(retry); - let timeout = short_to_optional_u8(timeout); - - let electrum_config = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig { - url, - socks5, - retry, - timeout, - stop_gap, - }); - Box::new(BlockchainConfig { - raw: electrum_config, - }) -} - -#[ffi_export] -fn free_blockchain_config(blockchain_config: Box) { - drop(blockchain_config); -} - -// TODO compact_filter rocksdb not compiling on android, switch to sqlite? -//#[derive_ReprC] -//#[repr(C)] -//#[derive(Debug)] -//pub struct BitcoinPeerConfig { -// pub address: char_p_boxed, -// pub socks5: Option, -// pub socks5_credentials: Option>>, -//} -// -//impl From<&BitcoinPeerConfig> for BdkBitcoinPeerConfig { -// fn from(config: &BitcoinPeerConfig) -> Self { -// let address = config.address.to_string(); -// let socks5 = config.socks5.as_ref().map(|p| p.to_string()); -// let socks5_credentials = config -// .socks5_credentials.as_ref() -// .map(|c| (c._0.to_string(), c._1.to_string())); -// -// BdkBitcoinPeerConfig { -// address, -// socks5: socks5, -// socks5_credentials: socks5_credentials, -// } -// } -//} -// -// -//#[ffi_export] -//fn new_compact_filters_config<'lt>( -// peers: c_slice::Ref<'lt, BitcoinPeerConfig>, -// network: char_p_ref, -// storage_dir: char_p_ref, -// skip_blocks: usize, -//) -> Box { -// let peers = peers.iter().map(|p| p.into()).collect(); -// let network = Network::from_str(network.to_str()).unwrap(); -// let storage_dir = storage_dir.to_string(); -// let skip_blocks = Some(skip_blocks); -// let cf_config = AnyBlockchainConfig::CompactFilters(CompactFiltersBlockchainConfig { -// peers, -// network, -// storage_dir, -// skip_blocks, -// }); -// Box::new(BlockchainConfig { raw: cf_config }) -//} - -// utility functions - -fn short_to_optional_u8(short: i16) -> Option { - if short < 0 { - None - } else { - Some(short_to_u8(short)) - } -} - -fn short_to_u8(short: i16) -> u8 { - if short < 0 { - u8::MIN - } else { - u8::try_from(short).unwrap_or(u8::MAX) - } -} diff --git a/src/wallet/database.rs b/src/wallet/database.rs deleted file mode 100644 index 76dc333..0000000 --- a/src/wallet/database.rs +++ /dev/null @@ -1,32 +0,0 @@ -use ::safer_ffi::prelude::*; -use bdk::database::any::SledDbConfiguration; -use bdk::database::AnyDatabaseConfig; -use safer_ffi::boxed::Box; -use safer_ffi::char_p::char_p_ref; - -#[derive_ReprC] -#[ReprC::opaque] -#[derive(Debug)] -pub struct DatabaseConfig { - pub raw: AnyDatabaseConfig, -} - -#[ffi_export] -fn new_memory_config() -> Box { - let memory_config = AnyDatabaseConfig::Memory(()); - Box::new(DatabaseConfig { raw: memory_config }) -} - -#[ffi_export] -fn new_sled_config(path: char_p_ref, tree_name: char_p_ref) -> Box { - let path = path.to_string(); - let tree_name = tree_name.to_string(); - - let sled_config = AnyDatabaseConfig::Sled(SledDbConfiguration { path, tree_name }); - Box::new(DatabaseConfig { raw: sled_config }) -} - -#[ffi_export] -fn free_database_config(database_config: Box) { - drop(database_config); -} diff --git a/src/wallet/mod.rs b/src/wallet/mod.rs deleted file mode 100644 index 4637efc..0000000 --- a/src/wallet/mod.rs +++ /dev/null @@ -1,175 +0,0 @@ -use std::convert::TryFrom; -use std::ffi::CString; - -use ::safer_ffi::prelude::*; -use bdk::blockchain::{log_progress, AnyBlockchain, AnyBlockchainConfig, ConfigurableBlockchain}; -use bdk::database::{AnyDatabase, AnyDatabaseConfig, ConfigurableDatabase}; -use bdk::wallet::AddressIndex::New; -use bdk::{Error, Wallet}; -use safer_ffi::boxed::Box; -use safer_ffi::char_p::{char_p_boxed, char_p_ref}; - -use blockchain::BlockchainConfig; -use database::DatabaseConfig; - -use crate::error::FfiError; -use crate::types::{FfiResult, FfiResultVoid}; -use crate::wallet::transaction::{LocalUtxo, TransactionDetails}; -use bdk::bitcoin::Network; -use std::str::FromStr; - -mod blockchain; -mod database; -mod transaction; - -// create a new wallet - -#[derive_ReprC] -#[ReprC::opaque] -pub struct OpaqueWallet { - raw: Wallet, -} - -#[ffi_export] -fn new_wallet_result( - descriptor: char_p_ref, - change_descriptor: Option, - network: char_p_ref, - blockchain_config: &BlockchainConfig, - database_config: &DatabaseConfig, -) -> FfiResult>> { - let descriptor = descriptor.to_string(); - let change_descriptor = change_descriptor.map(|s| s.to_string()); - let net = Network::from_str(network.to_str()).expect("Network name"); - let bc_config = &blockchain_config.raw; - let db_config = &database_config.raw; - let wallet_result = new_wallet(descriptor, change_descriptor, net, bc_config, db_config); - - match wallet_result { - Ok(w) => FfiResult { - ok: Some(Box::new(OpaqueWallet { raw: w })), - err: FfiError::None, - }, - Err(e) => FfiResult { - ok: None, - err: FfiError::from(&e), - }, - } -} - -fn new_wallet( - descriptor: String, - change_descriptor: Option, - network: Network, - blockchain_config: &AnyBlockchainConfig, - database_config: &AnyDatabaseConfig, -) -> Result, Error> { - let client = AnyBlockchain::from_config(blockchain_config)?; - let database = AnyDatabase::from_config(database_config)?; - - let descriptor: &str = descriptor.as_str(); - let change_descriptor: Option<&str> = change_descriptor.as_deref(); - - Wallet::new(descriptor, change_descriptor, network, database, client) -} - -#[ffi_export] -fn free_wallet_result(wallet_result: FfiResult>>) { - drop(wallet_result); -} - -// wallet operations - -#[ffi_export] -fn sync_wallet(opaque_wallet: &OpaqueWallet) -> FfiResultVoid { - let int_result = opaque_wallet.raw.sync(log_progress(), Some(100)); - match int_result { - Ok(_v) => FfiResultVoid { - err: FfiError::None, - }, - Err(e) => FfiResultVoid { - err: FfiError::from(&e), - }, - } -} - -#[ffi_export] -fn new_address(opaque_wallet: &OpaqueWallet) -> FfiResult { - let new_address = opaque_wallet.raw.get_address(New); - let string_result = new_address.map(|a| a.to_string()); - match string_result { - Ok(a) => FfiResult { - ok: char_p_boxed::try_from(a).unwrap(), - err: FfiError::None, - }, - Err(e) => FfiResult { - ok: char_p_boxed::from(CString::default()), - err: FfiError::from(&e), - }, - } -} - -#[ffi_export] -fn list_unspent(opaque_wallet: &OpaqueWallet) -> FfiResult> { - let unspent_result = opaque_wallet.raw.list_unspent(); - - match unspent_result { - Ok(v) => FfiResult { - ok: { - let ve: Vec = v.iter().map(|lu| LocalUtxo::from(lu)).collect(); - repr_c::Vec::from(ve) - }, - err: FfiError::None, - }, - Err(e) => FfiResult { - ok: repr_c::Vec::EMPTY, - err: FfiError::from(&e), - }, - } -} - -#[ffi_export] -fn free_veclocalutxo_result(unspent_result: FfiResult>) { - drop(unspent_result) -} - -#[ffi_export] -fn balance(opaque_wallet: &OpaqueWallet) -> FfiResult { - let balance_result = opaque_wallet.raw.get_balance(); - - match balance_result { - Ok(b) => FfiResult { - ok: b, - err: FfiError::None, - }, - Err(e) => FfiResult { - ok: u64::MIN, - err: FfiError::from(&e), - }, - } -} - -#[ffi_export] -fn list_transactions(opaque_wallet: &OpaqueWallet) -> FfiResult> { - let transactions_result = opaque_wallet.raw.list_transactions(false); - - match transactions_result { - Ok(v) => FfiResult { - ok: { - let ve: Vec = - v.iter().map(|t| TransactionDetails::from(t)).collect(); - repr_c::Vec::from(ve) - }, - err: FfiError::None, - }, - Err(e) => FfiResult { - ok: repr_c::Vec::EMPTY, - err: FfiError::from(&e), - }, - } -} - -#[ffi_export] -fn free_vectxdetails_result(txdetails_result: FfiResult>) { - drop(txdetails_result) -} diff --git a/src/wallet/transaction.rs b/src/wallet/transaction.rs deleted file mode 100644 index 5c2194c..0000000 --- a/src/wallet/transaction.rs +++ /dev/null @@ -1,124 +0,0 @@ -use std::convert::TryFrom; - -use ::safer_ffi::prelude::*; -use safer_ffi::char_p::char_p_boxed; - -// Non-opaque returned values - -#[derive_ReprC] -#[repr(C)] -#[derive(Debug, Clone)] -pub struct TransactionDetails { - // TODO Optional transaction - // pub transaction: Option, - /// Transaction id - pub txid: char_p_boxed, - /// Received value (sats) - pub received: u64, - /// Sent value (sats) - pub sent: u64, - /// Fee value (sats) if known, -1 if unknown, based on backend - pub fee: i64, - /// true if confirmed - pub is_confirmed: bool, - /// Confirmed in block height - pub confirmation_time: ConfirmationTime, - /// Whether the tx has been verified against the consensus rules - pub verified: bool, -} - -#[derive_ReprC] -#[repr(C)] -#[derive(Debug, Clone)] -pub struct ConfirmationTime { - /// confirmation block height, 0 if is_confirmed is false - pub height: u32, - /// confirmation block timestamp, 0 if is_confirmed is false - pub timestamp: u64, -} - -impl From<&bdk::TransactionDetails> for TransactionDetails { - fn from(op: &bdk::TransactionDetails) -> Self { - let fee = op.fee.map(|f| i64::try_from(f).unwrap()).unwrap_or(-1); - let confirmation_time = op - .confirmation_time - .as_ref() - .map(|c| ConfirmationTime { - height: c.height, - timestamp: c.timestamp, - }) - .unwrap_or(ConfirmationTime { - height: 0, - timestamp: 0, - }); - TransactionDetails { - txid: char_p_boxed::try_from(op.txid.to_string()).unwrap(), - received: op.received, - sent: op.sent, - fee, - is_confirmed: op.confirmation_time.is_some(), - confirmation_time, - verified: op.verified, - } - } -} - -#[derive_ReprC] -#[repr(C)] -#[derive(Debug, Clone)] -pub struct OutPoint { - /// The referenced transaction's txid, as hex string - pub txid: char_p_boxed, - /// The index of the referenced output in its transaction's vout - pub vout: u32, -} - -impl From<&bdk::bitcoin::OutPoint> for OutPoint { - fn from(op: &bdk::bitcoin::OutPoint) -> Self { - OutPoint { - txid: char_p_boxed::try_from(op.txid.to_string()).unwrap(), - vout: op.vout, - } - } -} - -#[derive_ReprC] -#[repr(C)] -#[derive(Debug, Clone)] -pub struct TxOut { - /// The value of the output, in satoshis - pub value: u64, - /// The script which must satisfy for the output to be spent, as hex string - pub script_pubkey: char_p_boxed, -} - -impl From<&bdk::bitcoin::TxOut> for TxOut { - fn from(to: &bdk::bitcoin::TxOut) -> Self { - TxOut { - value: to.value, - script_pubkey: char_p_boxed::try_from(to.script_pubkey.to_string()).unwrap(), - } - } -} - -#[derive_ReprC] -#[repr(C)] -#[derive(Debug, Clone)] -pub struct LocalUtxo { - /// Reference to a transaction output - pub outpoint: OutPoint, - /// Transaction output - pub txout: TxOut, - /// Type of keychain, as short 0 for "external" or 1 for "internal" - pub keychain: u16, -} - -impl From<&bdk::LocalUtxo> for LocalUtxo { - fn from(lu: &bdk::LocalUtxo) -> Self { - LocalUtxo { - outpoint: OutPoint::from(&lu.outpoint), - txout: TxOut::from(&lu.txout), - keychain: lu.keychain as u16, - } - } -} diff --git a/targets/kotlin/gradle.properties b/targets/kotlin/gradle.properties deleted file mode 100644 index 5976929..0000000 --- a/targets/kotlin/gradle.properties +++ /dev/null @@ -1,23 +0,0 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn -android.useAndroidX=true -# Automatically convert third-party libraries to use AndroidX -android.enableJetifier=true -# Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official -jna.debug_load=true -jna.debug_load.jna=true