Status parseUri(ParsedUri &result, const std::string &text) { Uri uri; if (uri.decode(text, false)) { // Turn Airbitz URI's into bitcoin URI's: if ("airbitz" == uri.scheme()) { uri.deauthorize(); auto path = uri.path(); if (0 != path.find("bitcoin/", 0)) return ABC_ERROR(ABC_CC_ParseError, "Unknown airbitz URI"); path.erase(0, 8); uri.pathSet(path); uri.schemeSet("bitcoin"); } // Check the scheme: if ("bitcoin" == uri.scheme()) { uri.deauthorize(); if (addressOk(uri.path())) result.address = uri.path(); auto query = uri.queryDecode(); bc::decode_base10(result.amountSatoshi, query["amount"], 8); result.label = query["label"]; result.message = query["message"]; result.category = query["category"]; result.ret = query["ret"]; result.paymentProto = query["r"]; } else if ("hbits" == uri.scheme()) { uri.deauthorize(); bc::ec_secret secret; ABC_CHECK(hbitsDecode(secret, uri.path())); result.wif = bc::secret_to_wif(secret, true); } else if ("bitid" == uri.scheme()) { result.bitidUri = text; } else { return ABC_ERROR(ABC_CC_ParseError, "Unknown URI scheme"); } } else if (addressOk(text)) { // This is a raw bitcoin address: result.address = text; } else if (bc::null_hash != bc::wif_to_secret(text)) { // This is a raw WIF private key: result.wif = text; } else if (minikeyOk(text)) { // This is a raw Casascius minikey: result.wif = bc::secret_to_wif(bc::minikey_to_secret(text), false); } else if (hbitsOk(text)) { // This is a raw hbits key: bc::ec_secret secret; ABC_CHECK(hbitsDecode(secret, text)); result.wif = bc::secret_to_wif(secret, true); } else { return ABC_ERROR(ABC_CC_ParseError, "Malformed bitcoin URI"); } // Private keys also have addresses: if (result.wif.size()) { const auto compressed = bc::is_wif_compressed(result.wif); const auto secret = bc::wif_to_secret(result.wif); const auto pubkey = bc::secret_to_public_key(secret, compressed); bc::payment_address address; address.set(pubkeyVersion(), bc::bitcoin_short_hash(pubkey)); result.address = address.encoded(); } return Status(); }