Status AddressJson::unpack(Address &result) { Address out; // Main json: ABC_CHECK(indexOk()); out.index = index(); ABC_CHECK(addressOk()); out.address = address(); // State json: AddressStateJson stateJson = state(); out.recyclable = stateJson.recyclable(); out.time = stateJson.time(); // Details json: AutoFree<tABC_TxDetails, ABC_TxDetailsFree> pDetails; ABC_CHECK_OLD(ABC_TxDetailsDecode(get(), &pDetails.get(), &error)); out.metadata = TxMetadata(pDetails); result = std::move(out); return Status(); }
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(); }