tABC_CC ABC_BridgeSweepKey(Wallet &self, tABC_U08Buf key, bool compressed, tABC_Sweep_Done_Callback fCallback, void *pData, tABC_Error *pError) { tABC_CC cc = ABC_CC_Ok; bc::ec_secret ec_key; bc::ec_point ec_addr; bc::payment_address address; PendingSweep sweep; WatcherInfo *watcherInfo = nullptr; ABC_CHECK_NEW(watcherFind(watcherInfo, self)); // Decode key and address: ABC_CHECK_ASSERT(key.size() == ec_key.size(), ABC_CC_Error, "Bad key size"); std::copy(key.begin(), key.end(), ec_key.data()); ec_addr = bc::secret_to_public_key(ec_key, compressed); address.set(pubkeyVersion(), bc::bitcoin_short_hash(ec_addr)); // Start the sweep: sweep.address = address; sweep.key = abcd::wif_key{ec_key, compressed}; sweep.done = false; sweep.fCallback = fCallback; sweep.pData = pData; watcherInfo->sweeping.push_back(sweep); watcherInfo->watcher.watch_address(address); exit: return cc; }
Status hbitsCreate(std::string &result, std::string &addressOut) { while (true) { libbitcoin::data_chunk cand(21); ABC_CHECK(randomData(cand, cand.size())); std::string minikey = libbitcoin::encode_base58(cand); minikey.insert(0, "a"); if (30 == minikey.size() && 0x00 == bc::sha256_hash(bc::to_data_chunk(minikey + "!"))[0]) { bc::ec_secret secret; hbitsDecode(secret, minikey); bc::ec_point pubkey = bc::secret_to_public_key(secret, true); bc::payment_address address; address.set(pubkeyVersion(), bc::bitcoin_short_hash(pubkey)); result = minikey; addressOut = address.encoded(); 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(); }