[wallet] Add AddressValidators
This commit is contained in:
48
examples/address_validator.rs
Normal file
48
examples/address_validator.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use magical_bitcoin_wallet::bitcoin;
|
||||
use magical_bitcoin_wallet::database::MemoryDatabase;
|
||||
use magical_bitcoin_wallet::descriptor::HDKeyPaths;
|
||||
use magical_bitcoin_wallet::types::ScriptType;
|
||||
use magical_bitcoin_wallet::wallet::address_validator::{AddressValidator, AddressValidatorError};
|
||||
use magical_bitcoin_wallet::{OfflineWallet, Wallet};
|
||||
|
||||
use bitcoin::hashes::hex::FromHex;
|
||||
use bitcoin::util::bip32::Fingerprint;
|
||||
use bitcoin::{Network, Script};
|
||||
|
||||
struct DummyValidator;
|
||||
impl AddressValidator for DummyValidator {
|
||||
fn validate(
|
||||
&self,
|
||||
script_type: ScriptType,
|
||||
hd_keypaths: &HDKeyPaths,
|
||||
script: &Script,
|
||||
) -> Result<(), AddressValidatorError> {
|
||||
let (_, path) = hd_keypaths
|
||||
.values()
|
||||
.find(|(fing, _)| fing == &Fingerprint::from_hex("bc123c3e").unwrap())
|
||||
.ok_or(AddressValidatorError::InvalidScript)?;
|
||||
|
||||
println!(
|
||||
"Validating `{:?}` {} address, script: {}",
|
||||
script_type, path, script
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), magical_bitcoin_wallet::error::Error> {
|
||||
let descriptor = "sh(and_v(v:pk(tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd/*),after(630000)))";
|
||||
let mut wallet: OfflineWallet<_> =
|
||||
Wallet::new_offline(descriptor, None, Network::Regtest, MemoryDatabase::new())?;
|
||||
|
||||
wallet.add_address_validator(Arc::new(Box::new(DummyValidator)));
|
||||
|
||||
wallet.get_new_address()?;
|
||||
wallet.get_new_address()?;
|
||||
wallet.get_new_address()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
extern crate base64;
|
||||
extern crate magical_bitcoin_wallet;
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use magical_bitcoin_wallet::bitcoin;
|
||||
use magical_bitcoin_wallet::descriptor::*;
|
||||
use magical_bitcoin_wallet::psbt::*;
|
||||
use magical_bitcoin_wallet::signer::Signer;
|
||||
|
||||
use bitcoin::consensus::encode::{deserialize, serialize};
|
||||
use bitcoin::util::psbt::PartiallySignedTransaction;
|
||||
use bitcoin::SigHashType;
|
||||
|
||||
fn main() {
|
||||
let desc = "pkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/*)";
|
||||
|
||||
let extended_desc = ExtendedDescriptor::from_str(desc).unwrap();
|
||||
|
||||
let psbt_str = "cHNidP8BAFMCAAAAAd9SiQfxXZ+CKjgjRNonWXsnlA84aLvjxtwCmMfRc0ZbAQAAAAD+////ASjS9QUAAAAAF6kUYJR3oB0lS1M0W1RRMMiENSX45IuHAAAAAAABAPUCAAAAA9I7/OqeFeOFdr5VTLnj3UI/CNRw2eWmMPf7qDv6uIF6AAAAABcWABTG+kgr0g44V0sK9/9FN9oG/CxMK/7///+d0ffphPcV6FE9J/3ZPKWu17YxBnWWTJQyRJs3HUo1gwEAAAAA/v///835mYd9DmnjVnUKd2421MDoZmIxvB4XyJluN3SPUV9hAAAAABcWABRfvwFGp+x/yWdXeNgFs9v0duyeS/7///8CFbH+AAAAAAAXqRSEnTOAjJN/X6ZgR9ftKmwisNSZx4cA4fUFAAAAABl2qRTs6pS4x17MSQ4yNs/1GPsfdlv2NIisAAAAACIGApVE9PPtkcqp8Da43yrXGv4nLOotZdyxwJoTWQxuLxIuCAxfmh4JAAAAAAA=";
|
||||
let psbt_buf = base64::decode(psbt_str).unwrap();
|
||||
let mut psbt: PartiallySignedTransaction = deserialize(&psbt_buf).unwrap();
|
||||
|
||||
let signer = PSBTSigner::from_descriptor(&psbt.global.unsigned_tx, &extended_desc).unwrap();
|
||||
|
||||
for (index, input) in psbt.inputs.iter_mut().enumerate() {
|
||||
for (pubkey, (fing, path)) in &input.hd_keypaths {
|
||||
let sighash = input.sighash_type.unwrap_or(SigHashType::All);
|
||||
|
||||
// Ignore the "witness_utxo" case because we know this psbt is a legacy tx
|
||||
if let Some(non_wit_utxo) = &input.non_witness_utxo {
|
||||
let prev_script = &non_wit_utxo.output
|
||||
[psbt.global.unsigned_tx.input[index].previous_output.vout as usize]
|
||||
.script_pubkey;
|
||||
let (signature, sighash) = signer
|
||||
.sig_legacy_from_fingerprint(index, sighash, fing, path, prev_script)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
let mut concat_sig = Vec::new();
|
||||
concat_sig.extend_from_slice(&signature.serialize_der());
|
||||
concat_sig.extend_from_slice(&[sighash as u8]);
|
||||
|
||||
input.partial_sigs.insert(*pubkey, concat_sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("signed: {}", base64::encode(&serialize(&psbt)));
|
||||
}
|
||||
Reference in New Issue
Block a user