diff --git a/drongo b/drongo index 9d15c27b..c8226ea9 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit 9d15c27bfd8bd6c51f03fe081d6e70718ecf2eb0 +Subproject commit c8226ea947d910186d3a2e37ba9c5e85c2ec09ef diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java index 0ceb16a1..4a895564 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppController.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java @@ -108,6 +108,9 @@ public class AppController implements Initializable { addTransactionTab("p2wsh", "0100000000010193a2db37b841b2a46f4e9bb63fe9c1012da3ab7fe30b9f9c974242778b5af8980000000000ffffffff01806fb307000000001976a914bbef244bcad13cffb68b5cef3017c7423675552288ac040047304402203cdcaf02a44e37e409646e8a506724e9e1394b890cb52429ea65bac4cc2403f1022024b934297bcd0c21f22cee0e48751c8b184cc3a0d704cae2684e14858550af7d01483045022100feb4e1530c13e72226dc912dcd257df90d81ae22dbddb5a3c2f6d86f81d47c8e022069889ddb76388fa7948aaa018b2480ac36132009bb9cfade82b651e88b4b137a01695221026ccfb8061f235cc110697c0bfb3afb99d82c886672f6b9b5393b25a434c0cbf32103befa190c0c22e2f53720b1be9476dcf11917da4665c44c9c71c3a2d28a933c352102be46dc245f58085743b1cc37c82f0d63a960efa43b5336534275fc469b49f4ac53ae00000000", null); addTransactionTab("test1", "02000000000102ba4dc5a4a14bfaa941b7d115b379b5e15f960635cf694c178b9116763cbd63b11600000017160014fc164cbcac023f5eacfcead2d17d8768c41949affeffffff074d44d2856beb68ba52e8832da60a1682768c2421c2d9a8109ef4e66babd1fd1e000000171600148c3098be6b430859115f5ee99c84c368afecd0481500400002305310000000000017a914ffaf369c2212b178c7a2c21c9ccdd5d126e74c4187327f0300000000001976a914a7cda2e06b102a143ab606937a01d152e300cd3e88ac02473044022006da0ca227f765179219e08a33026b94e7cacff77f87b8cd8eb1b46d6dda11d6022064faa7912924fd23406b6ed3328f1bbbc3760dc51109a49c1b38bf57029d304f012103c6a2fcd030270427d4abe1041c8af929a9e2dbab07b243673453847ab842ee1f024730440220786316a16095105a0af28dccac5cf80f449dea2ea810a9559a89ecb989c2cb3d02205cbd9913d1217ffec144ae4f2bd895f16d778c2ec49ae9c929fdc8bcc2a2b1db0121024d4985241609d072a59be6418d700e87688f6c4d99a51ad68e66078211f076ee38820900", null); addTransactionTab("3of3-1signed.psbt", null, "70736274ff0100550200000001294c4871c059bb76be81e94b78059ee2e0c9b1b47f38edb6b4e75916062394930000000000feffffff01f82a0000000000001976a914e65b294f890792f2c2725d488567018d660f0cf488ac701c09004f0102aa7ed3044b1635bb800000021bf4bfc48934b7966b39bdebb689525d9b8bfed5c8b16e8c58f9afe4641d6d5f03800b5dbec0355c9f0b5e8227bc903e9d0ff1fe6ced0dcfb6d416541c7412c4331406b57041300000800000008000000080020000804f0102aa7ed3042cd31dee80000002d544b2364010378f8c6cec85f6b7ed83a8203dcdbedb97e2625f431f897b837e0363428de8fcfbfe373c0d9e1e0cc8163d886764bafe71c5822eaa232981356589145f63394f300000800000008000000080020000804f0102aa7ed3049ec7d9f580000002793e04aff18b4e40ebc48bcdc6232c54c69cf7265a38fbd85b35705e34d2d42f03368e79aa2b2b7f736d156905a7a45891df07baa2d0b7f127a537908cb82deed514130a48af300000800000008000000080020000800001012b983a000000000000220020f64748dad1cbad107761aaed5c59f25aba006498d260b440e0a091691350c9aa010569532102f26969eb8d1da34d17d33ff99e2f020cc33b3d11d9798ec14f46b82bc455d3262103171d9b824205cd5db6e9353676a292ca954b24d8310a36fc983469ba3fb507a221037f3794f3be4c4acc086ac84d6902c025713eabf8890f20f44acf0b34e3c0f0f753ae220602f26969eb8d1da34d17d33ff99e2f020cc33b3d11d9798ec14f46b82bc455d3261c130a48af300000800000008000000080020000800000000000000000220603171d9b824205cd5db6e9353676a292ca954b24d8310a36fc983469ba3fb507a21c5f63394f300000800000008000000080020000800000000000000000220203171d9b824205cd5db6e9353676a292ca954b24d8310a36fc983469ba3fb507a24830450221008d27cc4b03bc543726e73b69e7980e7364d6f33f979a5cd9b92fb3d050666bd002204fc81fc9c67baf7c3b77041ed316714a9c117a5bdbb020e8c771ea3bdc342434012206037f3794f3be4c4acc086ac84d6902c025713eabf8890f20f44acf0b34e3c0f0f71c06b570413000008000000080000000800200008000000000000000000000"); + addTransactionTab("bip174-signer.psbt", null, "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f618765000000220202dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8872202023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d2010103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000"); + addTransactionTab("bip174-combiner.psbt", null, "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000002202029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01220202dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887220203089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f012202023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d2010103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000"); + addTransactionTab("bip174-finalizer.psbt", null, "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000"); } private void addTransactionTab(String name, String transactionHex, String psbtHex) { @@ -120,7 +123,7 @@ public class AppController implements Initializable { PSBT psbt = PSBT.fromString(psbtHex); addTransactionTab(name, null, psbt); } catch(Exception e) { - //ignore + System.out.println("Could not load PSBT: " + e.getMessage()); } } } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java index 64db9a10..528f4e29 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java @@ -1,5 +1,8 @@ package com.sparrowwallet.sparrow.transaction; +import com.sparrowwallet.drongo.KeyDerivation; +import com.sparrowwallet.drongo.address.Address; +import com.sparrowwallet.drongo.crypto.ECKey; import com.sparrowwallet.drongo.protocol.*; import com.sparrowwallet.drongo.psbt.PSBTInput; import com.sparrowwallet.sparrow.EventManager; @@ -34,6 +37,15 @@ public class InputController extends TransactionFormController implements Initia @FXML private Button outpointSelect; + @FXML + private TextField spends; + + @FXML + private Label from; + + @FXML + private TextField address; + @FXML private CodeArea scriptSigArea; @@ -103,22 +115,62 @@ public class InputController extends TransactionFormController implements Initia TransactionInput txInput = inputForm.getTransactionInput(); PSBTInput psbtInput = inputForm.getPsbtInput(); - inputFieldset.setText("Input #" + txInput.getIndex()); - outpoint.setText(txInput.getOutpoint().getHash().toString() + ":" + txInput.getOutpoint().getIndex()); - - //TODO: Enable select outpoint when wallet present - outpointSelect.setDisable(true); + initializeInputFields(txInput, psbtInput); initializeScriptFields(txInput, psbtInput); initializeStatusFields(txInput); initializeLocktimeFields(txInput); } + private void initializeInputFields(TransactionInput txInput, PSBTInput psbtInput) { + inputFieldset.setText("Input #" + txInput.getIndex()); + outpoint.setText(txInput.getOutpoint().getHash().toString() + ":" + txInput.getOutpoint().getIndex()); + + spends.setText("Unknown"); + from.setVisible(false); + if(psbtInput != null) { + TransactionOutput output = null; + if(psbtInput.getNonWitnessUtxo() != null) { + output = psbtInput.getNonWitnessUtxo().getOutputs().get(txInput.getIndex()); + } else if(psbtInput.getWitnessUtxo() != null) { + output = psbtInput.getWitnessUtxo(); + } + + if(output != null) { + spends.setText(output.getValue() + " sats"); + try { + Address[] addresses = output.getScript().getToAddresses(); + from.setVisible(true); + if(addresses.length == 1) { + address.setText(addresses[0].getAddress()); + } else { + address.setText("multiple addresses"); + } + } catch(NonStandardScriptException e) { + //ignore + } + } + } + + //TODO: Enable select outpoint when wallet present + outpointSelect.setDisable(true); + } + private void initializeScriptFields(TransactionInput txInput, PSBTInput psbtInput) { //TODO: Is this safe? Script redeemScript = txInput.getScriptSig().getFirstNestedScript(); + if(redeemScript == null && psbtInput != null && psbtInput.getRedeemScript() != null) { + redeemScript = psbtInput.getRedeemScript(); + } + if(redeemScript == null && psbtInput != null && psbtInput.getFinalScriptSig() != null) { + redeemScript = psbtInput.getFinalScriptSig().getFirstNestedScript(); + } scriptSigArea.clear(); - appendScript(scriptSigArea, txInput.getScriptSig(), redeemScript, null); + if(txInput.getScriptSig().isEmpty() && psbtInput != null && psbtInput.getFinalScriptSig() != null) { + appendScript(scriptSigArea, psbtInput.getFinalScriptSig(), redeemScript, null); + } else { + appendScript(scriptSigArea, txInput.getScriptSig(), redeemScript, null); + } redeemScriptArea.clear(); if(redeemScript != null) { @@ -129,18 +181,40 @@ public class InputController extends TransactionFormController implements Initia witnessesArea.clear(); witnessScriptArea.clear(); + Script witnesses = null; + Script witnessScript = null; + if(txInput.hasWitness()) { List witnessChunks = txInput.getWitness().asScriptChunks(); if(witnessChunks.get(witnessChunks.size() - 1).isScript()) { - Script witnessScript = new Script(witnessChunks.get(witnessChunks.size() - 1).getData()); - appendScript(witnessesArea, new Script(witnessChunks.subList(0, witnessChunks.size() - 1)), null, witnessScript); - appendScript(witnessScriptArea, witnessScript); + witnesses = new Script(witnessChunks.subList(0, witnessChunks.size() - 1)); + witnessScript = witnessChunks.get(witnessChunks.size() - 1).getScript(); } else { - appendScript(witnessesArea, new Script(witnessChunks)); - witnessScriptScroll.setDisable(true); + witnesses = new Script(witnessChunks); } + } else if(psbtInput != null) { + if(psbtInput.getFinalScriptWitness() != null) { + List witnessChunks = psbtInput.getFinalScriptWitness().asScriptChunks(); + if(witnessChunks.get(witnessChunks.size() - 1).isScript()) { + witnesses = new Script(witnessChunks.subList(0, witnessChunks.size() - 1)); + witnessScript = witnessChunks.get(witnessChunks.size() - 1).getScript(); + } else { + witnesses = new Script(witnessChunks); + } + } else if(psbtInput.getWitnessScript() != null) { + witnessScript = psbtInput.getWitnessScript(); + } + } + + if(witnesses != null) { + appendScript(witnessesArea, witnesses, null, witnessScript); } else { witnessesScroll.setDisable(true); + } + + if(witnessScript != null) { + appendScript(witnessScriptArea, witnessScript); + } else { witnessScriptScroll.setDisable(true); } } @@ -152,13 +226,23 @@ public class InputController extends TransactionFormController implements Initia if(inputForm.getPsbtInput() != null) { PSBTInput psbtInput = inputForm.getPsbtInput(); - try { - int reqSigs = psbtInput.getSigningScript().getNumRequiredSignatures(); - int foundSigs = psbtInput.getPartialSignatures().size(); - signatures.setText(foundSigs + "/" + reqSigs); - } catch (NonStandardScriptException e) { - //TODO: Handle unusual transaction sig + int reqSigs = -1; + if((psbtInput.getNonWitnessUtxo() != null || psbtInput.getWitnessUtxo() != null) && psbtInput.getSigningScript() != null) { + try { + reqSigs = psbtInput.getSigningScript().getNumRequiredSignatures(); + } catch (NonStandardScriptException e) { + //TODO: Handle unusual transaction sig + } } + + int foundSigs = psbtInput.getPartialSignatures().size(); + if(psbtInput.getFinalScriptWitness() != null) { + foundSigs = psbtInput.getFinalScriptWitness().getSignatures().size(); + } else if(psbtInput.getFinalScriptSig() != null) { + foundSigs = psbtInput.getFinalScriptSig().getSignatures().size(); + } + + signatures.setText(foundSigs + "/" + (reqSigs < 0 ? "?" : reqSigs)); } rbf.setSelected(txInput.isReplaceByFeeEnabled()); @@ -280,4 +364,28 @@ public class InputController extends TransactionFormController implements Initia this.inputForm = form; initializeView(); } + + @Override + protected String describeScriptChunk(ScriptChunk chunk) { + String chunkString = super.describeScriptChunk(chunk); + + ECKey pubKey = null; + if(chunk.isSignature()) { + if(inputForm.getPsbtInput() != null) { + TransactionSignature signature = chunk.getSignature(); + pubKey = inputForm.getPsbtInput().getKeyForSignature(signature); + } + } else if(chunk.isPubKey()) { + pubKey = chunk.getPubKey(); + } + + if(inputForm.getPsbtInput() != null) { + KeyDerivation derivation = inputForm.getPsbtInput().getKeyDerivation(pubKey); + if(derivation != null) { + return "[" + derivation.toString() + "] " + chunkString; + } + } + + return chunkString; + } } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/InputsController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/InputsController.java index 03d37ea4..50561340 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/InputsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/InputsController.java @@ -47,6 +47,7 @@ public class InputsController extends TransactionFormController implements Initi if(inputsForm.getPsbt() != null) { int reqSigs = 0; int foundSigs = 0; + boolean showDenominator = true; List outputs = new ArrayList<>(); for(int i = 0; i < tx.getInputs().size(); i++) { @@ -59,11 +60,23 @@ public class InputsController extends TransactionFormController implements Initi outputs.add(psbtInput.getWitnessUtxo()); } - try { - reqSigs += psbtInput.getSigningScript().getNumRequiredSignatures(); + if((psbtInput.getNonWitnessUtxo() != null || psbtInput.getWitnessUtxo() != null) && psbtInput.getSigningScript() != null) { + try { + reqSigs += psbtInput.getSigningScript().getNumRequiredSignatures(); + } catch (NonStandardScriptException e) { + showDenominator = false; + //TODO: Handle unusual transaction sig + } + } else { + showDenominator = false; + } + + if(psbtInput.getFinalScriptWitness() != null) { + foundSigs += psbtInput.getFinalScriptWitness().getSignatures().size(); + } else if(psbtInput.getFinalScriptSig() != null) { + foundSigs += psbtInput.getFinalScriptSig().getSignatures().size(); + } else { foundSigs += psbtInput.getPartialSignatures().size(); - } catch (NonStandardScriptException e) { - //TODO: Handle unusual transaction sig } } @@ -72,7 +85,12 @@ public class InputsController extends TransactionFormController implements Initi totalAmt += output.getValue(); } total.setText(totalAmt + " sats"); - signatures.setText(foundSigs + "/" + reqSigs); + if(showDenominator) { + signatures.setText(foundSigs + "/" + reqSigs); + } else { + signatures.setText(foundSigs + "/?"); + } + addPieData(inputsPie, outputs); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/OutputController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/OutputController.java index 2945c0fa..4768c9ae 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/OutputController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/OutputController.java @@ -1,8 +1,11 @@ package com.sparrowwallet.sparrow.transaction; +import com.sparrowwallet.drongo.address.Address; +import com.sparrowwallet.drongo.protocol.NonStandardScriptException; import com.sparrowwallet.drongo.protocol.TransactionOutput; import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.control.Label; import javafx.scene.control.TextField; import org.fxmisc.richtext.CodeArea; import tornadofx.control.Fieldset; @@ -19,6 +22,12 @@ public class OutputController extends TransactionFormController implements Initi @FXML private TextField value; + @FXML + private Label to; + + @FXML + private TextField address; + @FXML private CodeArea scriptPubKeyArea; @@ -31,8 +40,21 @@ public class OutputController extends TransactionFormController implements Initi TransactionOutput txOutput = outputForm.getTransactionOutput(); outputFieldset.setText("Output #" + txOutput.getIndex()); + value.setText(txOutput.getValue() + " sats"); + try { + Address[] addresses = txOutput.getScript().getToAddresses(); + to.setVisible(true); + if(addresses.length == 1) { + address.setText(addresses[0].getAddress()); + } else { + address.setText("multiple addresses"); + } + } catch(NonStandardScriptException e) { + //ignore + } + scriptPubKeyArea.clear(); appendScript(scriptPubKeyArea, txOutput.getScript(), null, null); } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionController.java index d0bdb74c..4582fc43 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionController.java @@ -182,13 +182,15 @@ public class TransactionController implements Initializable, TransactionListener if(transaction.hasWitnesses()) { for (int i = 0; i < transaction.getInputs().size(); i++) { TransactionInput input = transaction.getInputs().get(i); - TransactionWitness witness = input.getWitness(); - VarInt witnessCount = new VarInt(witness.getPushCount()); - cursor = addText(hex, cursor, witnessCount.getSizeInBytes()*2, "witness-" + getIndexedStyleClass(i, selectedInputIndex, "count")); - for(byte[] push : witness.getPushes()) { - VarInt witnessLen = new VarInt(push.length); - cursor = addText(hex, cursor, witnessLen.getSizeInBytes()*2, "witness-" + getIndexedStyleClass(i, selectedInputIndex, "length")); - cursor = addText(hex, cursor, (int)witnessLen.value*2, "witness-" + getIndexedStyleClass(i, selectedInputIndex, "data")); + if(input.hasWitness()) { + TransactionWitness witness = input.getWitness(); + VarInt witnessCount = new VarInt(witness.getPushCount()); + cursor = addText(hex, cursor, witnessCount.getSizeInBytes()*2, "witness-" + getIndexedStyleClass(i, selectedInputIndex, "count")); + for(byte[] push : witness.getPushes()) { + VarInt witnessLen = new VarInt(push.length); + cursor = addText(hex, cursor, witnessLen.getSizeInBytes()*2, "witness-" + getIndexedStyleClass(i, selectedInputIndex, "length")); + cursor = addText(hex, cursor, (int)witnessLen.value*2, "witness-" + getIndexedStyleClass(i, selectedInputIndex, "data")); + } } } } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionFormController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionFormController.java index f5e1f03a..cf086cd7 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionFormController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionFormController.java @@ -91,7 +91,7 @@ public abstract class TransactionFormController { } else if(chunk.isSignature()) { codeArea.append("", "script-signature"); } else if(chunk.isScript()) { - Script nestedScript = new Script(chunk.getData()); + Script nestedScript = chunk.getScript(); if (nestedScript.equals(redeemScript)) { codeArea.append("", "script-redeem"); } else if (nestedScript.equals(witnessScript)) { @@ -132,7 +132,7 @@ public abstract class TransactionFormController { ScriptChunk hoverChunk = script.getChunks().get(position.getMajor()/2); if(!hoverChunk.isOpCode()) { Point2D pos = e.getScreenPosition(); - popupMsg.setText(hoverChunk.toString()); + popupMsg.setText(describeScriptChunk(hoverChunk)); popup.show(area, pos.getX(), pos.getY() + 10); } } @@ -141,4 +141,8 @@ public abstract class TransactionFormController { popup.hide(); }); } + + protected String describeScriptChunk(ScriptChunk chunk) { + return chunk.toString(); + } } diff --git a/src/main/resources/com/sparrowwallet/sparrow/app.fxml b/src/main/resources/com/sparrowwallet/sparrow/app.fxml index 368e4819..6a34319f 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/app.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/app.fxml @@ -3,7 +3,7 @@ - + diff --git a/src/main/resources/com/sparrowwallet/sparrow/general.css b/src/main/resources/com/sparrowwallet/sparrow/general.css index 9ab7d98a..21a74841 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/general.css +++ b/src/main/resources/com/sparrowwallet/sparrow/general.css @@ -10,6 +10,10 @@ -fx-pref-height: 25px; } +.form .input-container { + -fx-spacing: 2; +} + .form .field { -fx-padding: 5 5; } diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml b/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml index e5ea11a8..d2556d08 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml @@ -18,10 +18,10 @@ - - diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/input.fxml b/src/main/resources/com/sparrowwallet/sparrow/transaction/input.fxml index 59dfc8ff..d329f62b 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/input.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/input.fxml @@ -18,9 +18,9 @@ - + - + @@ -37,6 +37,11 @@ + + + @@ -48,7 +53,7 @@ - + @@ -57,7 +62,7 @@ - + @@ -66,7 +71,7 @@ - + @@ -75,7 +80,7 @@ - + diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/inputs.fxml b/src/main/resources/com/sparrowwallet/sparrow/transaction/inputs.fxml index 3fda9e94..a7ab81b1 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/inputs.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/inputs.fxml @@ -11,9 +11,9 @@ - + - + diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/output.fxml b/src/main/resources/com/sparrowwallet/sparrow/transaction/output.fxml index 51d0e31a..eb5c1fa8 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/output.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/output.fxml @@ -17,9 +17,9 @@ - + - + @@ -28,8 +28,10 @@
- - + + +
@@ -42,7 +44,7 @@ - + diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/outputs.fxml b/src/main/resources/com/sparrowwallet/sparrow/transaction/outputs.fxml index 9d61ad34..e7b44807 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/outputs.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/outputs.fxml @@ -11,9 +11,9 @@ - + - + diff --git a/src/main/resources/sparrow-nodrop.png b/src/main/resources/sparrow-nodrop.png new file mode 100644 index 00000000..e3d7c012 Binary files /dev/null and b/src/main/resources/sparrow-nodrop.png differ diff --git a/src/main/resources/sparrow-small.png b/src/main/resources/sparrow-small.png index 0309f3f9..0b6bd66d 100644 Binary files a/src/main/resources/sparrow-small.png and b/src/main/resources/sparrow-small.png differ diff --git a/src/main/resources/sparrow.icns b/src/main/resources/sparrow.icns index 43c0dc9c..a518323f 100644 Binary files a/src/main/resources/sparrow.icns and b/src/main/resources/sparrow.icns differ diff --git a/src/main/resources/sparrow.png b/src/main/resources/sparrow.png index e3d7c012..091dfd29 100644 Binary files a/src/main/resources/sparrow.png and b/src/main/resources/sparrow.png differ