Expose all fields on the Transaction type

This commit is contained in:
thunderbiscuit 2023-03-13 12:04:51 -04:00
parent e0506deffa
commit 40ca62086c
No known key found for this signature in database
GPG Key ID: 88253696EB836462
4 changed files with 51 additions and 16 deletions

View File

@ -188,7 +188,7 @@ dictionary OutPoint {
dictionary TxOut { dictionary TxOut {
u64 value; u64 value;
string address; Script script_pubkey;
}; };
enum KeychainKind { enum KeychainKind {

View File

@ -17,9 +17,7 @@ use crate::wallet::{BumpFeeTxBuilder, TxBuilder, Wallet};
use bdk::bitcoin::blockdata::script::Script as BdkScript; use bdk::bitcoin::blockdata::script::Script as BdkScript;
use bdk::bitcoin::consensus::Decodable; use bdk::bitcoin::consensus::Decodable;
use bdk::bitcoin::psbt::serialize::Serialize; use bdk::bitcoin::psbt::serialize::Serialize;
use bdk::bitcoin::{ use bdk::bitcoin::{Address as BdkAddress, Network, OutPoint as BdkOutPoint, Transaction as BdkTransaction, Txid};
Address as BdkAddress, Network, OutPoint as BdkOutPoint, Transaction as BdkTransaction, Txid,
};
use bdk::blockchain::Progress as BdkProgress; use bdk::blockchain::Progress as BdkProgress;
use bdk::database::any::{SledDbConfiguration, SqliteDbConfiguration}; use bdk::database::any::{SledDbConfiguration, SqliteDbConfiguration};
use bdk::keys::bip39::WordCount; use bdk::keys::bip39::WordCount;
@ -79,7 +77,7 @@ pub enum AddressIndex {
/// Use with caution, if an index is given that is less than the current descriptor index /// Use with caution, if an index is given that is less than the current descriptor index
/// then the returned address and subsequent addresses returned by calls to `AddressIndex::New` /// then the returned address and subsequent addresses returned by calls to `AddressIndex::New`
/// and `AddressIndex::LastUsed` may have already been used. Also if the index is reset to a /// and `AddressIndex::LastUsed` may have already been used. Also if the index is reset to a
/// value earlier than the [`crate::blockchain::Blockchain`] stop_gap (default is 20) then a /// value earlier than the [`Blockchain`] stop_gap (default is 20) then a
/// larger stop_gap should be used to monitor for all possibly used addresses. /// larger stop_gap should be used to monitor for all possibly used addresses.
Reset { index: u32 }, Reset { index: u32 },
} }
@ -175,11 +173,12 @@ impl From<BdkBalance> for Balance {
} }
/// A transaction output, which defines new coins to be created from old ones. /// A transaction output, which defines new coins to be created from old ones.
#[derive(Debug)]
pub struct TxOut { pub struct TxOut {
/// The value of the output, in satoshis. /// The value of the output, in satoshis.
value: u64, value: u64,
/// The address of the output. /// The address of the output.
address: String, script_pubkey: Arc<Script>,
} }
pub struct LocalUtxo { pub struct LocalUtxo {
@ -189,14 +188,12 @@ pub struct LocalUtxo {
is_spent: bool, is_spent: bool,
} }
// This trait is used to convert the bdk TxOut type with field `script_pubkey: Script`
// into the bdk-ffi TxOut type which has a field `address: String` instead
trait NetworkLocalUtxo { trait NetworkLocalUtxo {
fn from_utxo(x: &bdk::LocalUtxo, network: Network) -> LocalUtxo; fn from_utxo(x: &bdk::LocalUtxo) -> LocalUtxo;
} }
impl NetworkLocalUtxo for LocalUtxo { impl NetworkLocalUtxo for LocalUtxo {
fn from_utxo(x: &bdk::LocalUtxo, network: Network) -> LocalUtxo { fn from_utxo(x: &bdk::LocalUtxo) -> LocalUtxo {
LocalUtxo { LocalUtxo {
outpoint: OutPoint { outpoint: OutPoint {
txid: x.outpoint.txid.to_string(), txid: x.outpoint.txid.to_string(),
@ -204,9 +201,7 @@ impl NetworkLocalUtxo for LocalUtxo {
}, },
txout: TxOut { txout: TxOut {
value: x.txout.value, value: x.txout.value,
address: BdkAddress::from_script(&x.txout.script_pubkey, network) script_pubkey: Arc::new(Script { script: x.txout.script_pubkey.clone() })
.unwrap()
.to_string(),
}, },
keychain: x.keychain, keychain: x.keychain,
is_spent: x.is_spent, is_spent: x.is_spent,
@ -238,17 +233,49 @@ impl fmt::Debug for ProgressHolder {
} }
} }
#[derive(Debug)]
pub struct TxIn {
pub previous_output: OutPoint,
pub script_sig: Script,
pub sequence: u32,
pub witness: Vec<Vec<u8>>,
}
/// A Bitcoin transaction. /// A Bitcoin transaction.
#[derive(Debug)] #[derive(Debug)]
pub struct Transaction { pub struct Transaction {
internal: BdkTransaction, internal: BdkTransaction,
pub version: i32,
pub lock_time: u32,
pub inputs: Vec<TxIn>,
pub outputs: Vec<TxOut>,
} }
impl Transaction { impl Transaction {
fn new(transaction_bytes: Vec<u8>) -> Result<Self, BdkError> { fn new(transaction_bytes: Vec<u8>) -> Result<Self, BdkError> {
let mut decoder = Cursor::new(transaction_bytes); let mut decoder = Cursor::new(transaction_bytes);
let tx: BdkTransaction = BdkTransaction::consensus_decode(&mut decoder)?; let tx: BdkTransaction = BdkTransaction::consensus_decode(&mut decoder)?;
Ok(Transaction { internal: tx }) let inputs: Vec<TxIn> = tx.input.iter().map(|input| TxIn {
previous_output: OutPoint {
txid: input.previous_output.txid.to_string(),
vout: input.previous_output.vout,
},
script_sig: Script::from(input.script_sig.clone()),
sequence: input.sequence.0,
witness: input.witness.to_vec(),
}).collect();
let outputs: Vec<TxOut> = tx.output.iter().map(|output| TxOut {
value: output.value,
script_pubkey: Arc::new(Script::from(output.script_pubkey.clone())),
}).collect();
Ok(Transaction {
internal: tx.clone(),
version: tx.version,
lock_time: tx.lock_time.0,
inputs,
outputs,
})
} }
fn txid(&self) -> String { fn txid(&self) -> String {
@ -316,6 +343,12 @@ impl Script {
} }
} }
impl From<BdkScript> for Script {
fn from(bdk_script: BdkScript) -> Self {
Script { script: bdk_script }
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
enum RbfValue { enum RbfValue {
Default, Default,

View File

@ -3,6 +3,7 @@ use bdk::bitcoin::util::psbt::PartiallySignedTransaction as BdkPartiallySignedTr
use bdk::psbt::PsbtUtils; use bdk::psbt::PsbtUtils;
use std::str::FromStr; use std::str::FromStr;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use bdk::bitcoin::consensus::serialize;
use crate::{BdkError, FeeRate, Transaction}; use crate::{BdkError, FeeRate, Transaction};
@ -34,7 +35,8 @@ impl PartiallySignedTransaction {
/// Return the transaction. /// Return the transaction.
pub(crate) fn extract_tx(&self) -> Arc<Transaction> { pub(crate) fn extract_tx(&self) -> Arc<Transaction> {
let tx = self.internal.lock().unwrap().clone().extract_tx(); let tx = self.internal.lock().unwrap().clone().extract_tx();
Arc::new(Transaction { internal: tx }) let buffer: Vec<u8> = serialize(&tx);
Arc::new(Transaction::new(buffer).unwrap())
} }
/// Combines this PartiallySignedTransaction with other PSBT as described by BIP 174. /// Combines this PartiallySignedTransaction with other PSBT as described by BIP 174.

View File

@ -131,7 +131,7 @@ impl Wallet {
let unspents = self.get_wallet().list_unspent()?; let unspents = self.get_wallet().list_unspent()?;
Ok(unspents Ok(unspents
.iter() .iter()
.map(|u| LocalUtxo::from_utxo(u, self.network())) .map(|u| LocalUtxo::from_utxo(u))
.collect()) .collect())
} }
} }