notify/
notify.rs

1// This example is a simple interactive tool that accepts a payment code, a seed and generates a
2// BIP351 notification payload that can then be embedded in an OP_RETURN.
3
4use std::str::FromStr;
5
6use bip351::*;
7use bitcoin::hashes::hex::{FromHex, ToHex};
8use bitcoin::Network;
9
10fn main() -> std::io::Result<()> {
11    let secp = bitcoin::secp256k1::Secp256k1::new();
12
13    let payment_code = prompt("Enter the recipient's payment code").unwrap();
14    let payment_code = PaymentCode::from_str(&payment_code).expect("Invalid payment code");
15
16    let sender_seed = prompt("Enter the sender's hex-encoded BIP39 seed").unwrap();
17    let sender_seed: Vec<u8> = FromHex::from_hex(&sender_seed).expect("Not a hex-encoded seed");
18
19    let network = prompt("Enter 0 for mainnet or 1 for testnet").unwrap();
20    let network = match network.as_str() {
21        "0" => Network::Bitcoin,
22        "1" => Network::Testnet,
23        _ => panic!("unknown network"),
24    };
25
26    let recipient_index = prompt("Enter a numerical recipient index").unwrap();
27    let recipient_index: u32 = recipient_index
28        .parse()
29        .expect("Not a valid unsigned integer");
30
31    let sender = Sender::from_seed(&secp, &sender_seed, network, 0).unwrap();
32
33    println!("The recipient supports the following address types:");
34    let accepted_addresses: Vec<_> = payment_code.address_types().iter().collect();
35    for (index, addr_type) in accepted_addresses.iter().enumerate() {
36        println!("({}): {:?}", index, addr_type);
37    }
38
39    let ordinal = prompt("Pick the number next to the address type you want to use").unwrap();
40    let addr_type = accepted_addresses
41        .into_iter()
42        .nth(ordinal.parse().expect("Not a valid integer"))
43        .expect("Index out of range")
44        .clone();
45
46    let (txout, _) = sender
47        .notify(&secp, &payment_code, recipient_index, addr_type)
48        .unwrap();
49    let payload = txout.script_pubkey.as_bytes()[2..].to_hex();
50    println!("The notification OP_RETURN payload is:\n{}", payload);
51
52    Ok(())
53}
54
55/// Prints a message and asks the user to input a line.
56fn prompt(prompt: &str) -> std::io::Result<String> {
57    println!("{}:", prompt);
58    let mut value = String::new();
59    std::io::stdin().read_line(&mut value)?;
60    assert_eq!(Some('\n'), value.pop());
61    Ok(value)
62}