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();
}
Example #2
0
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();
}