Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address to optimized QR string #581

Merged
merged 8 commits into from May 6, 2021
33 changes: 30 additions & 3 deletions src/util/address.rs
Expand Up @@ -36,7 +36,7 @@
//! let address = Address::p2pkh(&public_key, Network::Bitcoin);
//! ```

use std::fmt::{self, Display, Formatter};
use std::fmt;
use std::str::FromStr;
use std::error;

Expand Down Expand Up @@ -352,10 +352,23 @@ impl Address {
pub fn script_pubkey(&self) -> script::Script {
self.payload.script_pubkey()
}

/// Creates a string optimized to be encoded in QR codes, meaning it becomes uppercase if bech32.
/// Quoting BIP 173 "inside QR codes uppercase SHOULD be used, as those permit the use of
/// alphanumeric mode, which is 45% more compact than the normal byte mode."
/// Even inside Bitcoin URI may be more efficient to use the uppercase address since in QR codes
/// encoding modes can be mixed as needed within a QR symbol.
pub fn to_qr_string(&self) -> String {
sgeisler marked this conversation as resolved.
Show resolved Hide resolved
let address_string = self.to_string();
match self.payload {
Payload::WitnessProgram { .. } => address_string.to_ascii_uppercase(),
_ => address_string,
}
}
}

impl Display for Address {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
impl fmt::Display for Address {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self.payload {
Payload::PubkeyHash(ref hash) => {
let mut prefixed = [0; 21];
Expand Down Expand Up @@ -743,4 +756,18 @@ mod tests {
hex_script!("001454d26dddb59c7073c6a197946ea1841951fa7a74")
);
}

#[test]
fn test_qr_string() {
for el in ["132F25rTsvBdp9JzLLBHP5mvGY66i1xdiM", "33iFwdLuRpW1uK1RTRqsoi8rR4NpDzk66k"].iter() {
let addr = Address::from_str(el).unwrap();
assert_eq!(addr.to_qr_string(), *el);
}

for el in ["bcrt1q2nfxmhd4n3c8834pj72xagvyr9gl57n5r94fsl", "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej"].iter() {
let addr = Address::from_str(el).unwrap();
assert_eq!(addr.to_qr_string(), el.to_ascii_uppercase());
}
}

}