Merge pull request #14 from notmandatory/allow-signing-partially-signed-transactions
Allow signing partially signed transactions
This commit is contained in:
commit
69efddafec
@ -9,11 +9,11 @@ class LogProgress: BdkProgress {
|
|||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
println("Configuring an in-memory wallet on electrum..")
|
println("Configuring an in-memory wallet on electrum..")
|
||||||
val descriptor =
|
val descriptor =
|
||||||
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)";
|
"pkh(cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR)";
|
||||||
val amount = 10000uL;
|
val amount = 1000uL;
|
||||||
val recipient = "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt";
|
val recipient = "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt";
|
||||||
val db = DatabaseConfig.Memory("")
|
val db = DatabaseConfig.Memory("")
|
||||||
val client = BlockchainConfig.Electrum(ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5u, null, 100u))
|
val client = BlockchainConfig.Electrum(ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5u, null, 10u))
|
||||||
val wallet = OnlineWallet(descriptor, Network.TESTNET, db, client)
|
val wallet = OnlineWallet(descriptor, Network.TESTNET, db, client)
|
||||||
val address = wallet.getNewAddress()
|
val address = wallet.getNewAddress()
|
||||||
println("Please send $amount satoshis to address: $address")
|
println("Please send $amount satoshis to address: $address")
|
||||||
@ -22,8 +22,19 @@ fun main(args: Array<String>) {
|
|||||||
wallet.sync(LogProgress(), null)
|
wallet.sync(LogProgress(), null)
|
||||||
val balance = wallet.getBalance()
|
val balance = wallet.getBalance()
|
||||||
println("New wallet balance: $balance")
|
println("New wallet balance: $balance")
|
||||||
println("Refunding $amount satoshis to $recipient")
|
println("Press Enter to return funds")
|
||||||
val psbt = PartiallySignedBitcoinTransaction(wallet, recipient, amount)
|
readLine()
|
||||||
println("Press any key to exit")
|
println("Creating a partially signed bitcoin transaction with recipient $recipient and amount $amount satoshis...")
|
||||||
|
val transaction = PartiallySignedBitcoinTransaction(wallet, recipient, amount)
|
||||||
|
println("Signing the transaction...")
|
||||||
|
wallet.sign(transaction)
|
||||||
|
println("Broadcasting the signed transaction...")
|
||||||
|
val transactionId = wallet.broadcast(transaction)
|
||||||
|
println("Refunded $amount satoshis to $recipient via transaction id $transactionId")
|
||||||
|
println("Syncing...")
|
||||||
|
wallet.sync(LogProgress(), null)
|
||||||
|
val final_balance = wallet.getBalance()
|
||||||
|
println("New wallet balance: $final_balance")
|
||||||
|
println("Press Enter to exit")
|
||||||
readLine()
|
readLine()
|
||||||
}
|
}
|
||||||
|
@ -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_b7c7_rustbuffer_alloc(size, status)
|
_UniFFILib.INSTANCE.ffi_bdk_70ef_rustbuffer_alloc(size, status)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun free(buf: RustBuffer.ByValue) = rustCall() { status ->
|
internal fun free(buf: RustBuffer.ByValue) = rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.ffi_bdk_b7c7_rustbuffer_free(buf, status)
|
_UniFFILib.INSTANCE.ffi_bdk_70ef_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_b7c7_rustbuffer_reserve(buf, additional, status)
|
_UniFFILib.INSTANCE.ffi_bdk_70ef_rustbuffer_reserve(buf, additional, status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,67 +548,83 @@ internal interface _UniFFILib : Library {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ffi_bdk_b7c7_OfflineWallet_object_free(ptr: Pointer,
|
fun ffi_bdk_70ef_OfflineWallet_object_free(ptr: Pointer,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): Unit
|
): Unit
|
||||||
|
|
||||||
fun bdk_b7c7_OfflineWallet_new(descriptor: RustBuffer.ByValue,network: RustBuffer.ByValue,database_config: RustBuffer.ByValue,
|
fun bdk_70ef_OfflineWallet_new(descriptor: RustBuffer.ByValue,network: RustBuffer.ByValue,database_config: RustBuffer.ByValue,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): Pointer
|
): Pointer
|
||||||
|
|
||||||
fun bdk_b7c7_OfflineWallet_get_new_address(ptr: Pointer,
|
fun bdk_70ef_OfflineWallet_get_new_address(ptr: Pointer,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): RustBuffer.ByValue
|
): RustBuffer.ByValue
|
||||||
|
|
||||||
fun ffi_bdk_b7c7_OnlineWallet_object_free(ptr: Pointer,
|
fun bdk_70ef_OfflineWallet_get_balance(ptr: Pointer,
|
||||||
uniffi_out_err: RustCallStatus
|
|
||||||
): Unit
|
|
||||||
|
|
||||||
fun bdk_b7c7_OnlineWallet_new(descriptor: RustBuffer.ByValue,network: RustBuffer.ByValue,database_config: RustBuffer.ByValue,blockchain_config: RustBuffer.ByValue,
|
|
||||||
uniffi_out_err: RustCallStatus
|
|
||||||
): Pointer
|
|
||||||
|
|
||||||
fun bdk_b7c7_OnlineWallet_get_new_address(ptr: Pointer,
|
|
||||||
uniffi_out_err: RustCallStatus
|
|
||||||
): RustBuffer.ByValue
|
|
||||||
|
|
||||||
fun bdk_b7c7_OnlineWallet_get_network(ptr: Pointer,
|
|
||||||
uniffi_out_err: RustCallStatus
|
|
||||||
): RustBuffer.ByValue
|
|
||||||
|
|
||||||
fun bdk_b7c7_OnlineWallet_sync(ptr: Pointer,progress_update: Long,max_address_param: RustBuffer.ByValue,
|
|
||||||
uniffi_out_err: RustCallStatus
|
|
||||||
): Unit
|
|
||||||
|
|
||||||
fun bdk_b7c7_OnlineWallet_get_balance(ptr: Pointer,
|
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): Long
|
): Long
|
||||||
|
|
||||||
fun ffi_bdk_b7c7_PartiallySignedBitcoinTransaction_object_free(ptr: Pointer,
|
fun bdk_70ef_OfflineWallet_sign(ptr: Pointer,psbt: Pointer,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): Unit
|
): Unit
|
||||||
|
|
||||||
fun bdk_b7c7_PartiallySignedBitcoinTransaction_new(wallet: Pointer,recipient: RustBuffer.ByValue,amount: Long,
|
fun ffi_bdk_70ef_OnlineWallet_object_free(ptr: Pointer,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): Unit
|
||||||
|
|
||||||
|
fun bdk_70ef_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 ffi_bdk_b7c7_BdkProgress_init_callback(callback_stub: ForeignCallback,
|
fun bdk_70ef_OnlineWallet_get_new_address(ptr: Pointer,
|
||||||
uniffi_out_err: RustCallStatus
|
|
||||||
): Unit
|
|
||||||
|
|
||||||
fun ffi_bdk_b7c7_rustbuffer_alloc(size: Int,
|
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): RustBuffer.ByValue
|
): RustBuffer.ByValue
|
||||||
|
|
||||||
fun ffi_bdk_b7c7_rustbuffer_from_bytes(bytes: ForeignBytes.ByValue,
|
fun bdk_70ef_OnlineWallet_get_balance(ptr: Pointer,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): RustBuffer.ByValue
|
): Long
|
||||||
|
|
||||||
fun ffi_bdk_b7c7_rustbuffer_free(buf: RustBuffer.ByValue,
|
fun bdk_70ef_OnlineWallet_sign(ptr: Pointer,psbt: Pointer,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): Unit
|
): Unit
|
||||||
|
|
||||||
fun ffi_bdk_b7c7_rustbuffer_reserve(buf: RustBuffer.ByValue,additional: Int,
|
fun bdk_70ef_OnlineWallet_get_network(ptr: Pointer,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): RustBuffer.ByValue
|
||||||
|
|
||||||
|
fun bdk_70ef_OnlineWallet_sync(ptr: Pointer,progress_update: Long,max_address_param: RustBuffer.ByValue,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): Unit
|
||||||
|
|
||||||
|
fun bdk_70ef_OnlineWallet_broadcast(ptr: Pointer,psbt: Pointer,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): RustBuffer.ByValue
|
||||||
|
|
||||||
|
fun ffi_bdk_70ef_PartiallySignedBitcoinTransaction_object_free(ptr: Pointer,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): Unit
|
||||||
|
|
||||||
|
fun bdk_70ef_PartiallySignedBitcoinTransaction_new(wallet: Pointer,recipient: RustBuffer.ByValue,amount: Long,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): Pointer
|
||||||
|
|
||||||
|
fun ffi_bdk_70ef_BdkProgress_init_callback(callback_stub: ForeignCallback,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): Unit
|
||||||
|
|
||||||
|
fun ffi_bdk_70ef_rustbuffer_alloc(size: Int,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): RustBuffer.ByValue
|
||||||
|
|
||||||
|
fun ffi_bdk_70ef_rustbuffer_from_bytes(bytes: ForeignBytes.ByValue,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): RustBuffer.ByValue
|
||||||
|
|
||||||
|
fun ffi_bdk_70ef_rustbuffer_free(buf: RustBuffer.ByValue,
|
||||||
|
uniffi_out_err: RustCallStatus
|
||||||
|
): Unit
|
||||||
|
|
||||||
|
fun ffi_bdk_70ef_rustbuffer_reserve(buf: RustBuffer.ByValue,additional: Int,
|
||||||
uniffi_out_err: RustCallStatus
|
uniffi_out_err: RustCallStatus
|
||||||
): RustBuffer.ByValue
|
): RustBuffer.ByValue
|
||||||
|
|
||||||
@ -1305,20 +1321,22 @@ data class EsploraConfig (
|
|||||||
|
|
||||||
// Objects
|
// Objects
|
||||||
|
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
public interface OfflineWalletInterface {
|
public interface OfflineWalletInterface {
|
||||||
fun getNewAddress(): String
|
fun getNewAddress(): String
|
||||||
|
fun getBalance(): ULong
|
||||||
|
fun sign(psbt: PartiallySignedBitcoinTransaction )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
class OfflineWallet(
|
class OfflineWallet(
|
||||||
pointer: Pointer
|
pointer: Pointer
|
||||||
) : FFIObject(pointer), OfflineWalletInterface {
|
) : FFIObject(pointer), OfflineWalletInterface {
|
||||||
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_b7c7_OfflineWallet_new(descriptor.lower(), network.lower(), databaseConfig.lower() ,status)
|
_UniFFILib.INSTANCE.bdk_70ef_OfflineWallet_new(descriptor.lower(), network.lower(), databaseConfig.lower() ,status)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1331,7 +1349,7 @@ class OfflineWallet(
|
|||||||
*/
|
*/
|
||||||
override protected fun freeRustArcPtr() {
|
override protected fun freeRustArcPtr() {
|
||||||
rustCall() { status ->
|
rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.ffi_bdk_b7c7_OfflineWallet_object_free(this.pointer, status)
|
_UniFFILib.INSTANCE.ffi_bdk_70ef_OfflineWallet_object_free(this.pointer, status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1346,12 +1364,28 @@ class OfflineWallet(
|
|||||||
override fun getNewAddress(): String =
|
override fun getNewAddress(): String =
|
||||||
callWithPointer {
|
callWithPointer {
|
||||||
rustCall() { status ->
|
rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.bdk_b7c7_OfflineWallet_get_new_address(it, status)
|
_UniFFILib.INSTANCE.bdk_70ef_OfflineWallet_get_new_address(it, status)
|
||||||
}
|
}
|
||||||
}.let {
|
}.let {
|
||||||
String.lift(it)
|
String.lift(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getBalance(): ULong =
|
||||||
|
callWithPointer {
|
||||||
|
rustCallWithError(BdkException) { status ->
|
||||||
|
_UniFFILib.INSTANCE.bdk_70ef_OfflineWallet_get_balance(it, status)
|
||||||
|
}
|
||||||
|
}.let {
|
||||||
|
ULong.lift(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun sign(psbt: PartiallySignedBitcoinTransaction ) =
|
||||||
|
callWithPointer {
|
||||||
|
rustCallWithError(BdkException) { status ->
|
||||||
|
_UniFFILib.INSTANCE.bdk_70ef_OfflineWallet_sign(it, psbt.lower() , status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -1372,9 +1406,11 @@ class OfflineWallet(
|
|||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
public interface OnlineWalletInterface {
|
public interface OnlineWalletInterface {
|
||||||
fun getNewAddress(): String
|
fun getNewAddress(): String
|
||||||
|
fun getBalance(): ULong
|
||||||
|
fun sign(psbt: PartiallySignedBitcoinTransaction )
|
||||||
fun getNetwork(): Network
|
fun getNetwork(): Network
|
||||||
fun sync(progressUpdate: BdkProgress, maxAddressParam: UInt? )
|
fun sync(progressUpdate: BdkProgress, maxAddressParam: UInt? )
|
||||||
fun getBalance(): ULong
|
fun broadcast(psbt: PartiallySignedBitcoinTransaction ): String
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1385,7 +1421,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_b7c7_OnlineWallet_new(descriptor.lower(), network.lower(), databaseConfig.lower(), blockchainConfig.lower() ,status)
|
_UniFFILib.INSTANCE.bdk_70ef_OnlineWallet_new(descriptor.lower(), network.lower(), databaseConfig.lower(), blockchainConfig.lower() ,status)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1398,7 +1434,7 @@ class OnlineWallet(
|
|||||||
*/
|
*/
|
||||||
override protected fun freeRustArcPtr() {
|
override protected fun freeRustArcPtr() {
|
||||||
rustCall() { status ->
|
rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.ffi_bdk_b7c7_OnlineWallet_object_free(this.pointer, status)
|
_UniFFILib.INSTANCE.ffi_bdk_70ef_OnlineWallet_object_free(this.pointer, status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1413,16 +1449,32 @@ class OnlineWallet(
|
|||||||
override fun getNewAddress(): String =
|
override fun getNewAddress(): String =
|
||||||
callWithPointer {
|
callWithPointer {
|
||||||
rustCall() { status ->
|
rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.bdk_b7c7_OnlineWallet_get_new_address(it, status)
|
_UniFFILib.INSTANCE.bdk_70ef_OnlineWallet_get_new_address(it, status)
|
||||||
}
|
}
|
||||||
}.let {
|
}.let {
|
||||||
String.lift(it)
|
String.lift(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getBalance(): ULong =
|
||||||
|
callWithPointer {
|
||||||
|
rustCallWithError(BdkException) { status ->
|
||||||
|
_UniFFILib.INSTANCE.bdk_70ef_OnlineWallet_get_balance(it, status)
|
||||||
|
}
|
||||||
|
}.let {
|
||||||
|
ULong.lift(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun sign(psbt: PartiallySignedBitcoinTransaction ) =
|
||||||
|
callWithPointer {
|
||||||
|
rustCallWithError(BdkException) { status ->
|
||||||
|
_UniFFILib.INSTANCE.bdk_70ef_OnlineWallet_sign(it, psbt.lower() , status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getNetwork(): Network =
|
override fun getNetwork(): Network =
|
||||||
callWithPointer {
|
callWithPointer {
|
||||||
rustCall() { status ->
|
rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.bdk_b7c7_OnlineWallet_get_network(it, status)
|
_UniFFILib.INSTANCE.bdk_70ef_OnlineWallet_get_network(it, status)
|
||||||
}
|
}
|
||||||
}.let {
|
}.let {
|
||||||
Network.lift(it)
|
Network.lift(it)
|
||||||
@ -1431,17 +1483,17 @@ class OnlineWallet(
|
|||||||
override fun sync(progressUpdate: BdkProgress, maxAddressParam: UInt? ) =
|
override fun sync(progressUpdate: BdkProgress, maxAddressParam: UInt? ) =
|
||||||
callWithPointer {
|
callWithPointer {
|
||||||
rustCallWithError(BdkException) { status ->
|
rustCallWithError(BdkException) { status ->
|
||||||
_UniFFILib.INSTANCE.bdk_b7c7_OnlineWallet_sync(it, CallbackInterfaceBdkProgressInternals.lower(progressUpdate), lowerOptionalu32(maxAddressParam) , status)
|
_UniFFILib.INSTANCE.bdk_70ef_OnlineWallet_sync(it, CallbackInterfaceBdkProgressInternals.lower(progressUpdate), lowerOptionalu32(maxAddressParam) , status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBalance(): ULong =
|
override fun broadcast(psbt: PartiallySignedBitcoinTransaction ): String =
|
||||||
callWithPointer {
|
callWithPointer {
|
||||||
rustCallWithError(BdkException) { status ->
|
rustCallWithError(BdkException) { status ->
|
||||||
_UniFFILib.INSTANCE.bdk_b7c7_OnlineWallet_get_balance(it, status)
|
_UniFFILib.INSTANCE.bdk_70ef_OnlineWallet_broadcast(it, psbt.lower() , status)
|
||||||
}
|
}
|
||||||
}.let {
|
}.let {
|
||||||
ULong.lift(it)
|
String.lift(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1473,7 +1525,7 @@ class PartiallySignedBitcoinTransaction(
|
|||||||
constructor(wallet: OnlineWallet, recipient: String, amount: ULong ) :
|
constructor(wallet: OnlineWallet, recipient: String, amount: ULong ) :
|
||||||
this(
|
this(
|
||||||
rustCallWithError(BdkException) { status ->
|
rustCallWithError(BdkException) { status ->
|
||||||
_UniFFILib.INSTANCE.bdk_b7c7_PartiallySignedBitcoinTransaction_new(wallet.lower(), recipient.lower(), amount.lower() ,status)
|
_UniFFILib.INSTANCE.bdk_70ef_PartiallySignedBitcoinTransaction_new(wallet.lower(), recipient.lower(), amount.lower() ,status)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1486,7 +1538,7 @@ class PartiallySignedBitcoinTransaction(
|
|||||||
*/
|
*/
|
||||||
override protected fun freeRustArcPtr() {
|
override protected fun freeRustArcPtr() {
|
||||||
rustCall() { status ->
|
rustCall() { status ->
|
||||||
_UniFFILib.INSTANCE.ffi_bdk_b7c7_PartiallySignedBitcoinTransaction_object_free(this.pointer, status)
|
_UniFFILib.INSTANCE.ffi_bdk_70ef_PartiallySignedBitcoinTransaction_object_free(this.pointer, status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1564,7 +1616,7 @@ internal object CallbackInterfaceBdkProgressInternals: CallbackInternals<BdkProg
|
|||||||
) {
|
) {
|
||||||
override fun register(lib: _UniFFILib) {
|
override fun register(lib: _UniFFILib) {
|
||||||
rustCall() { status ->
|
rustCall() { status ->
|
||||||
lib.ffi_bdk_b7c7_BdkProgress_init_callback(this.foreignCallback, status)
|
lib.ffi_bdk_70ef_BdkProgress_init_callback(this.foreignCallback, status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,7 @@ import org.junit.Test
|
|||||||
|
|
||||||
class LogProgress: BdkProgress {
|
class LogProgress: BdkProgress {
|
||||||
override fun update(progress: Float, message: String? ) {
|
override fun update(progress: Float, message: String? ) {
|
||||||
println(progress);
|
println("progress: $progress, message: $message")
|
||||||
println(message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
src/bdk.udl
16
src/bdk.udl
@ -66,7 +66,13 @@ interface DatabaseConfig {
|
|||||||
interface OfflineWallet {
|
interface OfflineWallet {
|
||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
constructor(string descriptor, Network network, DatabaseConfig database_config);
|
constructor(string descriptor, Network network, DatabaseConfig database_config);
|
||||||
|
|
||||||
|
// OfflineWalletOperations
|
||||||
string get_new_address();
|
string get_new_address();
|
||||||
|
[Throws=BdkError]
|
||||||
|
u64 get_balance();
|
||||||
|
[Throws=BdkError]
|
||||||
|
void sign([ByRef] PartiallySignedBitcoinTransaction psbt);
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary ElectrumConfig {
|
dictionary ElectrumConfig {
|
||||||
@ -98,12 +104,20 @@ callback interface BdkProgress {
|
|||||||
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);
|
||||||
|
|
||||||
|
// OfflineWalletOperations
|
||||||
string get_new_address();
|
string get_new_address();
|
||||||
|
[Throws=BdkError]
|
||||||
|
u64 get_balance();
|
||||||
|
[Throws=BdkError]
|
||||||
|
void sign([ByRef] PartiallySignedBitcoinTransaction psbt);
|
||||||
|
|
||||||
|
// OnlineWalletInterface
|
||||||
Network get_network();
|
Network get_network();
|
||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
void sync(BdkProgress progress_update, u32? max_address_param);
|
void sync(BdkProgress progress_update, u32? max_address_param);
|
||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
u64 get_balance();
|
string broadcast([ByRef] PartiallySignedBitcoinTransaction psbt);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface PartiallySignedBitcoinTransaction {
|
interface PartiallySignedBitcoinTransaction {
|
||||||
|
35
src/lib.rs
35
src/lib.rs
@ -1,4 +1,3 @@
|
|||||||
use bdk::address_validator::AddressValidatorError;
|
|
||||||
use bdk::bitcoin::util::psbt::PartiallySignedTransaction;
|
use bdk::bitcoin::util::psbt::PartiallySignedTransaction;
|
||||||
use bdk::bitcoin::{Address, Network};
|
use bdk::bitcoin::{Address, Network};
|
||||||
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
|
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
|
||||||
@ -9,7 +8,7 @@ use bdk::blockchain::{
|
|||||||
use bdk::database::any::{AnyDatabase, SledDbConfiguration};
|
use bdk::database::any::{AnyDatabase, SledDbConfiguration};
|
||||||
use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase};
|
use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase};
|
||||||
use bdk::wallet::AddressIndex;
|
use bdk::wallet::AddressIndex;
|
||||||
use bdk::{Error, Wallet};
|
use bdk::{Error, SignOptions, Wallet};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Mutex, MutexGuard};
|
use std::sync::{Mutex, MutexGuard};
|
||||||
@ -66,6 +65,22 @@ trait OfflineWalletOperations<B>: WalletHolder<B> {
|
|||||||
.address
|
.address
|
||||||
.to_string()
|
.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_balance(&self) -> Result<u64, Error> {
|
||||||
|
self.get_wallet().get_balance()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sign<'a>(&self, psbt: &'a PartiallySignedBitcoinTransaction) -> Result<(), Error> {
|
||||||
|
let mut psbt = psbt.internal.lock().unwrap();
|
||||||
|
let finalized = self.get_wallet().sign(&mut psbt, SignOptions::default())?;
|
||||||
|
match finalized {
|
||||||
|
true => Ok(()),
|
||||||
|
false => Err(BdkError::Generic(format!(
|
||||||
|
"transaction signing not finalized {:?}",
|
||||||
|
psbt
|
||||||
|
))),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OfflineWallet {
|
impl OfflineWallet {
|
||||||
@ -114,15 +129,17 @@ impl PartiallySignedBitcoinTransaction {
|
|||||||
let wallet = online_wallet.get_wallet();
|
let wallet = online_wallet.get_wallet();
|
||||||
match Address::from_str(&recipient) {
|
match Address::from_str(&recipient) {
|
||||||
Ok(address) => {
|
Ok(address) => {
|
||||||
|
let (psbt, _) = {
|
||||||
let mut builder = wallet.build_tx();
|
let mut builder = wallet.build_tx();
|
||||||
builder.add_recipient(address.script_pubkey(), amount);
|
builder.add_recipient(address.script_pubkey(), amount);
|
||||||
let (pst, ..) = builder.finish()?;
|
builder.finish()?
|
||||||
|
};
|
||||||
Ok(PartiallySignedBitcoinTransaction {
|
Ok(PartiallySignedBitcoinTransaction {
|
||||||
internal: Mutex::new(pst),
|
internal: Mutex::new(psbt),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(..) => Err(BdkError::AddressValidator(
|
Err(..) => Err(BdkError::Generic(
|
||||||
AddressValidatorError::InvalidScript,
|
"failed to read wallet address".to_string(),
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,8 +204,10 @@ impl OnlineWallet {
|
|||||||
.sync(BdkProgressHolder { progress_update }, max_address_param)
|
.sync(BdkProgressHolder { progress_update }, max_address_param)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_balance(&self) -> Result<u64, Error> {
|
fn broadcast<'a>(&self, psbt: &'a PartiallySignedBitcoinTransaction) -> Result<String, Error> {
|
||||||
self.wallet.lock().unwrap().get_balance()
|
let tx = psbt.internal.lock().unwrap().clone().extract_tx();
|
||||||
|
let tx_id = self.get_wallet().broadcast(tx)?;
|
||||||
|
Ok(tx_id.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user