pub struct Sender(/* private fields */);Expand description
A struct that a sender of funds uses in combination with a recipient’s PaymentCode in order
to send notifications and calculate payment addresses. This is invariant with regard to
recipient and needs to be constructed only once per account (unique per BIP32 seed + account).
Implementations§
Source§impl Sender
impl Sender
Sourcepub fn from_seed<C: Signing>(
secp: &Secp256k1<C>,
seed: &[u8],
network: Network,
account: u32,
) -> Result<Self, Error>
pub fn from_seed<C: Signing>( secp: &Secp256k1<C>, seed: &[u8], network: Network, account: u32, ) -> Result<Self, Error>
Construct a sender side from a BIP32 seed.
Examples found in repository?
9fn main() -> Result<(), bip351::Error> {
10 let secp = Secp256k1::new();
11
12 let sender = bip351::Sender::from_seed(&secp, &[0xFE], Network::Bitcoin, 0)?;
13
14 let recipient = bip351::PaymentCode::from_str(
15 "pay1qqpsxq4730l4yre4lt3588eyt3f2lwggtfalvtgfns04a8smzkn7yys6xv2gs8",
16 )?;
17
18 // Sender makes sure the recipient supports segwit addresses.
19 let p2wpkh_addr_type = recipient
20 .address_types()
21 .get(&bip351::AddressType::P2wpkh)
22 .unwrap();
23
24 let (notification_txout, sender_recipient_commitment) =
25 sender.notify(&secp, &recipient, 0, p2wpkh_addr_type.clone())?;
26
27 // Here the sender would add `notification_txout` to a transaction and broadcast it.
28 // wallet.broadcast(tx)...
29
30 let payload = notification_txout.script_pubkey.as_bytes();
31 assert_eq!(
32 payload[2..].to_hex(),
33 "505049cb55bb02e3217349724307eed5514b53b1f53f0802672a9913d9bbb76afecc86be23f46401"
34 );
35
36 // At this point the recipient is notified. Sender can now send funds to their secret address at index `0`.
37 let recipient_addr_0 = sender.address(&secp, &sender_recipient_commitment, 0)?;
38 assert_eq!(
39 recipient_addr_0.to_string(),
40 "bc1qw7ld5h9tj2ruwxqvetznjfq9g5jyp0gjhrs30w"
41 );
42
43 // wallet.send(&recipient_addr_0, 100000);
44
45 Ok(())
46}More examples
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}Sourcepub fn from_master_xprv<C: Signing>(
secp: &Secp256k1<C>,
master: ExtendedPrivKey,
account: u32,
) -> Result<Self, Error>
pub fn from_master_xprv<C: Signing>( secp: &Secp256k1<C>, master: ExtendedPrivKey, account: u32, ) -> Result<Self, Error>
Construct a sender side from a master extended private key. Not supplying a master key here produces an error.
Sourcepub fn notify(
&self,
secp: &Secp256k1<All>,
payment_code: &PaymentCode,
recipient_index: u32,
address_type: AddressType,
) -> Result<(TxOut, SenderCommitment), Error>
pub fn notify( &self, secp: &Secp256k1<All>, payment_code: &PaymentCode, recipient_index: u32, address_type: AddressType, ) -> Result<(TxOut, SenderCommitment), Error>
Construct a notification for a payment code. The txout is an OP_RETURN consuming 0 sats.
The returned SenderCommitment is used for subsequent interaction with the payment code.
recipient_index must be unique for each recipient as it uniquely defines the relationship
between a sender and a recipient.
Examples found in repository?
9fn main() -> Result<(), bip351::Error> {
10 let secp = Secp256k1::new();
11
12 let sender = bip351::Sender::from_seed(&secp, &[0xFE], Network::Bitcoin, 0)?;
13
14 let recipient = bip351::PaymentCode::from_str(
15 "pay1qqpsxq4730l4yre4lt3588eyt3f2lwggtfalvtgfns04a8smzkn7yys6xv2gs8",
16 )?;
17
18 // Sender makes sure the recipient supports segwit addresses.
19 let p2wpkh_addr_type = recipient
20 .address_types()
21 .get(&bip351::AddressType::P2wpkh)
22 .unwrap();
23
24 let (notification_txout, sender_recipient_commitment) =
25 sender.notify(&secp, &recipient, 0, p2wpkh_addr_type.clone())?;
26
27 // Here the sender would add `notification_txout` to a transaction and broadcast it.
28 // wallet.broadcast(tx)...
29
30 let payload = notification_txout.script_pubkey.as_bytes();
31 assert_eq!(
32 payload[2..].to_hex(),
33 "505049cb55bb02e3217349724307eed5514b53b1f53f0802672a9913d9bbb76afecc86be23f46401"
34 );
35
36 // At this point the recipient is notified. Sender can now send funds to their secret address at index `0`.
37 let recipient_addr_0 = sender.address(&secp, &sender_recipient_commitment, 0)?;
38 assert_eq!(
39 recipient_addr_0.to_string(),
40 "bc1qw7ld5h9tj2ruwxqvetznjfq9g5jyp0gjhrs30w"
41 );
42
43 // wallet.send(&recipient_addr_0, 100000);
44
45 Ok(())
46}More examples
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}Sourcepub fn address(
&self,
secp: &Secp256k1<All>,
commitment: &SenderCommitment,
addr_index: u64,
) -> Result<Address, Error>
pub fn address( &self, secp: &Secp256k1<All>, commitment: &SenderCommitment, addr_index: u64, ) -> Result<Address, Error>
Generate an address for a recipient that has already been notified.
Examples found in repository?
9fn main() -> Result<(), bip351::Error> {
10 let secp = Secp256k1::new();
11
12 let sender = bip351::Sender::from_seed(&secp, &[0xFE], Network::Bitcoin, 0)?;
13
14 let recipient = bip351::PaymentCode::from_str(
15 "pay1qqpsxq4730l4yre4lt3588eyt3f2lwggtfalvtgfns04a8smzkn7yys6xv2gs8",
16 )?;
17
18 // Sender makes sure the recipient supports segwit addresses.
19 let p2wpkh_addr_type = recipient
20 .address_types()
21 .get(&bip351::AddressType::P2wpkh)
22 .unwrap();
23
24 let (notification_txout, sender_recipient_commitment) =
25 sender.notify(&secp, &recipient, 0, p2wpkh_addr_type.clone())?;
26
27 // Here the sender would add `notification_txout` to a transaction and broadcast it.
28 // wallet.broadcast(tx)...
29
30 let payload = notification_txout.script_pubkey.as_bytes();
31 assert_eq!(
32 payload[2..].to_hex(),
33 "505049cb55bb02e3217349724307eed5514b53b1f53f0802672a9913d9bbb76afecc86be23f46401"
34 );
35
36 // At this point the recipient is notified. Sender can now send funds to their secret address at index `0`.
37 let recipient_addr_0 = sender.address(&secp, &sender_recipient_commitment, 0)?;
38 assert_eq!(
39 recipient_addr_0.to_string(),
40 "bc1qw7ld5h9tj2ruwxqvetznjfq9g5jyp0gjhrs30w"
41 );
42
43 // wallet.send(&recipient_addr_0, 100000);
44
45 Ok(())
46}