@@ -1400,6 +1400,81 @@ UniValue importblindingkey(const JSONRPCRequest& request)
14001400 return NullUniValue;
14011401}
14021402
1403+ UniValue importissuanceblindingkey (const JSONRPCRequest& request)
1404+ {
1405+ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest (request);
1406+ CWallet* const pwallet = wallet.get ();
1407+
1408+ if (!EnsureWalletIsAvailable (pwallet, request.fHelp )) {
1409+ return NullUniValue;
1410+ }
1411+
1412+ if (request.fHelp || request.params .size () != 3 )
1413+ throw std::runtime_error (
1414+ " importissuanceblindingkey \" txid\" vin \" blindingkey\"\n "
1415+ " \n Imports a private blinding key in hex for an asset issuance."
1416+ " \n Arguments:\n "
1417+
1418+ " 1. \" txid\" (string, required) The transaction id of the issuance\n "
1419+ " 2. \" vin\" (numeric, required) The input number of the issuance in the transaction.\n "
1420+ " 3. \" blindingkey\" (string, required) The blinding key in hex\n "
1421+ " \n Example:\n "
1422+ + HelpExampleCli (" importblindingkey" , " \" my blinded CT address\" <blindinghex>" )
1423+ );
1424+
1425+ LOCK2 (cs_main, pwallet->cs_wallet );
1426+
1427+ if (!request.params [0 ].isStr () || !IsHex (request.params [0 ].get_str ()) || request.params [0 ].get_str ().size () != 64 ) {
1428+ throw JSONRPCError (RPC_TYPE_ERROR, " First argument must be a txid string" );
1429+ }
1430+ std::string txidstr = request.params [0 ].get_str ();
1431+ uint256 txid;
1432+ txid.SetHex (txidstr);
1433+
1434+ uint32_t vindex;
1435+ if (!request.params [1 ].isNum ()) {
1436+ throw JSONRPCError (RPC_TYPE_ERROR, " vin must be an integer" );
1437+ }
1438+ vindex = request.params [1 ].get_int ();
1439+
1440+ if (!request.params [2 ].isStr () || !IsHex (request.params [2 ].get_str ()) || request.params [2 ].get_str ().size () != 64 ) {
1441+ throw JSONRPCError (RPC_TYPE_ERROR, " blinding key must be a hex string of length 64" );
1442+ }
1443+
1444+ std::vector<unsigned char > keydata = ParseHex (request.params [2 ].get_str ());
1445+ if (keydata.size () != 32 ) {
1446+ throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, " Invalid hexadecimal key length" );
1447+ }
1448+ CKey key;
1449+ key.Set (keydata.begin (), keydata.end (), true );
1450+
1451+ // Process as issuance key dump
1452+ for (std::map<uint256, CWalletTx>::const_iterator it = pwallet->mapWallet .begin (); it != pwallet->mapWallet .end (); ++it) {
1453+ const CWalletTx* pcoin = &(*it).second ;
1454+ if (pcoin->GetHash () != txid) {
1455+ continue ;
1456+ }
1457+ if (pcoin->tx ->vin .size () <= vindex) {
1458+ throw JSONRPCError (RPC_WALLET_ERROR, " Transaction is in wallet but vin does not exist" );
1459+ }
1460+ if (pcoin->tx ->vin [vindex].assetIssuance .IsNull ()) {
1461+ throw JSONRPCError (RPC_WALLET_ERROR, " Transaction input has no issuance" );
1462+ }
1463+
1464+ // Import the key in that slot
1465+ uint256 keyval;
1466+ memcpy (keyval.begin (), &keydata[0 ], 32 );
1467+ CScript blindingScript (CScript () << OP_RETURN << std::vector<unsigned char >(pcoin->tx ->vin [vindex].prevout .hash .begin (), pcoin->tx ->vin [vindex].prevout .hash .end ()) << pcoin->tx ->vin [vindex].prevout .n );
1468+ if (!pwallet->AddSpecificBlindingKey (CScriptID (blindingScript), keyval)) {
1469+ throw JSONRPCError (RPC_WALLET_ERROR, " Failed to import blinding key" );
1470+ }
1471+ pwallet->MarkDirty ();
1472+ return NullUniValue;
1473+ }
1474+
1475+ throw JSONRPCError (RPC_WALLET_ERROR, " Transaction is unknown to wallet." );
1476+ }
1477+
14031478UniValue dumpblindingkey (const JSONRPCRequest& request)
14041479{
14051480 std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest (request);
@@ -1443,3 +1518,66 @@ UniValue dumpblindingkey(const JSONRPCRequest& request)
14431518
14441519 throw JSONRPCError (RPC_WALLET_ERROR, " Blinding key for address is unknown" );
14451520}
1521+
1522+ UniValue dumpissuanceblindingkey (const JSONRPCRequest& request)
1523+ {
1524+ std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest (request);
1525+ CWallet* const pwallet = wallet.get ();
1526+
1527+ if (!EnsureWalletIsAvailable (pwallet, request.fHelp )) {
1528+ return NullUniValue;
1529+ }
1530+
1531+ if (request.fHelp || request.params .size () != 2 )
1532+ throw std::runtime_error (
1533+ " dumpissuanceblindingkey \" txid\" vin\n "
1534+ " \n Dumps the private blinding key for an asset issuance in wallet."
1535+ " \n Arguments:\n "
1536+ " 1. \" txid\" (string, required) The transaction id of the issuance\n "
1537+ " 2. \" vin\" (numeric, required) The input number of the issuance in the transaction.\n "
1538+ " \n Result:\n "
1539+ " \" blindingkey\" (string) The blinding key\n "
1540+ " \n Example:\n "
1541+ + HelpExampleCli (" dumpissuanceblindingkey" , " \" <txid>\" , 0" )
1542+ );
1543+
1544+ LOCK2 (cs_main, pwallet->cs_wallet );
1545+
1546+ if (!request.params [0 ].isStr () || !IsHex (request.params [0 ].get_str ()) || request.params [0 ].get_str ().size () != 64 ) {
1547+ throw JSONRPCError (RPC_TYPE_ERROR, " First argument must be a txid string" );
1548+ }
1549+ std::string txidstr = request.params [0 ].get_str ();
1550+ uint256 txid;
1551+ txid.SetHex (txidstr);
1552+
1553+ uint32_t vindex;
1554+ if (!request.params [1 ].isNum ()) {
1555+ throw JSONRPCError (RPC_TYPE_ERROR, " vin must be an integer" );
1556+ }
1557+ vindex = request.params [1 ].get_int ();
1558+
1559+ // Process as issuance key dump
1560+ for (std::map<uint256, CWalletTx>::const_iterator it = pwallet->mapWallet .begin (); it != pwallet->mapWallet .end (); ++it) {
1561+ const CWalletTx* pcoin = &(*it).second ;
1562+ if (pcoin->tx ->GetHash () != txid) {
1563+ continue ;
1564+ }
1565+ if (pcoin->tx ->vin .size () <= vindex) {
1566+ throw JSONRPCError (RPC_WALLET_ERROR, " Transaction is in wallet but vin does not exist" );
1567+ }
1568+ if (pcoin->tx ->vin [vindex].assetIssuance .IsNull ()) {
1569+ throw JSONRPCError (RPC_WALLET_ERROR, " Transaction input has no issuance" );
1570+ }
1571+ // We can actually deblind the input
1572+ if (pcoin->GetIssuanceAmount (vindex, false ) != -1 ) {
1573+ CScript blindingScript (CScript () << OP_RETURN << std::vector<unsigned char >(pcoin->tx ->vin [vindex].prevout .hash .begin (), pcoin->tx ->vin [vindex].prevout .hash .end ()) << pcoin->tx ->vin [vindex].prevout .n );
1574+ CKey key;
1575+ key = pwallet->GetBlindingKey (&blindingScript);
1576+ return HexStr (key.begin (), key.end ());
1577+ } else {
1578+ // We don't know how to deblind this using our wallet
1579+ throw JSONRPCError (RPC_WALLET_ERROR, " Unable to unblind issuance with wallet blinding key." );
1580+ }
1581+ }
1582+ throw JSONRPCError (RPC_WALLET_ERROR, " Transaction is unknown to wallet." );
1583+ }
0 commit comments