Test a callback
This commit is contained in:
parent
40a4b58757
commit
2907eb074d
@ -44,15 +44,15 @@ open class RustBuffer : Structure() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
internal fun alloc(size: Int = 0) = rustCall() { status ->
|
internal fun alloc(size: Int = 0) = rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.ffi_bdk_14a1_rustbuffer_alloc(size, status)
|
_UniFFILib.INSTANCE.ffi_bdk_d1e_rustbuffer_alloc(size, status)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun free(buf: RustBuffer.ByValue) = rustCall() { status ->
|
internal fun free(buf: RustBuffer.ByValue) = rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.ffi_bdk_14a1_rustbuffer_free(buf, status)
|
_UniFFILib.INSTANCE.ffi_bdk_d1e_rustbuffer_free(buf, status)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun reserve(buf: RustBuffer.ByValue, additional: Int) = rustCall() { status ->
|
internal fun reserve(buf: RustBuffer.ByValue, additional: Int) = rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.ffi_bdk_14a1_rustbuffer_reserve(buf, additional, status)
|
_UniFFILib.INSTANCE.ffi_bdk_d1e_rustbuffer_reserve(buf, additional, status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,6 +232,30 @@ internal fun UByte.write(buf: RustBufferBuilder) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
internal fun UInt.Companion.lift(v: Int): UInt {
|
||||||
|
return v.toUInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
internal fun UInt.Companion.read(buf: ByteBuffer): UInt {
|
||||||
|
return UInt.lift(buf.getInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
internal fun UInt.lower(): Int {
|
||||||
|
return this.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
internal fun UInt.write(buf: RustBufferBuilder) {
|
||||||
|
buf.putInt(this.toInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
internal fun ULong.Companion.lift(v: Long): ULong {
|
internal fun ULong.Companion.lift(v: Long): ULong {
|
||||||
return v.toULong()
|
return v.toULong()
|
||||||
@ -256,6 +280,26 @@ internal fun ULong.write(buf: RustBufferBuilder) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal fun Float.Companion.lift(v: Float): Float {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun Float.Companion.read(buf: ByteBuffer): Float {
|
||||||
|
return buf.getFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun Float.lower(): Float {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun Float.write(buf: RustBufferBuilder) {
|
||||||
|
buf.putFloat(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
internal fun String.Companion.lift(rbuf: RustBuffer.ByValue): String {
|
internal fun String.Companion.lift(rbuf: RustBuffer.ByValue): String {
|
||||||
try {
|
try {
|
||||||
val byteArr = ByteArray(rbuf.len)
|
val byteArr = ByteArray(rbuf.len)
|
||||||
@ -342,6 +386,12 @@ internal fun String.write(buf: RustBufferBuilder) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -388,6 +438,45 @@ internal fun writeOptionalu8(v: UByte?, buf: RustBufferBuilder) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Helper functions for pasing values of type UInt?
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
internal fun liftOptionalu32(rbuf: RustBuffer.ByValue): UInt? {
|
||||||
|
return liftFromRustBuffer(rbuf) { buf ->
|
||||||
|
readOptionalu32(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
internal fun readOptionalu32(buf: ByteBuffer): UInt? {
|
||||||
|
if (buf.get().toInt() == 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return UInt.read(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
internal fun lowerOptionalu32(v: UInt?): RustBuffer.ByValue {
|
||||||
|
return lowerIntoRustBuffer(v) { v, buf ->
|
||||||
|
writeOptionalu32(v, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
internal fun writeOptionalu32(v: UInt?, buf: RustBufferBuilder) {
|
||||||
|
if (v == null) {
|
||||||
|
buf.putByte(0)
|
||||||
|
} else {
|
||||||
|
buf.putByte(1)
|
||||||
|
v.write(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Helper functions for pasing values of type String?
|
// Helper functions for pasing values of type String?
|
||||||
|
|
||||||
internal fun liftOptionalstring(rbuf: RustBuffer.ByValue): String? {
|
internal fun liftOptionalstring(rbuf: RustBuffer.ByValue): String? {
|
||||||
@ -446,48 +535,58 @@ internal interface _UniFFILib : Library {
|
|||||||
companion object {
|
companion object {
|
||||||
internal val INSTANCE: _UniFFILib by lazy {
|
internal val INSTANCE: _UniFFILib by lazy {
|
||||||
loadIndirect<_UniFFILib>(componentName = "bdk")
|
loadIndirect<_UniFFILib>(componentName = "bdk")
|
||||||
|
.also { lib: _UniFFILib ->
|
||||||
|
CallbackInterfaceBdkProgressInternals.register(lib)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ffi_bdk_14a1_OfflineWallet_object_free(ptr: Pointer,
|
fun ffi_bdk_d1e_OfflineWallet_object_free(ptr: Pointer,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): Unit
|
): Unit
|
||||||
|
|
||||||
fun bdk_14a1_OfflineWallet_new(descriptor: RustBuffer.ByValue,network: RustBuffer.ByValue,database_config: RustBuffer.ByValue,
|
fun bdk_d1e_OfflineWallet_new(descriptor: RustBuffer.ByValue,network: RustBuffer.ByValue,database_config: RustBuffer.ByValue,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): Pointer
|
): Pointer
|
||||||
|
|
||||||
fun bdk_14a1_OfflineWallet_get_new_address(ptr: Pointer,
|
fun bdk_d1e_OfflineWallet_get_new_address(ptr: Pointer,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): RustBuffer.ByValue
|
): RustBuffer.ByValue
|
||||||
|
|
||||||
fun ffi_bdk_14a1_OnlineWallet_object_free(ptr: Pointer,
|
fun ffi_bdk_d1e_OnlineWallet_object_free(ptr: Pointer,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): Unit
|
): Unit
|
||||||
|
|
||||||
fun bdk_14a1_OnlineWallet_new(descriptor: RustBuffer.ByValue,network: RustBuffer.ByValue,database_config: RustBuffer.ByValue,blockchain_config: RustBuffer.ByValue,
|
fun bdk_d1e_OnlineWallet_new(descriptor: RustBuffer.ByValue,network: RustBuffer.ByValue,database_config: RustBuffer.ByValue,blockchain_config: RustBuffer.ByValue,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): Pointer
|
): Pointer
|
||||||
|
|
||||||
fun bdk_14a1_OnlineWallet_get_network(ptr: Pointer,
|
fun bdk_d1e_OnlineWallet_get_network(ptr: Pointer,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): RustBuffer.ByValue
|
): RustBuffer.ByValue
|
||||||
|
|
||||||
fun ffi_bdk_14a1_rustbuffer_alloc(size: Int,
|
fun bdk_d1e_OnlineWallet_sync(ptr: Pointer,progress_update: Long,max_address_param: RustBuffer.ByValue,
|
||||||
uniffi_out_err: RustCallStatus
|
|
||||||
): RustBuffer.ByValue
|
|
||||||
|
|
||||||
fun ffi_bdk_14a1_rustbuffer_from_bytes(bytes: ForeignBytes.ByValue,
|
|
||||||
uniffi_out_err: RustCallStatus
|
|
||||||
): RustBuffer.ByValue
|
|
||||||
|
|
||||||
fun ffi_bdk_14a1_rustbuffer_free(buf: RustBuffer.ByValue,
|
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): Unit
|
): Unit
|
||||||
|
|
||||||
fun ffi_bdk_14a1_rustbuffer_reserve(buf: RustBuffer.ByValue,additional: Int,
|
fun ffi_bdk_d1e_BdkProgress_init_callback(callback_stub: ForeignCallback,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): Unit
|
||||||
|
|
||||||
|
fun ffi_bdk_d1e_rustbuffer_alloc(size: Int,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): RustBuffer.ByValue
|
||||||
|
|
||||||
|
fun ffi_bdk_d1e_rustbuffer_from_bytes(bytes: ForeignBytes.ByValue,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): RustBuffer.ByValue
|
||||||
|
|
||||||
|
fun ffi_bdk_d1e_rustbuffer_free(buf: RustBuffer.ByValue,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): Unit
|
||||||
|
|
||||||
|
fun ffi_bdk_d1e_rustbuffer_reserve(buf: RustBuffer.ByValue,additional: Int,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): RustBuffer.ByValue
|
): RustBuffer.ByValue
|
||||||
|
|
||||||
@ -657,6 +756,82 @@ abstract class FFIObject(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal typealias Handle = Long
|
||||||
|
internal class ConcurrentHandleMap<T>(
|
||||||
|
private val leftMap: MutableMap<Handle, T> = mutableMapOf(),
|
||||||
|
private val rightMap: MutableMap<T, Handle> = mutableMapOf()
|
||||||
|
) {
|
||||||
|
private val lock = java.util.concurrent.locks.ReentrantLock()
|
||||||
|
private val currentHandle = AtomicLong(0L)
|
||||||
|
private val stride = 1L
|
||||||
|
|
||||||
|
fun insert(obj: T): Handle =
|
||||||
|
lock.withLock {
|
||||||
|
rightMap[obj] ?:
|
||||||
|
currentHandle.getAndAdd(stride)
|
||||||
|
.also { handle ->
|
||||||
|
leftMap[handle] = obj
|
||||||
|
rightMap[obj] = handle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <R> callWithResult(handle: Handle, fn: (T) -> R): R =
|
||||||
|
lock.withLock {
|
||||||
|
leftMap[handle] ?: throw RuntimeException("Panic: handle not in handlemap")
|
||||||
|
}.let { obj ->
|
||||||
|
fn.invoke(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun get(handle: Handle) = lock.withLock {
|
||||||
|
leftMap[handle]
|
||||||
|
}
|
||||||
|
|
||||||
|
fun delete(handle: Handle) {
|
||||||
|
this.remove(handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remove(handle: Handle): T? =
|
||||||
|
lock.withLock {
|
||||||
|
leftMap.remove(handle)?.let { obj ->
|
||||||
|
rightMap.remove(obj)
|
||||||
|
obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ForeignCallback : com.sun.jna.Callback {
|
||||||
|
public fun invoke(handle: Long, method: Int, args: RustBuffer.ByValue): RustBuffer.ByValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magic number for the Rust proxy to call using the same mechanism as every other method,
|
||||||
|
// to free the callback once it's dropped by Rust.
|
||||||
|
internal const val IDX_CALLBACK_FREE = 0
|
||||||
|
|
||||||
|
internal abstract class CallbackInternals<CallbackInterface>(
|
||||||
|
val foreignCallback: ForeignCallback
|
||||||
|
) {
|
||||||
|
val handleMap = ConcurrentHandleMap<CallbackInterface>()
|
||||||
|
|
||||||
|
// Registers the foreign callback with the Rust side.
|
||||||
|
// This method is generated for each callback interface.
|
||||||
|
abstract fun register(lib: _UniFFILib)
|
||||||
|
|
||||||
|
fun drop(handle: Long): RustBuffer.ByValue {
|
||||||
|
return handleMap.remove(handle).let { RustBuffer.ByValue() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun lift(n: Long) = handleMap.get(n)
|
||||||
|
|
||||||
|
fun read(buf: ByteBuffer) = lift(buf.getLong())
|
||||||
|
|
||||||
|
fun lower(v: CallbackInterface) =
|
||||||
|
handleMap.insert(v).also {
|
||||||
|
assert(handleMap.get(it) === v) { "Handle map is not returning the object we just placed there. This is a bug in the HandleMap." }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun write(v: CallbackInterface, buf: RustBufferBuilder) =
|
||||||
|
buf.putLong(lower(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Public interface members begin here.
|
// Public interface members begin here.
|
||||||
@ -1121,7 +1296,7 @@ class OfflineWallet(
|
|||||||
constructor(descriptor: String, network: Network, databaseConfig: DatabaseConfig ) :
|
constructor(descriptor: String, network: Network, databaseConfig: DatabaseConfig ) :
|
||||||
this(
|
this(
|
||||||
rustCallWithError(BdkException) { status ->
|
rustCallWithError(BdkException) { status ->
|
||||||
_UniFFILib.INSTANCE.bdk_14a1_OfflineWallet_new(descriptor.lower(), network.lower(), databaseConfig.lower() ,status)
|
_UniFFILib.INSTANCE.bdk_d1e_OfflineWallet_new(descriptor.lower(), network.lower(), databaseConfig.lower() ,status)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1134,7 +1309,7 @@ class OfflineWallet(
|
|||||||
*/
|
*/
|
||||||
override protected fun freeRustArcPtr() {
|
override protected fun freeRustArcPtr() {
|
||||||
rustCall() { status ->
|
rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.ffi_bdk_14a1_OfflineWallet_object_free(this.pointer, status)
|
_UniFFILib.INSTANCE.ffi_bdk_d1e_OfflineWallet_object_free(this.pointer, status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1149,7 +1324,7 @@ class OfflineWallet(
|
|||||||
override fun getNewAddress(): String =
|
override fun getNewAddress(): String =
|
||||||
callWithPointer {
|
callWithPointer {
|
||||||
rustCall() { status ->
|
rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.bdk_14a1_OfflineWallet_get_new_address(it, status)
|
_UniFFILib.INSTANCE.bdk_d1e_OfflineWallet_get_new_address(it, status)
|
||||||
}
|
}
|
||||||
}.let {
|
}.let {
|
||||||
String.lift(it)
|
String.lift(it)
|
||||||
@ -1175,6 +1350,7 @@ class OfflineWallet(
|
|||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
public interface OnlineWalletInterface {
|
public interface OnlineWalletInterface {
|
||||||
fun getNetwork(): Network
|
fun getNetwork(): Network
|
||||||
|
fun sync(progressUpdate: BdkProgress, maxAddressParam: UInt? )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1185,7 +1361,7 @@ class OnlineWallet(
|
|||||||
constructor(descriptor: String, network: Network, databaseConfig: DatabaseConfig, blockchainConfig: BlockchainConfig ) :
|
constructor(descriptor: String, network: Network, databaseConfig: DatabaseConfig, blockchainConfig: BlockchainConfig ) :
|
||||||
this(
|
this(
|
||||||
rustCallWithError(BdkException) { status ->
|
rustCallWithError(BdkException) { status ->
|
||||||
_UniFFILib.INSTANCE.bdk_14a1_OnlineWallet_new(descriptor.lower(), network.lower(), databaseConfig.lower(), blockchainConfig.lower() ,status)
|
_UniFFILib.INSTANCE.bdk_d1e_OnlineWallet_new(descriptor.lower(), network.lower(), databaseConfig.lower(), blockchainConfig.lower() ,status)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1198,7 +1374,7 @@ class OnlineWallet(
|
|||||||
*/
|
*/
|
||||||
override protected fun freeRustArcPtr() {
|
override protected fun freeRustArcPtr() {
|
||||||
rustCall() { status ->
|
rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.ffi_bdk_14a1_OnlineWallet_object_free(this.pointer, status)
|
_UniFFILib.INSTANCE.ffi_bdk_d1e_OnlineWallet_object_free(this.pointer, status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1213,12 +1389,19 @@ class OnlineWallet(
|
|||||||
override fun getNetwork(): Network =
|
override fun getNetwork(): Network =
|
||||||
callWithPointer {
|
callWithPointer {
|
||||||
rustCall() { status ->
|
rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.bdk_14a1_OnlineWallet_get_network(it, status)
|
_UniFFILib.INSTANCE.bdk_d1e_OnlineWallet_get_network(it, status)
|
||||||
}
|
}
|
||||||
}.let {
|
}.let {
|
||||||
Network.lift(it)
|
Network.lift(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun sync(progressUpdate: BdkProgress, maxAddressParam: UInt? ) =
|
||||||
|
callWithPointer {
|
||||||
|
rustCallWithError(BdkException) { status ->
|
||||||
|
_UniFFILib.INSTANCE.bdk_d1e_OnlineWallet_sync(it, CallbackInterfaceBdkProgressInternals.lower(progressUpdate), lowerOptionalu32(maxAddressParam) , status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -1240,3 +1423,54 @@ class OnlineWallet(
|
|||||||
// Callback Interfaces
|
// Callback Interfaces
|
||||||
|
|
||||||
|
|
||||||
|
public interface BdkProgress {
|
||||||
|
fun update(progress: Float, message: String? )
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal class CallbackInterfaceBdkProgressFFI : ForeignCallback {
|
||||||
|
@Suppress("TooGenericExceptionCaught")
|
||||||
|
override fun invoke(handle: Long, method: Int, args: RustBuffer.ByValue): RustBuffer.ByValue {
|
||||||
|
return CallbackInterfaceBdkProgressInternals.handleMap.callWithResult(handle) { cb ->
|
||||||
|
when (method) {
|
||||||
|
IDX_CALLBACK_FREE -> CallbackInterfaceBdkProgressInternals.drop(handle)
|
||||||
|
1 -> this.invokeUpdate(cb, args)
|
||||||
|
|
||||||
|
// This should never happen, because an out of bounds method index won't
|
||||||
|
// ever be used. Once we can catch errors, we should return an InternalException.
|
||||||
|
// https://github.com/mozilla/uniffi-rs/issues/351
|
||||||
|
else -> RustBuffer.ByValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun invokeUpdate(kotlinCallbackInterface: BdkProgress, args: RustBuffer.ByValue): RustBuffer.ByValue =
|
||||||
|
try {
|
||||||
|
val buf = args.asByteBuffer() ?: throw InternalException("No ByteBuffer in RustBuffer; this is a Uniffi bug")
|
||||||
|
kotlinCallbackInterface.update(
|
||||||
|
Float.read(buf),
|
||||||
|
readOptionalstring(buf)
|
||||||
|
)
|
||||||
|
.let { RustBuffer.ByValue() }
|
||||||
|
// TODO catch errors and report them back to Rust.
|
||||||
|
// https://github.com/mozilla/uniffi-rs/issues/351
|
||||||
|
} finally {
|
||||||
|
RustBuffer.free(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object CallbackInterfaceBdkProgressInternals: CallbackInternals<BdkProgress>(
|
||||||
|
foreignCallback = CallbackInterfaceBdkProgressFFI()
|
||||||
|
) {
|
||||||
|
override fun register(lib: _UniFFILib) {
|
||||||
|
rustCall() { status ->
|
||||||
|
lib.ffi_bdk_d1e_BdkProgress_init_callback(this.foreignCallback, status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,6 +4,13 @@ import uniffi.bdk.OfflineWallet
|
|||||||
import org.junit.Assert.*
|
import org.junit.Assert.*
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
class LogProgress: BdkProgress {
|
||||||
|
override fun update(progress: Float, message: String? ) {
|
||||||
|
println(progress);
|
||||||
|
println(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Library tests which will execute for jvm and android modules.
|
* Library tests which will execute for jvm and android modules.
|
||||||
*/
|
*/
|
||||||
@ -45,4 +52,12 @@ class LibTest {
|
|||||||
val network = wallet.getNetwork()
|
val network = wallet.getNetwork()
|
||||||
assertEquals(network, Network.TESTNET)
|
assertEquals(network, Network.TESTNET)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onlineWalletSync() {
|
||||||
|
val db = DatabaseConfig.Memory("")
|
||||||
|
val client = BlockchainConfig.Electrum(ElectrumConfig("ssl://electrum.blockstream.info:50002", null, 5u, null, 100u))
|
||||||
|
val wallet = OnlineWallet(desc, Network.TESTNET, db, client)
|
||||||
|
wallet.sync(LogProgress(), null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,8 +91,14 @@ interface BlockchainConfig {
|
|||||||
Esplora(EsploraConfig config);
|
Esplora(EsploraConfig config);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
callback interface BdkProgress {
|
||||||
|
void update(f32 progress, string? message);
|
||||||
|
};
|
||||||
|
|
||||||
interface OnlineWallet {
|
interface OnlineWallet {
|
||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
constructor(string descriptor, Network network, DatabaseConfig database_config, BlockchainConfig blockchain_config);
|
constructor(string descriptor, Network network, DatabaseConfig database_config, BlockchainConfig blockchain_config);
|
||||||
Network get_network();
|
Network get_network();
|
||||||
|
[Throws=BdkError]
|
||||||
|
void sync(BdkProgress progress_update, u32? max_address_param);
|
||||||
};
|
};
|
||||||
|
33
src/lib.rs
33
src/lib.rs
@ -1,5 +1,6 @@
|
|||||||
use bdk::bitcoin::Network;
|
use bdk::bitcoin::Network;
|
||||||
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
|
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
|
||||||
|
use bdk::blockchain::Progress;
|
||||||
use bdk::blockchain::{
|
use bdk::blockchain::{
|
||||||
electrum::ElectrumBlockchainConfig, esplora::EsploraBlockchainConfig, ConfigurableBlockchain,
|
electrum::ElectrumBlockchainConfig, esplora::EsploraBlockchainConfig, ConfigurableBlockchain,
|
||||||
};
|
};
|
||||||
@ -75,6 +76,24 @@ struct OnlineWallet {
|
|||||||
wallet: Mutex<Wallet<AnyBlockchain, AnyDatabase>>,
|
wallet: Mutex<Wallet<AnyBlockchain, AnyDatabase>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait BdkProgress: Send {
|
||||||
|
fn update(&self, progress: f32, message: Option<String>);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BdkProgressHolder {
|
||||||
|
progress_update: Mutex<Box<dyn BdkProgress>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Progress for BdkProgressHolder {
|
||||||
|
fn update(&self, progress: f32, message: Option<String>) -> Result<(), Error> {
|
||||||
|
self.progress_update
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.update(progress, message);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl OnlineWallet {
|
impl OnlineWallet {
|
||||||
fn new(
|
fn new(
|
||||||
descriptor: String,
|
descriptor: String,
|
||||||
@ -121,6 +140,20 @@ impl OnlineWallet {
|
|||||||
fn get_network(&self) -> Network {
|
fn get_network(&self) -> Network {
|
||||||
self.wallet.lock().unwrap().network()
|
self.wallet.lock().unwrap().network()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sync(
|
||||||
|
&self,
|
||||||
|
progress_update: Box<dyn BdkProgress>,
|
||||||
|
max_address_param: Option<u32>,
|
||||||
|
) -> Result<(), BdkError> {
|
||||||
|
progress_update.update(21.0, Some("message".to_string()));
|
||||||
|
self.wallet.lock().unwrap().sync(
|
||||||
|
BdkProgressHolder {
|
||||||
|
progress_update: Mutex::new(progress_update),
|
||||||
|
},
|
||||||
|
max_address_param,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uniffi::deps::static_assertions::assert_impl_all!(OfflineWallet: Sync, Send);
|
uniffi::deps::static_assertions::assert_impl_all!(OfflineWallet: Sync, Send);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user