Skip to content

Commit 26370c6

Browse files
committed
rpc: Include MuSig2 fields in decodepsbt
1 parent ff3d460 commit 26370c6

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

src/rpc/rawtransaction.cpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,37 @@ const RPCResult decodepsbt_inputs{
916916
}},
917917
{RPCResult::Type::STR_HEX, "taproot_internal_key", /*optional=*/ true, "The hex-encoded Taproot x-only internal key"},
918918
{RPCResult::Type::STR_HEX, "taproot_merkle_root", /*optional=*/ true, "The hex-encoded Taproot merkle root"},
919+
{RPCResult::Type::ARR, "musig2_participant_pubkeys", /*optional=*/true, "",
920+
{
921+
{RPCResult::Type::OBJ, "", "",
922+
{
923+
{RPCResult::Type::STR_HEX, "aggregate_pubkey", "The compressed aggregate public key for which the participants create."},
924+
{RPCResult::Type::ARR, "participant_pubkeys", "",
925+
{
926+
{RPCResult::Type::STR_HEX, "pubkey", "The compressed public keys that are aggregated for aggregate_pubkey."},
927+
}},
928+
}},
929+
}},
930+
{RPCResult::Type::ARR, "musig2_pubnonces", /*optional=*/true, "",
931+
{
932+
{RPCResult::Type::OBJ, "", "",
933+
{
934+
{RPCResult::Type::STR_HEX, "participant_pubkey", "The compressed public key of the participant that created this pubnonce."},
935+
{RPCResult::Type::STR_HEX, "aggregate_pubkey", "The compressed aggregate public key for which this pubnonce is for."},
936+
{RPCResult::Type::STR_HEX, "leaf_hash", /*optional=*/true, "The hash of the leaf script that contains the aggregate pubkey being signed for. Omitted when signing for the internal key."},
937+
{RPCResult::Type::STR_HEX, "pubnonce", "The public nonce itself."},
938+
}},
939+
}},
940+
{RPCResult::Type::ARR, "musig2_partial_sigs", /*optional=*/true, "",
941+
{
942+
{RPCResult::Type::OBJ, "", "",
943+
{
944+
{RPCResult::Type::STR_HEX, "participant_pubkey", "The compressed public key of the participant that created this partial signature."},
945+
{RPCResult::Type::STR_HEX, "aggregate_pubkey", "The compressed aggregate public key for which this partial signature is for."},
946+
{RPCResult::Type::STR_HEX, "leaf_hash", /*optional=*/true, "The hash of the leaf script that contains the aggregate pubkey being signed for. Omitted when signing for the internal key."},
947+
{RPCResult::Type::STR_HEX, "partial_sig", "The partial signature itself."},
948+
}},
949+
}},
919950
{RPCResult::Type::OBJ_DYN, "unknown", /*optional=*/ true, "The unknown input fields",
920951
{
921952
{RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
@@ -983,6 +1014,17 @@ const RPCResult decodepsbt_outputs{
9831014
}},
9841015
}},
9851016
}},
1017+
{RPCResult::Type::ARR, "musig2_participant_pubkeys", /*optional=*/true, "",
1018+
{
1019+
{RPCResult::Type::OBJ, "", "",
1020+
{
1021+
{RPCResult::Type::STR_HEX, "aggregate_pubkey", "The compressed aggregate public key for which the participants create."},
1022+
{RPCResult::Type::ARR, "participant_pubkeys", "",
1023+
{
1024+
{RPCResult::Type::STR_HEX, "pubkey", "The compressed public keys that are aggregated for aggregate_pubkey."},
1025+
}},
1026+
}},
1027+
}},
9861028
{RPCResult::Type::OBJ_DYN, "unknown", /*optional=*/true, "The unknown output fields",
9871029
{
9881030
{RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
@@ -1304,6 +1346,52 @@ static RPCHelpMan decodepsbt()
13041346
in.pushKV("taproot_merkle_root", HexStr(input.m_tap_merkle_root));
13051347
}
13061348

1349+
// Write MuSig2 fields
1350+
if (!input.m_musig2_participants.empty()) {
1351+
UniValue musig_pubkeys(UniValue::VARR);
1352+
for (const auto& [agg, parts] : input.m_musig2_participants) {
1353+
UniValue musig_part(UniValue::VOBJ);
1354+
musig_part.pushKV("aggregate_pubkey", HexStr(agg));
1355+
UniValue part_pubkeys(UniValue::VARR);
1356+
for (const auto& pub : parts) {
1357+
part_pubkeys.push_back(HexStr(pub));
1358+
}
1359+
musig_part.pushKV("participant_pubkeys", part_pubkeys);
1360+
musig_pubkeys.push_back(musig_part);
1361+
}
1362+
in.pushKV("musig2_participant_pubkeys", musig_pubkeys);
1363+
}
1364+
if (!input.m_musig2_pubnonces.empty()) {
1365+
UniValue musig_pubnonces(UniValue::VARR);
1366+
for (const auto& [agg_lh, part_pubnonce] : input.m_musig2_pubnonces) {
1367+
const auto& [agg, lh] = agg_lh;
1368+
for (const auto& [part, pubnonce] : part_pubnonce) {
1369+
UniValue info(UniValue::VOBJ);
1370+
info.pushKV("participant_pubkey", HexStr(part));
1371+
info.pushKV("aggregate_pubkey", HexStr(agg));
1372+
if (!lh.IsNull()) info.pushKV("leaf_hash", HexStr(lh));
1373+
info.pushKV("pubnonce", HexStr(pubnonce));
1374+
musig_pubnonces.push_back(info);
1375+
}
1376+
}
1377+
in.pushKV("musig2_pubnonces", musig_pubnonces);
1378+
}
1379+
if (!input.m_musig2_partial_sigs.empty()) {
1380+
UniValue musig_partial_sigs(UniValue::VARR);
1381+
for (const auto& [agg_lh, part_psig] : input.m_musig2_partial_sigs) {
1382+
const auto& [agg, lh] = agg_lh;
1383+
for (const auto& [part, psig] : part_psig) {
1384+
UniValue info(UniValue::VOBJ);
1385+
info.pushKV("participant_pubkey", HexStr(part));
1386+
info.pushKV("aggregate_pubkey", HexStr(agg));
1387+
if (!lh.IsNull()) info.pushKV("leaf_hash", HexStr(lh));
1388+
info.pushKV("partial_sig", HexStr(psig));
1389+
musig_partial_sigs.push_back(info);
1390+
}
1391+
}
1392+
in.pushKV("musig2_partial_sigs", musig_partial_sigs);
1393+
}
1394+
13071395
// Proprietary
13081396
if (!input.m_proprietary.empty()) {
13091397
UniValue proprietary(UniValue::VARR);
@@ -1399,6 +1487,22 @@ static RPCHelpMan decodepsbt()
13991487
out.pushKV("taproot_bip32_derivs", std::move(keypaths));
14001488
}
14011489

1490+
// Write MuSig2 fields
1491+
if (!output.m_musig2_participants.empty()) {
1492+
UniValue musig_pubkeys(UniValue::VARR);
1493+
for (const auto& [agg, parts] : output.m_musig2_participants) {
1494+
UniValue musig_part(UniValue::VOBJ);
1495+
musig_part.pushKV("aggregate_pubkey", HexStr(agg));
1496+
UniValue part_pubkeys(UniValue::VARR);
1497+
for (const auto& pub : parts) {
1498+
part_pubkeys.push_back(HexStr(pub));
1499+
}
1500+
musig_part.pushKV("participant_pubkeys", part_pubkeys);
1501+
musig_pubkeys.push_back(musig_part);
1502+
}
1503+
out.pushKV("musig2_participant_pubkeys", musig_pubkeys);
1504+
}
1505+
14021506
// Proprietary
14031507
if (!output.m_proprietary.empty()) {
14041508
UniValue proprietary(UniValue::VARR);

0 commit comments

Comments
 (0)