| 1128 | } |
| 1129 | |
| 1130 | RPCHelpMan blindrawtransaction() |
| 1131 | { |
| 1132 | return RPCHelpMan{"blindrawtransaction", |
| 1133 | "\nConvert one or more outputs of a raw transaction into confidential ones using only wallet inputs.\n" |
| 1134 | "Returns the hex-encoded raw transaction.\n" |
| 1135 | "The output keys used can be specified by using a confidential address in createrawtransaction.\n" |
| 1136 | "This call may add an additional 0-value unspendable output in order to balance the blinders.\n", |
| 1137 | { |
| 1138 | {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A hex-encoded raw transaction."}, |
| 1139 | {"ignoreblindfail", RPCArg::Type::BOOL , RPCArg::Default{true}, "Return a transaction even when a blinding attempt fails due to number of blinded inputs/outputs."}, |
| 1140 | {"asset_commitments", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "An array of input asset generators. If provided, this list must be empty, or match the final input commitment list, including ordering, to make a valid surjection proof. This list does not include generators for issuances, as these assets are inherently unblinded.", |
| 1141 | { |
| 1142 | {"assetcommitment", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A hex-encoded asset commitment, one for each input." |
| 1143 | " Null commitments must be \"\"."}, |
| 1144 | } |
| 1145 | }, |
| 1146 | {"blind_issuances", RPCArg::Type::BOOL , RPCArg::Default{true}, "Blind the issuances found in the raw transaction or not. All issuances will be blinded if true."}, |
| 1147 | {"totalblinder", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Ignored for now."}, |
| 1148 | }, |
| 1149 | RPCResult{ |
| 1150 | RPCResult::Type::STR_HEX, "transaction", "serialized transaction", |
| 1151 | }, |
| 1152 | RPCExamples{""}, |
| 1153 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 1154 | { |
| 1155 | std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); |
| 1156 | if (!wallet) return NullUniValue; |
| 1157 | CWallet* const pwallet = wallet.get(); |
| 1158 | |
| 1159 | std::vector<unsigned char> txData(ParseHexV(request.params[0], "argument 1")); |
| 1160 | CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); |
| 1161 | CMutableTransaction tx; |
| 1162 | try { |
| 1163 | ssData >> tx; |
| 1164 | } catch (const std::exception &) { |
| 1165 | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); |
| 1166 | } |
| 1167 | |
| 1168 | bool ignore_blind_fail = true; |
| 1169 | if (request.params.size() > 1) { |
| 1170 | ignore_blind_fail = request.params[1].get_bool(); |
| 1171 | } |
| 1172 | |
| 1173 | std::vector<std::vector<unsigned char> > auxiliary_generators; |
| 1174 | if (request.params.size() > 2) { |
| 1175 | UniValue assetCommitments = request.params[2].get_array(); |
| 1176 | if (assetCommitments.size() != 0 && assetCommitments.size() < tx.vin.size()) { |
| 1177 | throw JSONRPCError(RPC_INVALID_PARAMETER, "Asset commitment array must have at least as many entries as transaction inputs."); |
| 1178 | } |
| 1179 | for (size_t nIn = 0; nIn < assetCommitments.size(); nIn++) { |
| 1180 | if (assetCommitments[nIn].isStr()) { |
| 1181 | std::string assetcommitment = assetCommitments[nIn].get_str(); |
| 1182 | if (IsHex(assetcommitment) && assetcommitment.size() == 66) { |
| 1183 | auxiliary_generators.push_back(ParseHex(assetcommitment)); |
| 1184 | continue; |
| 1185 | } |
| 1186 | } |
| 1187 | throw JSONRPCError(RPC_INVALID_PARAMETER, "Asset commitments must be a hex encoded string of length 66."); |
nothing calls this directly
no test coverage detected