wallet: export raw tx hex and tx keys from signTxs()
What changed, and why it matters
This commit changes how a Monero wallet library requests data when signing transactions via RPC. It now explicitly asks the remote wallet to also return the raw transaction hex data and the transaction keys, matching behavior already present in the JNI wallet implementation. There is no direct evidence in the commit that this introduces a security vulnerability; it appears to be a parity/feature completeness change.
No security action required based on the supplied commit. Reviewers may want to confirm that exposing raw transaction hex and transaction keys through the RPC interface is consistent with the library's threat model and documentation, but this is a design/parity consideration rather than a clear vulnerability.
Security signals we found
No strong security signals were identified.
Evidence from the diff
In MoneroWalletRpc.signTxs(), two boolean parameters are added to the sign_transfer RPC call: export_raw=true and get_tx_keys=true. The downstream converter is updated to accept tx_raw_list in addition to tx_blob_list when populating transaction full hex. Tests are updated to assert that tx keys and full hex are populated. The change aligns RPC behavior with the JNI wallet path.
Changed components
src/main/java/monero/wallet/MoneroWalletRpc.javasrc/test/java/TestMoneroWalletCommon.javaInspect captured patch +5 / −1
diff --git a/src/main/java/monero/wallet/MoneroWalletRpc.java b/src/main/java/monero/wallet/MoneroWalletRpc.java
index f767c08..4d3dcb0 100644
--- a/src/main/java/monero/wallet/MoneroWalletRpc.java
+++ b/src/main/java/monero/wallet/MoneroWalletRpc.java
@@ -1415,6 +1415,8 @@ public class MoneroWalletRpc extends MoneroWalletDefault {
public MoneroTxSet signTxs(String unsignedTxHex) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("unsigned_txset", unsignedTxHex);
+ params.put("export_raw", true);
+ params.put("get_tx_keys", true);
Map<String, Object> resp = rpc.sendJsonRequest("sign_transfer", params);
Map<String, Object> result = (Map<String, Object>) resp.get("result");
return convertRpcSentTxsToTxSet(result, null, null);
@@ -2885,7 +2887,7 @@ public class MoneroWalletRpc extends MoneroWalletDefault {
} else if (key.equals("tx_key_list")) {
List<String> keys = (List<String>) val;
for (int i = 0; i < keys.size(); i++) txs.get(i).setKey(keys.get(i));
- } else if (key.equals("tx_blob_list")) {
+ } else if (key.equals("tx_blob_list") || key.equals("tx_raw_list")) {
List<String> blobs = (List<String>) val;
for (int i = 0; i < blobs.size(); i++) txs.get(i).setFullHex(blobs.get(i));
} else if (key.equals("tx_metadata_list")) {
diff --git a/src/test/java/TestMoneroWalletCommon.java b/src/test/java/TestMoneroWalletCommon.java
index 4adc8e5..1533adf 100644
--- a/src/test/java/TestMoneroWalletCommon.java
+++ b/src/test/java/TestMoneroWalletCommon.java
@@ -2564,6 +2564,8 @@ public abstract class TestMoneroWalletCommon {
assertFalse(signedTxSet.getSignedTxHex().isEmpty());
assertEquals(1, signedTxSet.getTxs().size());
assertFalse(signedTxSet.getTxs().get(0).getHash().isEmpty());
+ assertFalse(signedTxSet.getTxs().get(0).getKey().isEmpty());
+ assertFalse(signedTxSet.getTxs().get(0).getFullHex().isEmpty());
// parse or "describe" unsigned tx set
MoneroTxSet describedTxSet = offlineWallet.describeUnsignedTxSet(unsignedTx.getTxSet().getUnsignedTxHex());
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.