feat: add Transaction and PartiallySignedTransaction types
This commit is contained in:
parent
1521811e9b
commit
13c751cebc
@ -94,7 +94,7 @@ interface TxBuilder {
|
||||
TxBuilder fee_rate(float sat_per_vbyte);
|
||||
|
||||
[Throws=BdkError]
|
||||
string finish([ByRef] Wallet wallet);
|
||||
PartiallySignedTransaction finish([ByRef] Wallet wallet);
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -225,7 +225,37 @@ interface Address {
|
||||
|
||||
Network network();
|
||||
|
||||
Script script_pubkey();
|
||||
|
||||
string to_qr_uri();
|
||||
|
||||
string as_string();
|
||||
};
|
||||
|
||||
interface Transaction {
|
||||
[Throws=BdkError]
|
||||
constructor(sequence<u8> transaction_bytes);
|
||||
|
||||
string txid();
|
||||
|
||||
u64 size();
|
||||
|
||||
u64 vsize();
|
||||
|
||||
boolean is_coin_base();
|
||||
|
||||
boolean is_explicitly_rbf();
|
||||
|
||||
boolean is_lock_time_enabled();
|
||||
|
||||
i32 version();
|
||||
};
|
||||
|
||||
interface PartiallySignedTransaction {
|
||||
[Throws=BdkError]
|
||||
constructor(string psbt_base64);
|
||||
|
||||
string serialize();
|
||||
|
||||
Transaction extract_tx();
|
||||
};
|
||||
|
@ -1,4 +1,15 @@
|
||||
use bdk::bitcoin::address::{NetworkChecked, NetworkUnchecked};
|
||||
use bdk::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf;
|
||||
use bdk::bitcoin::consensus::Decodable;
|
||||
use bdk::bitcoin::network::constants::Network as BdkNetwork;
|
||||
use bdk::bitcoin::psbt::PartiallySignedTransaction as BdkPartiallySignedTransaction;
|
||||
use bdk::bitcoin::Address as BdkAddress;
|
||||
use bdk::bitcoin::Transaction as BdkTransaction;
|
||||
use bdk::Error as BdkError;
|
||||
|
||||
use std::io::Cursor;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
/// A Bitcoin script.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@ -20,3 +31,251 @@ impl From<BdkScriptBuf> for Script {
|
||||
Script(script)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Network {
|
||||
/// Mainnet Bitcoin.
|
||||
Bitcoin,
|
||||
/// Bitcoin's testnet network.
|
||||
Testnet,
|
||||
/// Bitcoin's signet network.
|
||||
Signet,
|
||||
/// Bitcoin's regtest network.
|
||||
Regtest,
|
||||
}
|
||||
|
||||
impl From<Network> for BdkNetwork {
|
||||
fn from(network: Network) -> Self {
|
||||
match network {
|
||||
Network::Bitcoin => BdkNetwork::Bitcoin,
|
||||
Network::Testnet => BdkNetwork::Testnet,
|
||||
Network::Signet => BdkNetwork::Signet,
|
||||
Network::Regtest => BdkNetwork::Regtest,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BdkNetwork> for Network {
|
||||
fn from(network: BdkNetwork) -> Self {
|
||||
match network {
|
||||
BdkNetwork::Bitcoin => Network::Bitcoin,
|
||||
BdkNetwork::Testnet => Network::Testnet,
|
||||
BdkNetwork::Signet => Network::Signet,
|
||||
BdkNetwork::Regtest => Network::Regtest,
|
||||
_ => panic!("Network {} not supported", network),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A Bitcoin address.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Address {
|
||||
inner: BdkAddress<NetworkChecked>,
|
||||
}
|
||||
|
||||
impl Address {
|
||||
pub fn new(address: String, network: Network) -> Result<Self, BdkError> {
|
||||
Ok(Address {
|
||||
inner: address
|
||||
.parse::<bdk::bitcoin::Address<NetworkUnchecked>>()
|
||||
.unwrap() // TODO 11: Handle error correctly by rethrowing it as a BdkError
|
||||
.require_network(network.into())
|
||||
.map_err(|e| BdkError::Generic(e.to_string()))?,
|
||||
})
|
||||
}
|
||||
|
||||
/// alternative constructor
|
||||
// fn from_script(script: Arc<Script>, network: Network) -> Result<Self, BdkError> {
|
||||
// BdkAddress::from_script(&script.inner, network)
|
||||
// .map(|a| Address { inner: a })
|
||||
// .map_err(|e| BdkError::Generic(e.to_string()))
|
||||
// }
|
||||
//
|
||||
// fn payload(&self) -> Payload {
|
||||
// match &self.inner.payload.clone() {
|
||||
// BdkPayload::PubkeyHash(pubkey_hash) => Payload::PubkeyHash {
|
||||
// pubkey_hash: pubkey_hash.to_vec(),
|
||||
// },
|
||||
// BdkPayload::ScriptHash(script_hash) => Payload::ScriptHash {
|
||||
// script_hash: script_hash.to_vec(),
|
||||
// },
|
||||
// BdkPayload::WitnessProgram { version, program } => Payload::WitnessProgram {
|
||||
// version: *version,
|
||||
// program: program.clone(),
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
|
||||
pub fn network(&self) -> Network {
|
||||
self.inner.network.into()
|
||||
}
|
||||
|
||||
pub fn script_pubkey(&self) -> Arc<Script> {
|
||||
Arc::new(Script(self.inner.script_pubkey()))
|
||||
}
|
||||
|
||||
pub fn to_qr_uri(&self) -> String {
|
||||
self.inner.to_qr_uri()
|
||||
}
|
||||
|
||||
pub fn as_string(&self) -> String {
|
||||
self.inner.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Address> for BdkAddress {
|
||||
fn from(address: Address) -> Self {
|
||||
address.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BdkAddress> for Address {
|
||||
fn from(address: BdkAddress) -> Self {
|
||||
Address { inner: address }
|
||||
}
|
||||
}
|
||||
|
||||
/// A Bitcoin transaction.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Transaction {
|
||||
inner: BdkTransaction,
|
||||
}
|
||||
|
||||
impl Transaction {
|
||||
pub fn new(transaction_bytes: Vec<u8>) -> Result<Self, BdkError> {
|
||||
let mut decoder = Cursor::new(transaction_bytes);
|
||||
let tx: BdkTransaction = BdkTransaction::consensus_decode(&mut decoder)
|
||||
.map_err(|e| BdkError::Generic(e.to_string()))?;
|
||||
Ok(Transaction { inner: tx })
|
||||
}
|
||||
|
||||
pub fn txid(&self) -> String {
|
||||
self.inner.txid().to_string()
|
||||
}
|
||||
|
||||
// fn weight(&self) -> u64 {
|
||||
// self.inner.weight() as u64
|
||||
// }
|
||||
|
||||
pub fn size(&self) -> u64 {
|
||||
self.inner.size() as u64
|
||||
}
|
||||
|
||||
pub fn vsize(&self) -> u64 {
|
||||
self.inner.vsize() as u64
|
||||
}
|
||||
|
||||
// fn serialize(&self) -> Vec<u8> {
|
||||
// self.inner.serialize()
|
||||
// }
|
||||
|
||||
pub fn is_coin_base(&self) -> bool {
|
||||
self.inner.is_coin_base()
|
||||
}
|
||||
|
||||
pub fn is_explicitly_rbf(&self) -> bool {
|
||||
self.inner.is_explicitly_rbf()
|
||||
}
|
||||
|
||||
pub fn is_lock_time_enabled(&self) -> bool {
|
||||
self.inner.is_lock_time_enabled()
|
||||
}
|
||||
|
||||
pub fn version(&self) -> i32 {
|
||||
self.inner.version
|
||||
}
|
||||
|
||||
// fn lock_time(&self) -> u32 {
|
||||
// self.inner.lock_time.0
|
||||
// }
|
||||
|
||||
// fn input(&self) -> Vec<TxIn> {
|
||||
// self.inner.input.iter().map(|x| x.into()).collect()
|
||||
// }
|
||||
//
|
||||
// fn output(&self) -> Vec<TxOut> {
|
||||
// self.inner.output.iter().map(|x| x.into()).collect()
|
||||
// }
|
||||
}
|
||||
|
||||
impl From<BdkTransaction> for Transaction {
|
||||
fn from(tx: BdkTransaction) -> Self {
|
||||
Transaction { inner: tx }
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct PartiallySignedTransaction {
|
||||
pub(crate) inner: Mutex<BdkPartiallySignedTransaction>,
|
||||
}
|
||||
|
||||
impl PartiallySignedTransaction {
|
||||
pub(crate) fn new(psbt_base64: String) -> Result<Self, BdkError> {
|
||||
let psbt: BdkPartiallySignedTransaction =
|
||||
BdkPartiallySignedTransaction::from_str(&psbt_base64)
|
||||
.map_err(|e| BdkError::Generic(e.to_string()))?;
|
||||
|
||||
Ok(PartiallySignedTransaction {
|
||||
inner: Mutex::new(psbt),
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn serialize(&self) -> String {
|
||||
let psbt = self.inner.lock().unwrap().clone();
|
||||
psbt.to_string()
|
||||
}
|
||||
|
||||
// pub(crate) fn txid(&self) -> String {
|
||||
// let tx = self.inner.lock().unwrap().clone().extract_tx();
|
||||
// let txid = tx.txid();
|
||||
// txid.to_hex()
|
||||
// }
|
||||
|
||||
/// Return the transaction.
|
||||
pub(crate) fn extract_tx(&self) -> Arc<Transaction> {
|
||||
let tx = self.inner.lock().unwrap().clone().extract_tx();
|
||||
Arc::new(tx.into())
|
||||
}
|
||||
|
||||
// /// Combines this PartiallySignedTransaction with other PSBT as described by BIP 174.
|
||||
// ///
|
||||
// /// In accordance with BIP 174 this function is commutative i.e., `A.combine(B) == B.combine(A)`
|
||||
// pub(crate) fn combine(
|
||||
// &self,
|
||||
// other: Arc<PartiallySignedTransaction>,
|
||||
// ) -> Result<Arc<PartiallySignedTransaction>, BdkError> {
|
||||
// let other_psbt = other.inner.lock().unwrap().clone();
|
||||
// let mut original_psbt = self.inner.lock().unwrap().clone();
|
||||
//
|
||||
// original_psbt.combine(other_psbt)?;
|
||||
// Ok(Arc::new(PartiallySignedTransaction {
|
||||
// inner: Mutex::new(original_psbt),
|
||||
// }))
|
||||
// }
|
||||
|
||||
// /// The total transaction fee amount, sum of input amounts minus sum of output amounts, in Sats.
|
||||
// /// If the PSBT is missing a TxOut for an input returns None.
|
||||
// pub(crate) fn fee_amount(&self) -> Option<u64> {
|
||||
// self.inner.lock().unwrap().fee_amount()
|
||||
// }
|
||||
|
||||
// /// The transaction's fee rate. This value will only be accurate if calculated AFTER the
|
||||
// /// `PartiallySignedTransaction` is finalized and all witness/signature data is added to the
|
||||
// /// transaction.
|
||||
// /// If the PSBT is missing a TxOut for an input returns None.
|
||||
// pub(crate) fn fee_rate(&self) -> Option<Arc<FeeRate>> {
|
||||
// self.inner.lock().unwrap().fee_rate().map(Arc::new)
|
||||
// }
|
||||
|
||||
// /// Serialize the PSBT data structure as a String of JSON.
|
||||
// pub(crate) fn json_serialize(&self) -> String {
|
||||
// let psbt = self.inner.lock().unwrap();
|
||||
// serde_json::to_string(psbt.deref()).unwrap()
|
||||
// }
|
||||
}
|
||||
|
||||
impl From<BdkPartiallySignedTransaction> for PartiallySignedTransaction {
|
||||
fn from(psbt: BdkPartiallySignedTransaction) -> Self {
|
||||
PartiallySignedTransaction {
|
||||
inner: Mutex::new(psbt),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
use crate::keys::DescriptorPublicKey;
|
||||
use crate::keys::DescriptorSecretKey;
|
||||
use crate::Network;
|
||||
|
||||
use bdk::bitcoin::bip32::Fingerprint;
|
||||
use bdk::bitcoin::key::Secp256k1;
|
||||
use bdk::descriptor::{ExtendedDescriptor, IntoWalletDescriptor};
|
||||
@ -9,13 +13,10 @@ use bdk::template::{
|
||||
};
|
||||
use bdk::Error as BdkError;
|
||||
use bdk::KeychainKind;
|
||||
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::keys::DescriptorPublicKey;
|
||||
use crate::keys::DescriptorSecretKey;
|
||||
use crate::Network;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Descriptor {
|
||||
pub extended_descriptor: ExtendedDescriptor,
|
||||
|
@ -1,8 +1,10 @@
|
||||
use crate::wallet::{Update, Wallet};
|
||||
|
||||
use bdk::wallet::Update as BdkUpdate;
|
||||
use bdk::Error as BdkError;
|
||||
use bdk_esplora::esplora_client::{BlockingClient, Builder};
|
||||
use bdk_esplora::EsploraExt;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct EsploraClient(BlockingClient);
|
||||
|
@ -1,3 +1,5 @@
|
||||
use crate::Network;
|
||||
|
||||
use bdk::bitcoin::bip32::DerivationPath as BdkDerivationPath;
|
||||
use bdk::bitcoin::key::Secp256k1;
|
||||
use bdk::bitcoin::secp256k1::rand;
|
||||
@ -11,14 +13,13 @@ use bdk::keys::{
|
||||
use bdk::miniscript::descriptor::{DescriptorXKey, Wildcard};
|
||||
use bdk::miniscript::BareCtx;
|
||||
use bdk::Error as BdkError;
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::Network;
|
||||
|
||||
// /// Mnemonic phrases are a human-readable version of the private keys.
|
||||
// /// Supported number of words are 12, 15, 18, 21 and 24.
|
||||
/// Mnemonic phrases are a human-readable version of the private keys.
|
||||
/// Supported number of words are 12, 15, 18, 21 and 24.
|
||||
pub(crate) struct Mnemonic {
|
||||
inner: BdkMnemonic,
|
||||
}
|
||||
|
@ -2,22 +2,14 @@ mod bitcoin;
|
||||
mod descriptor;
|
||||
mod esplora;
|
||||
mod keys;
|
||||
mod psbt;
|
||||
mod wallet;
|
||||
|
||||
use bdk::bitcoin::address::{NetworkChecked, NetworkUnchecked};
|
||||
use bdk::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf;
|
||||
use bdk::bitcoin::Address as BdkAddress;
|
||||
use bdk::bitcoin::Network as BdkNetwork;
|
||||
use bdk::wallet::AddressIndex as BdkAddressIndex;
|
||||
use bdk::wallet::AddressInfo as BdkAddressInfo;
|
||||
use bdk::wallet::Balance as BdkBalance;
|
||||
use bdk::Error as BdkError;
|
||||
use bdk::KeychainKind;
|
||||
use std::sync::Arc;
|
||||
|
||||
// TODO 6: Why are these imports required?
|
||||
use crate::bitcoin::Address;
|
||||
use crate::bitcoin::Network;
|
||||
use crate::bitcoin::PartiallySignedTransaction;
|
||||
use crate::bitcoin::Script;
|
||||
use crate::bitcoin::Transaction;
|
||||
use crate::descriptor::Descriptor;
|
||||
use crate::esplora::EsploraClient;
|
||||
use crate::keys::DerivationPath;
|
||||
@ -27,50 +19,24 @@ use crate::keys::Mnemonic;
|
||||
use crate::wallet::TxBuilder;
|
||||
use crate::wallet::Update;
|
||||
use crate::wallet::Wallet;
|
||||
|
||||
use bdk::keys::bip39::WordCount;
|
||||
use bdk::wallet::AddressIndex as BdkAddressIndex;
|
||||
use bdk::wallet::AddressInfo as BdkAddressInfo;
|
||||
use bdk::wallet::Balance as BdkBalance;
|
||||
use bdk::Error as BdkError;
|
||||
use bdk::KeychainKind;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
uniffi::include_scaffolding!("bdk");
|
||||
|
||||
pub enum Network {
|
||||
/// Mainnet Bitcoin.
|
||||
Bitcoin,
|
||||
/// Bitcoin's testnet network.
|
||||
Testnet,
|
||||
/// Bitcoin's signet network.
|
||||
Signet,
|
||||
/// Bitcoin's regtest network.
|
||||
Regtest,
|
||||
}
|
||||
|
||||
impl From<Network> for BdkNetwork {
|
||||
fn from(network: Network) -> Self {
|
||||
match network {
|
||||
Network::Bitcoin => BdkNetwork::Bitcoin,
|
||||
Network::Testnet => BdkNetwork::Testnet,
|
||||
Network::Signet => BdkNetwork::Signet,
|
||||
Network::Regtest => BdkNetwork::Regtest,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BdkNetwork> for Network {
|
||||
fn from(network: BdkNetwork) -> Self {
|
||||
match network {
|
||||
BdkNetwork::Bitcoin => Network::Bitcoin,
|
||||
BdkNetwork::Testnet => Network::Testnet,
|
||||
BdkNetwork::Signet => Network::Signet,
|
||||
BdkNetwork::Regtest => Network::Regtest,
|
||||
_ => panic!("Network {} not supported", network),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /// A output script and an amount of satoshis.
|
||||
/// A output script and an amount of satoshis.
|
||||
// pub struct ScriptAmount {
|
||||
// pub script: Arc<Script>,
|
||||
// pub amount: u64,
|
||||
// }
|
||||
//
|
||||
|
||||
/// A derived address and the index it was found at.
|
||||
pub struct AddressInfo {
|
||||
/// Child index of this address.
|
||||
@ -343,144 +309,6 @@ impl Balance {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /// A Bitcoin transaction.
|
||||
// #[derive(Debug, Clone, PartialEq, Eq)]
|
||||
// pub struct Transaction {
|
||||
// inner: BdkTransaction,
|
||||
// }
|
||||
//
|
||||
// impl Transaction {
|
||||
// fn new(transaction_bytes: Vec<u8>) -> Result<Self, BdkError> {
|
||||
// let mut decoder = Cursor::new(transaction_bytes);
|
||||
// let tx: BdkTransaction = BdkTransaction::consensus_decode(&mut decoder)?;
|
||||
// Ok(Transaction { inner: tx })
|
||||
// }
|
||||
//
|
||||
// fn txid(&self) -> String {
|
||||
// self.inner.txid().to_string()
|
||||
// }
|
||||
//
|
||||
// fn weight(&self) -> u64 {
|
||||
// self.inner.weight() as u64
|
||||
// }
|
||||
//
|
||||
// fn size(&self) -> u64 {
|
||||
// self.inner.size() as u64
|
||||
// }
|
||||
//
|
||||
// fn vsize(&self) -> u64 {
|
||||
// self.inner.vsize() as u64
|
||||
// }
|
||||
//
|
||||
// fn serialize(&self) -> Vec<u8> {
|
||||
// self.inner.serialize()
|
||||
// }
|
||||
//
|
||||
// fn is_coin_base(&self) -> bool {
|
||||
// self.inner.is_coin_base()
|
||||
// }
|
||||
//
|
||||
// fn is_explicitly_rbf(&self) -> bool {
|
||||
// self.inner.is_explicitly_rbf()
|
||||
// }
|
||||
//
|
||||
// fn is_lock_time_enabled(&self) -> bool {
|
||||
// self.inner.is_lock_time_enabled()
|
||||
// }
|
||||
//
|
||||
// fn version(&self) -> i32 {
|
||||
// self.inner.version
|
||||
// }
|
||||
//
|
||||
// fn lock_time(&self) -> u32 {
|
||||
// self.inner.lock_time.0
|
||||
// }
|
||||
//
|
||||
// fn input(&self) -> Vec<TxIn> {
|
||||
// self.inner.input.iter().map(|x| x.into()).collect()
|
||||
// }
|
||||
//
|
||||
// fn output(&self) -> Vec<TxOut> {
|
||||
// self.inner.output.iter().map(|x| x.into()).collect()
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl From<BdkTransaction> for Transaction {
|
||||
// fn from(tx: BdkTransaction) -> Self {
|
||||
// Transaction { inner: tx }
|
||||
// }
|
||||
// }
|
||||
|
||||
/// A Bitcoin address.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Address {
|
||||
inner: BdkAddress<NetworkChecked>,
|
||||
}
|
||||
|
||||
impl Address {
|
||||
fn new(address: String, network: Network) -> Result<Self, BdkError> {
|
||||
Ok(Address {
|
||||
inner: address
|
||||
.parse::<bdk::bitcoin::Address<NetworkUnchecked>>()
|
||||
.unwrap() // TODO 11: Handle error correctly by rethrowing it as a BdkError
|
||||
.require_network(network.into())
|
||||
.map_err(|e| BdkError::Generic(e.to_string()))?,
|
||||
})
|
||||
}
|
||||
|
||||
/// alternative constructor
|
||||
// fn from_script(script: Arc<Script>, network: Network) -> Result<Self, BdkError> {
|
||||
// BdkAddress::from_script(&script.inner, network)
|
||||
// .map(|a| Address { inner: a })
|
||||
// .map_err(|e| BdkError::Generic(e.to_string()))
|
||||
// }
|
||||
//
|
||||
// fn payload(&self) -> Payload {
|
||||
// match &self.inner.payload.clone() {
|
||||
// BdkPayload::PubkeyHash(pubkey_hash) => Payload::PubkeyHash {
|
||||
// pubkey_hash: pubkey_hash.to_vec(),
|
||||
// },
|
||||
// BdkPayload::ScriptHash(script_hash) => Payload::ScriptHash {
|
||||
// script_hash: script_hash.to_vec(),
|
||||
// },
|
||||
// BdkPayload::WitnessProgram { version, program } => Payload::WitnessProgram {
|
||||
// version: *version,
|
||||
// program: program.clone(),
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
|
||||
fn network(&self) -> Network {
|
||||
self.inner.network.into()
|
||||
}
|
||||
|
||||
fn script_pubkey(&self) -> Arc<Script> {
|
||||
Arc::new(Script {
|
||||
inner: self.inner.script_pubkey(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_qr_uri(&self) -> String {
|
||||
self.inner.to_qr_uri()
|
||||
}
|
||||
|
||||
fn as_string(&self) -> String {
|
||||
self.inner.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BdkAddress> for Address {
|
||||
fn from(address: BdkAddress) -> Self {
|
||||
Address { inner: address }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Address> for BdkAddress {
|
||||
fn from(address: Address) -> Self {
|
||||
address.inner
|
||||
}
|
||||
}
|
||||
|
||||
// /// The method used to produce an address.
|
||||
// #[derive(Debug)]
|
||||
@ -498,23 +326,6 @@ impl From<Address> for BdkAddress {
|
||||
// },
|
||||
// }
|
||||
|
||||
/// A Bitcoin script.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Script {
|
||||
inner: BdkScriptBuf,
|
||||
}
|
||||
|
||||
impl Script {
|
||||
fn new(raw_output_script: Vec<u8>) -> Self {
|
||||
let script: BdkScriptBuf = BdkScriptBuf::from(raw_output_script);
|
||||
Script { inner: script }
|
||||
}
|
||||
|
||||
fn to_bytes(&self) -> Vec<u8> {
|
||||
self.inner.to_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
// impl From<BdkScript> for Script {
|
||||
// fn from(bdk_script: BdkScript) -> Self {
|
||||
// Script { inner: bdk_script }
|
||||
|
@ -1,119 +0,0 @@
|
||||
// use bdk::bitcoin::hashes::hex::ToHex;
|
||||
// use bdk::bitcoin::util::psbt::PartiallySignedTransaction as BdkPartiallySignedTransaction;
|
||||
// use bdk::bitcoincore_rpc::jsonrpc::serde_json;
|
||||
// use bdk::psbt::PsbtUtils;
|
||||
// use std::ops::Deref;
|
||||
// use std::str::FromStr;
|
||||
// use std::sync::{Arc, Mutex};
|
||||
//
|
||||
// use crate::{BdkError, FeeRate, Transaction};
|
||||
//
|
||||
// #[derive(Debug)]
|
||||
// pub(crate) struct PartiallySignedTransaction {
|
||||
// pub(crate) inner: Mutex<BdkPartiallySignedTransaction>,
|
||||
// }
|
||||
//
|
||||
// impl PartiallySignedTransaction {
|
||||
// pub(crate) fn new(psbt_base64: String) -> Result<Self, BdkError> {
|
||||
// let psbt: BdkPartiallySignedTransaction =
|
||||
// BdkPartiallySignedTransaction::from_str(&psbt_base64)?;
|
||||
// Ok(PartiallySignedTransaction {
|
||||
// inner: Mutex::new(psbt),
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// pub(crate) fn serialize(&self) -> String {
|
||||
// let psbt = self.inner.lock().unwrap().clone();
|
||||
// psbt.to_string()
|
||||
// }
|
||||
//
|
||||
// pub(crate) fn txid(&self) -> String {
|
||||
// let tx = self.inner.lock().unwrap().clone().extract_tx();
|
||||
// let txid = tx.txid();
|
||||
// txid.to_hex()
|
||||
// }
|
||||
//
|
||||
// /// Return the transaction.
|
||||
// pub(crate) fn extract_tx(&self) -> Arc<Transaction> {
|
||||
// let tx = self.inner.lock().unwrap().clone().extract_tx();
|
||||
// Arc::new(tx.into())
|
||||
// }
|
||||
//
|
||||
// /// Combines this PartiallySignedTransaction with other PSBT as described by BIP 174.
|
||||
// ///
|
||||
// /// In accordance with BIP 174 this function is commutative i.e., `A.combine(B) == B.combine(A)`
|
||||
// pub(crate) fn combine(
|
||||
// &self,
|
||||
// other: Arc<PartiallySignedTransaction>,
|
||||
// ) -> Result<Arc<PartiallySignedTransaction>, BdkError> {
|
||||
// let other_psbt = other.inner.lock().unwrap().clone();
|
||||
// let mut original_psbt = self.inner.lock().unwrap().clone();
|
||||
//
|
||||
// original_psbt.combine(other_psbt)?;
|
||||
// Ok(Arc::new(PartiallySignedTransaction {
|
||||
// inner: Mutex::new(original_psbt),
|
||||
// }))
|
||||
// }
|
||||
//
|
||||
// /// The total transaction fee amount, sum of input amounts minus sum of output amounts, in Sats.
|
||||
// /// If the PSBT is missing a TxOut for an input returns None.
|
||||
// pub(crate) fn fee_amount(&self) -> Option<u64> {
|
||||
// self.inner.lock().unwrap().fee_amount()
|
||||
// }
|
||||
//
|
||||
// /// The transaction's fee rate. This value will only be accurate if calculated AFTER the
|
||||
// /// `PartiallySignedTransaction` is finalized and all witness/signature data is added to the
|
||||
// /// transaction.
|
||||
// /// If the PSBT is missing a TxOut for an input returns None.
|
||||
// pub(crate) fn fee_rate(&self) -> Option<Arc<FeeRate>> {
|
||||
// self.inner.lock().unwrap().fee_rate().map(Arc::new)
|
||||
// }
|
||||
//
|
||||
// /// Serialize the PSBT data structure as a String of JSON.
|
||||
// pub(crate) fn json_serialize(&self) -> String {
|
||||
// let psbt = self.inner.lock().unwrap();
|
||||
// serde_json::to_string(psbt.deref()).unwrap()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // The goal of these tests to to ensure `bdk-ffi` intermediate code correctly calls `bdk` APIs.
|
||||
// // These tests should not be used to verify `bdk` behavior that is already tested in the `bdk`
|
||||
// // crate.
|
||||
// #[cfg(test)]
|
||||
// mod test {
|
||||
// use crate::wallet::{TxBuilder, Wallet};
|
||||
// use bdk::wallet::get_funded_wallet;
|
||||
// use std::sync::Mutex;
|
||||
//
|
||||
// #[test]
|
||||
// fn test_psbt_fee() {
|
||||
// let test_wpkh = "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)";
|
||||
// let (funded_wallet, _, _) = get_funded_wallet(test_wpkh);
|
||||
// let test_wallet = Wallet {
|
||||
// inner_mutex: Mutex::new(funded_wallet),
|
||||
// };
|
||||
// let drain_to_address = "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt".to_string();
|
||||
// let drain_to_script = crate::Address::new(drain_to_address)
|
||||
// .unwrap()
|
||||
// .script_pubkey();
|
||||
//
|
||||
// let tx_builder = TxBuilder::new()
|
||||
// .fee_rate(2.0)
|
||||
// .drain_wallet()
|
||||
// .drain_to(drain_to_script.clone());
|
||||
// //dbg!(&tx_builder);
|
||||
// assert!(tx_builder.drain_wallet);
|
||||
// assert_eq!(tx_builder.drain_to, Some(drain_to_script.inner.clone()));
|
||||
//
|
||||
// let tx_builder_result = tx_builder.finish(&test_wallet).unwrap();
|
||||
//
|
||||
// assert!(tx_builder_result.psbt.fee_rate().is_some());
|
||||
// assert_eq!(
|
||||
// tx_builder_result.psbt.fee_rate().unwrap().as_sat_per_vb(),
|
||||
// 2.682927
|
||||
// );
|
||||
//
|
||||
// assert!(tx_builder_result.psbt.fee_amount().is_some());
|
||||
// assert_eq!(tx_builder_result.psbt.fee_amount().unwrap(), 220);
|
||||
// }
|
||||
// }
|
@ -1,11 +1,14 @@
|
||||
use crate::bitcoin::PartiallySignedTransaction;
|
||||
use crate::descriptor::Descriptor;
|
||||
use crate::{AddressIndex, AddressInfo, Network};
|
||||
use crate::{Balance, Script};
|
||||
|
||||
use bdk::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf;
|
||||
use bdk::wallet::Update as BdkUpdate;
|
||||
use bdk::Wallet as BdkWallet;
|
||||
use bdk::{Error as BdkError, FeeRate};
|
||||
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
use bdk::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Wallet {
|
||||
@ -353,7 +356,7 @@ impl TxBuilder {
|
||||
/// Add a recipient to the internal list.
|
||||
pub(crate) fn add_recipient(&self, script: Arc<Script>, amount: u64) -> Arc<Self> {
|
||||
let mut recipients: Vec<(BdkScriptBuf, u64)> = self.recipients.clone();
|
||||
recipients.append(&mut vec![(script.inner.clone(), amount)]);
|
||||
recipients.append(&mut vec![(script.0.clone(), amount)]);
|
||||
|
||||
Arc::new(TxBuilder {
|
||||
recipients,
|
||||
@ -502,7 +505,10 @@ impl TxBuilder {
|
||||
//
|
||||
/// Finish building the transaction. Returns the BIP174 PSBT.
|
||||
/// TODO: The TxBuilder in bdk returns a Psbt type
|
||||
pub(crate) fn finish(&self, wallet: &Wallet) -> Result<String, BdkError> {
|
||||
pub(crate) fn finish(
|
||||
&self,
|
||||
wallet: &Wallet,
|
||||
) -> Result<Arc<PartiallySignedTransaction>, BdkError> {
|
||||
// TODO: I had to change the wallet here to be mutable. Why is that now required with the 1.0 API?
|
||||
let mut wallet = wallet.get_wallet();
|
||||
let mut tx_builder = wallet.build_tx();
|
||||
@ -551,7 +557,11 @@ impl TxBuilder {
|
||||
// tx_builder.add_data(self.data.as_slice());
|
||||
// }
|
||||
|
||||
tx_builder.finish().map(|psbt| psbt.serialize_hex())
|
||||
// tx_builder.finish().map(|psbt| psbt.serialize_hex())
|
||||
// tx_builder.finish().into()
|
||||
let psbt = tx_builder.finish()?;
|
||||
|
||||
Ok(Arc::new(psbt.into()))
|
||||
}
|
||||
}
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user