forked from cygnet3/rust-silentpayments
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate_transaction.rs
72 lines (59 loc) · 3.76 KB
/
create_transaction.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use bdk::descriptor::{ExtendedDescriptor, XOnlyPublicKey};
use bdk::key::XPriv;
use bdk::util::bech32::ToWords;
use bdk::util::address::Address;
use bdk::util::bitcoin::Address as BtcAddress;
use bdk::wallet::{FeeRate, Wallet, SyncOptions};
use bdk::database::MemoryDatabase;
use bdk::blockchain::ElectrumBlockchain;
use bitcoin::consensus::encode;
use bitcoin::util::bip32::{Mnemonic, XPrv};
// Import the necessary modules and types from the BDK library
const scan_priv_key: &[u8] = &[0x01, 0x02, 0x03, 0x04, 0x05]; // Replace with your actual scan private key
const spend_priv_key: &[u8] = &[0x06, 0x07, 0x08, 0x09, 0x0a]; // Replace with your actual spend private key
const silent_payment_address: &str = "spqrstzabeokxcndfglmjpvqonmlpqjvwxy5t"; // Replace with the actual silent payment address
const FEE_RATE: u64 = 1000; // Set the desired fee rate for the transaction (e.g., 1 sat/vB)
fn main() {
// Create a new XPriv instance using the scan and spend private keys
let scan_privkey = XPriv::from_slice(scan_priv_key).unwrap();
let spend_privkey = XPriv::from_slice(spend_priv_key).unwrap();
// Define the desired DerivationPath for the wallet (e.g., `m/352h/1h/0h/1h/0`)
let scan_path = ExtendedDescriptor::from_str("m/352h/1h/0h/1h/0").unwrap();
let spend_path = ExtendedDescriptor::from_str("m/352h/1h/0h/0h/0").unwrap();
// Derive the public keys for both scan and spend paths
let scan_pubkey = scan_privkey.derive(&scan_path).unwrap().public_key;
let spend_pubkey = spend_privkey.derive(&spend_path).unwrap().public_key;
// Create a new XOnlyPublicKey instance for the silent payment address
let xonly_pubkey = XOnlyPublicKey::from_slice(scan_pubkey.as_bytes().concat(spend_pubkey.as_bytes())).unwrap();
// Define the necessary inputs and outputs for constructing the transaction
let input = TransactionInput {
previous_output: PreviousOutput {
txid: [0x01, 0x02, 0x03, 0x04, 0x05], // Replace with the actual transaction ID of an unspent output
vout: 0, // Set the desired output index for the input
},
script_sig: vec![0x01], // Set the necessary script signature for the input
witness: vec![0x02], // Set the necessary witness data for the input
};
let output = TransactionOutput {
value: 50000, // Set the desired output value (e.g., 50,000 satoshis)
script_pubkey: Address::p2tr(&xonly_pubkey, Network::Testnet).script_pubkey(), // Use the derived public key for the output
};
// Create a new Wallet instance using an in-memory database and define the desired sync options
let db = MemoryDatabase::new();
let blockchain = ElectrumBlockchain::new(Network::Testnet);
let sync_options = SyncOptions {
checkpoints: true, // Enable or disable the use of checkpoints when synchronizing with the blockchain
};
let wallet = Wallet::new(&db, scan_privkey.to_xpub(), &blockchain, sync_options).unwrap();
// Create a new TransactionBuilder instance and set the necessary options for constructing the transaction
let mut tx_builder = wallet.build_tx().unwrap();
tx_builder.set_fee_rate(FeeRate::from_sat_per_ubyte(FEE_RATE)); // Set the desired fee rate for the transaction
tx_builder.add_input(input); // Add the input to the transaction builder
tx_builder.add_output(output); // Add the output to the transaction builder
// Sign and finalize the constructed transaction using the derived public key
let mut tx = Transaction::default();
tx_builder.sign(&mut tx, &spend_privkey).unwrap(); // Sign the transaction with the spend private key
// Serialize the signed transaction into a byte array and print it to the console
let serialized_tx = encode::serialize_transactions(&[&tx]).unwrap();
println!("{}", serialized_tx);
}