Simplify Kotlin Wallet api
This commit is contained in:
parent
110dfbd13c
commit
757113c002
@ -1,9 +1,6 @@
|
|||||||
package org.bitcoindevkit.bdk
|
package org.bitcoindevkit.bdk
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import com.sun.jna.Native
|
|
||||||
import org.junit.*
|
|
||||||
|
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@ -17,8 +17,7 @@ dependencies {
|
|||||||
api "org.slf4j:slf4j-api:1.7.30"
|
api "org.slf4j:slf4j-api:1.7.30"
|
||||||
testImplementation "ch.qos.logback:logback-classic:1.2.3"
|
testImplementation "ch.qos.logback:logback-classic:1.2.3"
|
||||||
testImplementation "ch.qos.logback:logback-core:1.2.3"
|
testImplementation "ch.qos.logback:logback-core:1.2.3"
|
||||||
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
|
testImplementation(project(':test-fixtures'))
|
||||||
testImplementation (project(':test-fixtures'))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package org.bitcoindevkit.bdk
|
package org.bitcoindevkit.bdk
|
||||||
|
|
||||||
enum class Error {
|
enum class JnaError {
|
||||||
InvalidU32Bytes,
|
InvalidU32Bytes,
|
||||||
Generic,
|
Generic,
|
||||||
ScriptDoesntHaveAddressForm,
|
ScriptDoesntHaveAddressForm,
|
||||||
@ -37,7 +37,8 @@ enum class Error {
|
|||||||
Hex,
|
Hex,
|
||||||
Psbt,
|
Psbt,
|
||||||
Electrum,
|
Electrum,
|
||||||
// Esplora
|
|
||||||
|
// Esplora
|
||||||
// CompactFilters
|
// CompactFilters
|
||||||
Sled,
|
Sled,
|
||||||
}
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
package org.bitcoindevkit.bdk
|
||||||
|
|
||||||
|
class JnaException internal constructor(val err: JnaError) : Exception()
|
@ -1,6 +1,8 @@
|
|||||||
package org.bitcoindevkit.bdk
|
package org.bitcoindevkit.bdk
|
||||||
|
|
||||||
import com.sun.jna.*
|
import com.sun.jna.Library
|
||||||
|
import com.sun.jna.Pointer
|
||||||
|
import com.sun.jna.PointerType
|
||||||
|
|
||||||
interface LibJna : Library {
|
interface LibJna : Library {
|
||||||
|
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package org.bitcoindevkit.bdk
|
||||||
|
|
||||||
|
import com.sun.jna.Pointer
|
||||||
|
import com.sun.jna.PointerType
|
||||||
|
import org.slf4j.Logger
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
|
abstract class ResultBase<PT : PointerType, RT : Any> internal constructor(protected val resultT: PT) :
|
||||||
|
LibBase() {
|
||||||
|
|
||||||
|
protected open val log: Logger = LoggerFactory.getLogger(ResultBase::class.java)
|
||||||
|
|
||||||
|
protected abstract fun err(): Pointer?
|
||||||
|
|
||||||
|
protected abstract fun ok(): RT
|
||||||
|
|
||||||
|
protected abstract fun free(pointer: PT)
|
||||||
|
|
||||||
|
private fun checkErr() {
|
||||||
|
val errPointer = err()
|
||||||
|
val err = errPointer?.getString(0)
|
||||||
|
libJna.free_string(errPointer)
|
||||||
|
if (err != null) {
|
||||||
|
throw JnaException(JnaError.valueOf(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun value(): RT {
|
||||||
|
checkErr()
|
||||||
|
return ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun finalize() {
|
||||||
|
free(resultT)
|
||||||
|
log.debug("$resultT freed")
|
||||||
|
}
|
||||||
|
}
|
@ -1,32 +1,26 @@
|
|||||||
package org.bitcoindevkit.bdk
|
package org.bitcoindevkit.bdk
|
||||||
|
|
||||||
|
import com.sun.jna.Pointer
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
class StringResult internal constructor(private val stringResultT: LibJna.StringResult_t) : LibBase() {
|
class StringResult internal constructor(stringResultT: LibJna.StringResult_t) :
|
||||||
|
ResultBase<LibJna.StringResult_t, String>(stringResultT) {
|
||||||
|
|
||||||
private val log: Logger = LoggerFactory.getLogger(StringResult::class.java)
|
override val log: Logger = LoggerFactory.getLogger(StringResult::class.java)
|
||||||
|
|
||||||
fun isErr(): Boolean {
|
override fun err(): Pointer? {
|
||||||
return libJna.get_string_err(stringResultT) != null
|
return libJna.get_string_err(resultT)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun err(): Error? {
|
override fun ok(): String {
|
||||||
val errPointer = libJna.get_string_err(stringResultT)
|
val okPointer = libJna.get_string_ok(resultT)
|
||||||
val err = errPointer?.getString(0)
|
val ok = okPointer!!.getString(0)
|
||||||
libJna.free_string(errPointer)
|
|
||||||
return err?.let { Error.valueOf(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ok(): String? {
|
|
||||||
val okPointer = libJna.get_string_ok(stringResultT)
|
|
||||||
val ok = okPointer?.getString(0)
|
|
||||||
libJna.free_string(okPointer)
|
libJna.free_string(okPointer)
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun finalize() {
|
override fun free(pointer: LibJna.StringResult_t) {
|
||||||
libJna.free_string_result(stringResultT)
|
libJna.free_string_result(resultT)
|
||||||
log.debug("StringResult_t freed")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,25 +1,23 @@
|
|||||||
package org.bitcoindevkit.bdk
|
package org.bitcoindevkit.bdk
|
||||||
|
|
||||||
|
import com.sun.jna.Pointer
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
class VoidResult internal constructor(private val voidResultT: LibJna.VoidResult_t) : LibBase() {
|
class VoidResult internal constructor(voidResultT: LibJna.VoidResult_t) :
|
||||||
|
ResultBase<LibJna.VoidResult_t, Unit>(voidResultT) {
|
||||||
|
|
||||||
private val log: Logger = LoggerFactory.getLogger(VoidResult::class.java)
|
override val log: Logger = LoggerFactory.getLogger(VoidResult::class.java)
|
||||||
|
|
||||||
fun isErr(): Boolean {
|
override fun err(): Pointer? {
|
||||||
return libJna.get_void_err(voidResultT) != null
|
return libJna.get_void_err(resultT)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun err(): Error? {
|
override fun ok() {
|
||||||
val errPointer = libJna.get_void_err(voidResultT)
|
// Void
|
||||||
val err = errPointer?.getString(0)
|
|
||||||
libJna.free_string(errPointer)
|
|
||||||
return err?.let { Error.valueOf(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun finalize() {
|
override fun free(pointer: LibJna.VoidResult_t) {
|
||||||
libJna.free_void_result(voidResultT)
|
libJna.free_void_result(resultT)
|
||||||
log.debug("VoidResult_t freed")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,23 +3,30 @@ package org.bitcoindevkit.bdk
|
|||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
class Wallet internal constructor(
|
class Wallet constructor(
|
||||||
private val walletRefT: LibJna.WalletRef_t,
|
name: String,
|
||||||
|
descriptor: String,
|
||||||
|
changeDescriptor: String?,
|
||||||
) : LibBase() {
|
) : LibBase() {
|
||||||
|
|
||||||
private val log: Logger = LoggerFactory.getLogger(Wallet::class.java)
|
val log: Logger = LoggerFactory.getLogger(Wallet::class.java)
|
||||||
|
|
||||||
fun sync(): VoidResult {
|
private val walletResult =
|
||||||
return VoidResult(libJna.sync_wallet(walletRefT.pointer))
|
WalletResult(libJna.new_wallet_result(name, descriptor, changeDescriptor))
|
||||||
|
private val walletRefT = walletResult.value()
|
||||||
|
|
||||||
|
fun sync() {
|
||||||
|
val voidResult = VoidResult(libJna.sync_wallet(walletRefT.pointer))
|
||||||
|
return voidResult.value()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAddress(): StringResult {
|
fun getAddress(): String {
|
||||||
return StringResult(libJna.new_address(walletRefT.pointer))
|
val stringResult = StringResult(libJna.new_address(walletRefT.pointer))
|
||||||
|
return stringResult.value()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun finalize() {
|
protected fun finalize(pointer: LibJna.WalletResult_t) {
|
||||||
libJna.free_wallet_ref(walletRefT)
|
libJna.free_wallet_ref(walletRefT)
|
||||||
log.debug("WalletRef_t freed")
|
log.debug("$walletRefT freed")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,36 +1,23 @@
|
|||||||
package org.bitcoindevkit.bdk
|
package org.bitcoindevkit.bdk
|
||||||
|
|
||||||
|
import com.sun.jna.Pointer
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
class WalletResult(
|
class WalletResult internal constructor(walletResultT: LibJna.WalletResult_t) :
|
||||||
name: String,
|
ResultBase<LibJna.WalletResult_t, LibJna.WalletRef_t>(walletResultT) {
|
||||||
descriptor: String,
|
|
||||||
changeDescriptor: String?,
|
|
||||||
) : LibBase() {
|
|
||||||
|
|
||||||
private val log: Logger = LoggerFactory.getLogger(WalletResult::class.java)
|
override val log: Logger = LoggerFactory.getLogger(WalletResult::class.java)
|
||||||
private val walletResultT = libJna.new_wallet_result(name, descriptor, changeDescriptor)
|
|
||||||
|
|
||||||
fun isErr(): Boolean {
|
override fun err(): Pointer? {
|
||||||
return libJna.get_wallet_err(walletResultT) != null
|
return libJna.get_wallet_err(resultT)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun err(): Error? {
|
override fun ok(): LibJna.WalletRef_t {
|
||||||
val errPointer = libJna.get_wallet_err(walletResultT)
|
return libJna.get_wallet_ok(resultT)!!
|
||||||
val err = errPointer?.getString(0)
|
|
||||||
libJna.free_string(errPointer)
|
|
||||||
return err?.let { Error.valueOf(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ok(): Wallet? {
|
override fun free(pointer: LibJna.WalletResult_t) {
|
||||||
val okWalletRef = libJna.get_wallet_ok(walletResultT)
|
libJna.free_wallet_result(resultT)
|
||||||
return if (okWalletRef != null) Wallet(okWalletRef) else null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun finalize() {
|
|
||||||
libJna.free_wallet_result(walletResultT)
|
|
||||||
log.debug("WalletResult_t freed")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,11 +1,5 @@
|
|||||||
package org.bitcoindevkit.bdk
|
package org.bitcoindevkit.bdk
|
||||||
|
|
||||||
import com.sun.jna.Native
|
|
||||||
import org.junit.*
|
|
||||||
import org.junit.Assert.assertEquals
|
|
||||||
import kotlin.test.assertNotNull
|
|
||||||
import kotlin.test.assertNull
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Library test, which will execute on linux host.
|
* Library test, which will execute on linux host.
|
||||||
*
|
*
|
||||||
|
@ -8,7 +8,7 @@ dependencies {
|
|||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation "net.java.dev.jna:jna:5.8.0"
|
implementation "net.java.dev.jna:jna:5.8.0"
|
||||||
implementation (project(':jvm'))
|
implementation (project(':jvm'))
|
||||||
implementation 'org.jetbrains.kotlin:kotlin-test-junit'
|
implementation "junit:junit:4.13.2"
|
||||||
//implementation "org.mockito.kotlin:mockito-kotlin:3.2.0"
|
//implementation "org.mockito.kotlin:mockito-kotlin:3.2.0"
|
||||||
api "org.slf4j:slf4j-api:1.7.30"
|
api "org.slf4j:slf4j-api:1.7.30"
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import org.junit.*
|
|||||||
import org.junit.Assert.*
|
import org.junit.Assert.*
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import javax.management.Descriptor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Library test, which will execute on linux host.
|
* Library test, which will execute on linux host.
|
||||||
@ -21,21 +22,17 @@ abstract class LibTest : LibBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun walletResultError() {
|
fun walletResultError() {
|
||||||
val badWalletResult = WalletResult("bad", "bad", "bad")
|
val jnaException = assertThrows(JnaException::class.java) {
|
||||||
assertTrue(badWalletResult.isErr())
|
Wallet("bad", "bad", "bad")
|
||||||
val walletErr = badWalletResult.err()
|
}
|
||||||
assertNotNull(walletErr)
|
assertEquals(jnaException.err, JnaError.Descriptor)
|
||||||
log.debug("wallet error $walletErr")
|
|
||||||
assertEquals(Error.Descriptor, walletErr)
|
|
||||||
val wallet = badWalletResult.ok()
|
|
||||||
assertNull(wallet)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun walletResultFinalize() {
|
fun walletResultFinalize() {
|
||||||
val names = listOf("one", "two", "three")
|
val names = listOf("one", "two", "three")
|
||||||
names.map {
|
names.map {
|
||||||
val wallet = WalletResult(it, desc, change)
|
val wallet = Wallet(it, desc, change)
|
||||||
assertNotNull(wallet)
|
assertNotNull(wallet)
|
||||||
}
|
}
|
||||||
System.gc()
|
System.gc()
|
||||||
@ -44,23 +41,16 @@ abstract class LibTest : LibBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun walletSync() {
|
fun walletSync() {
|
||||||
val walletResult = WalletResult(name, desc, change)
|
val wallet = Wallet(name, desc, change)
|
||||||
val wallet = walletResult.ok()
|
|
||||||
assertNotNull(wallet)
|
assertNotNull(wallet)
|
||||||
val syncResult = wallet!!.sync();
|
wallet.sync()
|
||||||
assertFalse(syncResult.isErr())
|
|
||||||
assertNull(syncResult.err())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun walletNewAddress() {
|
fun walletNewAddress() {
|
||||||
val walletResult = WalletResult(name, desc, change)
|
val wallet = Wallet(name, desc, change)
|
||||||
val wallet = walletResult.ok()
|
|
||||||
assertNotNull(wallet)
|
assertNotNull(wallet)
|
||||||
val addressResult = wallet!!.getAddress()
|
val address = wallet.getAddress()
|
||||||
assertFalse(addressResult.isErr())
|
|
||||||
assertNull(addressResult.err())
|
|
||||||
val address = addressResult.ok()
|
|
||||||
assertNotNull(address)
|
assertNotNull(address)
|
||||||
log.debug("address created from kotlin: $address")
|
log.debug("address created from kotlin: $address")
|
||||||
assertEquals(address, "tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e")
|
assertEquals(address, "tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e")
|
||||||
|
@ -129,13 +129,12 @@ fn get_wallet_ok<'lt>(wallet_result: &'lt WalletResult) -> Option<Box<WalletRef<
|
|||||||
.raw
|
.raw
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok()
|
.ok()
|
||||||
.map(|w| Box::new(WalletRef { raw: w}))
|
.map(|w| Box::new(WalletRef { raw: w }))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ffi_export]
|
#[ffi_export]
|
||||||
fn sync_wallet<'lt>(wallet_ref: &'lt WalletRef<'lt>) -> Box<VoidResult> {
|
fn sync_wallet<'lt>(wallet_ref: &'lt WalletRef<'lt>) -> Box<VoidResult> {
|
||||||
let void_result = wallet_ref
|
let void_result = wallet_ref.raw.sync(log_progress(), Some(100));
|
||||||
.raw.sync(log_progress(), Some(100));
|
|
||||||
Box::new(VoidResult { raw: void_result })
|
Box::new(VoidResult { raw: void_result })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user