| 789 | |
| 790 | template<typename T_tx_ref, typename T_merkle_block> |
| 791 | static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef, T_merkle_block& merkleBlock) |
| 792 | { |
| 793 | std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); |
| 794 | if (!wallet) return NullUniValue; |
| 795 | CWallet* const pwallet = wallet.get(); |
| 796 | |
| 797 | LOCK(pwallet->cs_wallet); |
| 798 | |
| 799 | std::vector<unsigned char> txData = ParseHex(request.params[0].get_str()); |
| 800 | std::vector<unsigned char> txOutProofData = ParseHex(request.params[1].get_str()); |
| 801 | |
| 802 | std::set<CScript> claim_scripts; |
| 803 | if (request.params.size() > 2) { |
| 804 | const std::string claim_script = request.params[2].get_str(); |
| 805 | if (!IsHex(claim_script)) { |
| 806 | throw JSONRPCError(RPC_INVALID_PARAMETER, "Given claim_script is not hex."); |
| 807 | } |
| 808 | // If given manually, no need for it to be a witness script |
| 809 | std::vector<unsigned char> witnessBytes(ParseHex(claim_script)); |
| 810 | CScript witness_script(witnessBytes.begin(), witnessBytes.end()); |
| 811 | claim_scripts.insert(std::move(witness_script)); |
| 812 | } |
| 813 | else { |
| 814 | // Look for known wpkh address in wallet |
| 815 | for (std::map<CTxDestination, CAddressBookData>::const_iterator iter = pwallet->m_address_book.begin(); iter != pwallet->m_address_book.end(); ++iter) { |
| 816 | CScript dest_script = GetScriptForDestination(iter->first); |
| 817 | claim_scripts.insert(std::move(dest_script)); |
| 818 | } |
| 819 | } |
| 820 | |
| 821 | // Make the tx |
| 822 | CMutableTransaction mtx; |
| 823 | |
| 824 | // Construct pegin input |
| 825 | CreatePegInInput(mtx, 0, txBTCRef, merkleBlock, claim_scripts, txData, txOutProofData, wallet->chain().getTip()); |
| 826 | |
| 827 | // Manually construct peg-in transaction, sign it, and send it off. |
| 828 | // Decrement the output value as much as needed given the total vsize to |
| 829 | // pay the fees. |
| 830 | |
| 831 | if (!pwallet->IsLocked()) |
| 832 | pwallet->TopUpKeyPool(); |
| 833 | |
| 834 | // Generate a new key that is added to wallet |
| 835 | CTxDestination wpkhash; |
| 836 | bilingual_str error; |
| 837 | if (!pwallet->GetNewDestination(OutputType::BECH32, "", wpkhash, error)) { |
| 838 | throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, error.original); |
| 839 | } |
| 840 | |
| 841 | // Get value for output |
| 842 | CAmount value = 0; |
| 843 | if (!GetAmountFromParentChainPegin(value, *txBTCRef, mtx.vin[0].prevout.n)) { |
| 844 | throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Amounts to pegin must be explicit and asset must be %s", Params().GetConsensus().parent_pegged_asset.GetHex())); |
| 845 | } |
| 846 | |
| 847 | // one wallet output and one fee output |
| 848 | mtx.vout.push_back(CTxOut(Params().GetConsensus().pegged_asset, value, GetScriptForDestination(wpkhash))); |
no test coverage detected