diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java index 4c5263d9..87ac1a69 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppController.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java @@ -167,7 +167,12 @@ public class AppController implements Initializable { if(isWalletFile(file)) { openWalletFile(file); } else { - openTransactionFile(file); + NetworkDialog dlg = new NetworkDialog(); + Optional network = dlg.showAndWait(); + if (network.isEmpty()) { + return; + } + openTransactionFile(network.get(), file); } } success = true; @@ -442,6 +447,13 @@ public class AppController implements Initializable { public void openTransactionFromFile(ActionEvent event) { Stage window = new Stage(); + //TODO:TESTNET - it would be nice to integrate this with the file choose dialog + NetworkDialog dlg = new NetworkDialog(); + Optional network = dlg.showAndWait(); + if (network.isEmpty()) { + return; + } + FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Open Transaction"); fileChooser.getExtensionFilters().addAll( @@ -452,11 +464,11 @@ public class AppController implements Initializable { File file = fileChooser.showOpenDialog(window); if (file != null) { - openTransactionFile(file); + openTransactionFile(network.get(), file); } } - private void openTransactionFile(File file) { + private void openTransactionFile(Network network, File file) { for(Tab tab : tabs.getTabs()) { TabData tabData = (TabData)tab.getUserData(); if(file.equals(tabData.getFile())) { @@ -474,7 +486,7 @@ public class AppController implements Initializable { String name = file.getName(); try { - Tab tab = addTransactionTab(name, bytes); + Tab tab = addTransactionTab(network, name, bytes); TabData tabData = (TabData)tab.getUserData(); tabData.setFile(file); tabs.getSelectionModel().select(tab); @@ -488,7 +500,7 @@ public class AppController implements Initializable { }; String text = byteSource.asCharSource(Charsets.UTF_8).read().trim(); - Tab tab = addTransactionTab(name, text); + Tab tab = addTransactionTab(network, name, text); tabs.getSelectionModel().select(tab); } } catch(IOException e) { @@ -504,13 +516,20 @@ public class AppController implements Initializable { } public void openTransactionFromText(ActionEvent event) { + //TODO:TESTNET - it would be nice to have this on the text entry form + NetworkDialog dlg = new NetworkDialog(); + Optional network = dlg.showAndWait(); + if (network.isEmpty()) { + return; + } + TextAreaDialog dialog = new TextAreaDialog(); dialog.setTitle("Open from text"); dialog.getDialogPane().setHeaderText("Paste a transaction or PSBT:"); Optional text = dialog.showAndWait(); if(text.isPresent() && !text.get().isEmpty()) { try { - Tab tab = addTransactionTab(null, text.get().trim()); + Tab tab = addTransactionTab(network.get(), null, text.get().trim()); TabData tabData = (TabData)tab.getUserData(); tabData.setText(text.get()); tabs.getSelectionModel().select(tab); @@ -552,17 +571,21 @@ public class AppController implements Initializable { } public void openTransactionFromQR(ActionEvent event) { - //TODO: is wallet always valid??? - QRScanDialog qrScanDialog = new QRScanDialog(getWalletForCurrentTab().getNetwork()); + NetworkDialog dlg = new NetworkDialog(); + Optional network = dlg.showAndWait(); + if(network.isEmpty()) { + return; + } + QRScanDialog qrScanDialog = new QRScanDialog(network.get()); Optional optionalResult = qrScanDialog.showAndWait(); if(optionalResult.isPresent()) { QRScanDialog.Result result = optionalResult.get(); if(result.transaction != null) { - Tab tab = addTransactionTab(null, result.transaction); + Tab tab = addTransactionTab(network.get(), null, result.transaction); tabs.getSelectionModel().select(tab); } if(result.psbt != null) { - Tab tab = addTransactionTab(null, result.psbt); + Tab tab = addTransactionTab(network.get(), null, result.psbt); tabs.getSelectionModel().select(tab); } if(result.error != null) { @@ -743,16 +766,22 @@ public class AppController implements Initializable { } public void newWallet(ActionEvent event) { - WalletNameDialog dlg = new WalletNameDialog(); - Optional walletName = dlg.showAndWait(); - if(walletName.isPresent()) { - File walletFile = Storage.getWalletFile(walletName.get()); - Storage storage = new Storage(walletFile); - //TODO: get from settings or user input - Wallet wallet = new Wallet(Network.BITCOIN, walletName.get(), PolicyType.SINGLE, ScriptType.P2WPKH); - Tab tab = addWalletTab(storage, wallet); - tabs.getSelectionModel().select(tab); + WalletNameDialog dlgName = new WalletNameDialog(); + Optional walletName = dlgName.showAndWait(); + if(walletName.isEmpty()) { + return; } + //TODO:TESTNET - do we just put in a default value and the user can modify the wallet setting? + NetworkDialog dlgNetwork = new NetworkDialog(); + Optional network = dlgNetwork.showAndWait(); + if (network.isEmpty()) { + return; + } + File walletFile = Storage.getWalletFile(walletName.get()); + Storage storage = new Storage(walletFile); + Wallet wallet = new Wallet(network.get(), walletName.get(), PolicyType.SINGLE, ScriptType.P2WPKH); + Tab tab = addWalletTab(storage, wallet); + tabs.getSelectionModel().select(tab); } public void openWallet(ActionEvent event) { @@ -772,6 +801,7 @@ public class AppController implements Initializable { Storage storage = new Storage(file); FileType fileType = IOUtils.getFileType(file); if(FileType.JSON.equals(fileType)) { + //TODO:TESTNET - what happens loading an old wallet without the 'NETWORK' key Wallet wallet = storage.loadWallet(); restorePublicKeysFromSeed(wallet, null); Tab tab = addWalletTab(storage, wallet); @@ -981,44 +1011,42 @@ public class AppController implements Initializable { public void openExamples(ActionEvent event) { try { - addTransactionTab("p2pkh", "01000000019c2e0f24a03e72002a96acedb12a632e72b6b74c05dc3ceab1fe78237f886c48010000006a47304402203da9d487be5302a6d69e02a861acff1da472885e43d7528ed9b1b537a8e2cac9022002d1bca03a1e9715a99971bafe3b1852b7a4f0168281cbd27a220380a01b3307012102c9950c622494c2e9ff5a003e33b690fe4832477d32c2d256c67eab8bf613b34effffffff02b6f50500000000001976a914bdf63990d6dc33d705b756e13dd135466c06b3b588ac845e0201000000001976a9145fb0e9755a3424efd2ba0587d20b1e98ee29814a88ac06241559"); - addTransactionTab("p2sh", "0100000003a5ee1a0fd80dfbc3142df136ab56e082b799c13aa977c048bdf8f61bd158652c000000006b48304502203b0160de302cded63589a88214fe499a25aa1d86a2ea09129945cd632476a12c022100c77727daf0718307e184d55df620510cf96d4b5814ae3258519c0482c1ca82fa0121024f4102c1f1cf662bf99f2b034eb03edd4e6c96793cb9445ff519aab580649120ffffffff0fce901eb7b7551ba5f414735ff93b83a2a57403df11059ec88245fba2aaf1a0000000006a47304402204089adb8a1de1a9e22aa43b94d54f1e54dc9bea745d57df1a633e03dd9ede3c2022037d1e53e911ed7212186028f2e085f70524930e22eb6184af090ba4ab779a5b90121030644cb394bf381dbec91680bdf1be1986ad93cfb35603697353199fb285a119effffffff0fce901eb7b7551ba5f414735ff93b83a2a57403df11059ec88245fba2aaf1a0010000009300493046022100a07b2821f96658c938fa9c68950af0e69f3b2ce5f8258b3a6ad254d4bc73e11e022100e82fab8df3f7e7a28e91b3609f91e8ebf663af3a4dc2fd2abd954301a5da67e701475121022afc20bf379bc96a2f4e9e63ffceb8652b2b6a097f63fbee6ecec2a49a48010e2103a767c7221e9f15f870f1ad9311f5ab937d79fcaeee15bb2c722bca515581b4c052aeffffffff02a3b81b00000000001976a914ea00917f128f569cbdf79da5efcd9001671ab52c88ac80969800000000001976a9143dec0ead289be1afa8da127a7dbdd425a05e25f688ac00000000"); - addTransactionTab("p2sh-p2wpkh", "01000000000101db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000001716001479091972186c449eb1ded22b78e40d009bdf0089feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac02473044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb012103ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a2687392040000"); - addTransactionTab("p2sh-p2wsh", "01000000000101708256c5896fb3f00ef37601f8e30c5b460dbcd1fca1cd7199f9b56fc4ecd5400000000023220020615ae01ed1bc1ffaad54da31d7805d0bb55b52dfd3941114330368c1bbf69b4cffffffff01603edb0300000000160014bbef244bcad13cffb68b5cef3017c7423675552204004730440220010d2854b86b90b7c33661ca25f9d9f15c24b88c5c4992630f77ff004b998fb802204106fc3ec8481fa98e07b7e78809ac91b6ccaf60bf4d3f729c5a75899bb664a501473044022046d66321c6766abcb1366a793f9bfd0e11e0b080354f18188588961ea76c5ad002207262381a0661d66f5c39825202524c45f29d500c6476176cd910b1691176858701695221026ccfb8061f235cc110697c0bfb3afb99d82c886672f6b9b5393b25a434c0cbf32103befa190c0c22e2f53720b1be9476dcf11917da4665c44c9c71c3a2d28a933c352102be46dc245f58085743b1cc37c82f0d63a960efa43b5336534275fc469b49f4ac53ae00000000"); - addTransactionTab("p2wpkh", "01000000000101109d2e41430bfdec7e6dfb02bf78b5827eeb717ef25210ff3203b0db8c76c9260000000000ffffffff01a032eb0500000000160014bbef244bcad13cffb68b5cef3017c742367555220247304402202f7cac3494e521018ae0be4ca18517639ef7c00658d42a9f938b2b344c8454e2022039a54218832fad5d14b331329d9042c51ee6be287e95e49ee5b96fda1f5ce13f0121026ccfb8061f235cc110697c0bfb3afb99d82c886672f6b9b5393b25a434c0cbf300000000"); - addTransactionTab("p2wsh", "0100000000010193a2db37b841b2a46f4e9bb63fe9c1012da3ab7fe30b9f9c974242778b5af8980000000000ffffffff01806fb307000000001976a914bbef244bcad13cffb68b5cef3017c7423675552288ac040047304402203cdcaf02a44e37e409646e8a506724e9e1394b890cb52429ea65bac4cc2403f1022024b934297bcd0c21f22cee0e48751c8b184cc3a0d704cae2684e14858550af7d01483045022100feb4e1530c13e72226dc912dcd257df90d81ae22dbddb5a3c2f6d86f81d47c8e022069889ddb76388fa7948aaa018b2480ac36132009bb9cfade82b651e88b4b137a01695221026ccfb8061f235cc110697c0bfb3afb99d82c886672f6b9b5393b25a434c0cbf32103befa190c0c22e2f53720b1be9476dcf11917da4665c44c9c71c3a2d28a933c352102be46dc245f58085743b1cc37c82f0d63a960efa43b5336534275fc469b49f4ac53ae00000000"); - //addTransactionTab("test1", "02000000000102ba4dc5a4a14bfaa941b7d115b379b5e15f960635cf694c178b9116763cbd63b11600000017160014fc164cbcac023f5eacfcead2d17d8768c41949affeffffff074d44d2856beb68ba52e8832da60a1682768c2421c2d9a8109ef4e66babd1fd1e000000171600148c3098be6b430859115f5ee99c84c368afecd0481500400002305310000000000017a914ffaf369c2212b178c7a2c21c9ccdd5d126e74c4187327f0300000000001976a914a7cda2e06b102a143ab606937a01d152e300cd3e88ac02473044022006da0ca227f765179219e08a33026b94e7cacff77f87b8cd8eb1b46d6dda11d6022064faa7912924fd23406b6ed3328f1bbbc3760dc51109a49c1b38bf57029d304f012103c6a2fcd030270427d4abe1041c8af929a9e2dbab07b243673453847ab842ee1f024730440220786316a16095105a0af28dccac5cf80f449dea2ea810a9559a89ecb989c2cb3d02205cbd9913d1217ffec144ae4f2bd895f16d778c2ec49ae9c929fdc8bcc2a2b1db0121024d4985241609d072a59be6418d700e87688f6c4d99a51ad68e66078211f076ee38820900"); - //addTransactionTab("3of3-1s.psbt", "70736274ff0100550200000001294c4871c059bb76be81e94b78059ee2e0c9b1b47f38edb6b4e75916062394930000000000feffffff01f82a0000000000001976a914e65b294f890792f2c2725d488567018d660f0cf488ac701c09004f0102aa7ed3044b1635bb800000021bf4bfc48934b7966b39bdebb689525d9b8bfed5c8b16e8c58f9afe4641d6d5f03800b5dbec0355c9f0b5e8227bc903e9d0ff1fe6ced0dcfb6d416541c7412c4331406b57041300000800000008000000080020000804f0102aa7ed3042cd31dee80000002d544b2364010378f8c6cec85f6b7ed83a8203dcdbedb97e2625f431f897b837e0363428de8fcfbfe373c0d9e1e0cc8163d886764bafe71c5822eaa232981356589145f63394f300000800000008000000080020000804f0102aa7ed3049ec7d9f580000002793e04aff18b4e40ebc48bcdc6232c54c69cf7265a38fbd85b35705e34d2d42f03368e79aa2b2b7f736d156905a7a45891df07baa2d0b7f127a537908cb82deed514130a48af300000800000008000000080020000800001012b983a000000000000220020f64748dad1cbad107761aaed5c59f25aba006498d260b440e0a091691350c9aa010569532102f26969eb8d1da34d17d33ff99e2f020cc33b3d11d9798ec14f46b82bc455d3262103171d9b824205cd5db6e9353676a292ca954b24d8310a36fc983469ba3fb507a221037f3794f3be4c4acc086ac84d6902c025713eabf8890f20f44acf0b34e3c0f0f753ae220602f26969eb8d1da34d17d33ff99e2f020cc33b3d11d9798ec14f46b82bc455d3261c130a48af300000800000008000000080020000800000000000000000220603171d9b824205cd5db6e9353676a292ca954b24d8310a36fc983469ba3fb507a21c5f63394f300000800000008000000080020000800000000000000000220203171d9b824205cd5db6e9353676a292ca954b24d8310a36fc983469ba3fb507a24830450221008d27cc4b03bc543726e73b69e7980e7364d6f33f979a5cd9b92fb3d050666bd002204fc81fc9c67baf7c3b77041ed316714a9c117a5bdbb020e8c771ea3bdc342434012206037f3794f3be4c4acc086ac84d6902c025713eabf8890f20f44acf0b34e3c0f0f71c06b570413000008000000080000000800200008000000000000000000000"); - //addTransactionTab("signer.psbt", "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f618765000000220202dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8872202023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d2010103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000"); - //addTransactionTab("combiner.psbt", "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000002202029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01220202dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887220203089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f012202023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d2010103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000"); - addTransactionTab("finalizer.psbt", "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000"); + addTransactionTab(Network.BITCOIN, "p2pkh", "01000000019c2e0f24a03e72002a96acedb12a632e72b6b74c05dc3ceab1fe78237f886c48010000006a47304402203da9d487be5302a6d69e02a861acff1da472885e43d7528ed9b1b537a8e2cac9022002d1bca03a1e9715a99971bafe3b1852b7a4f0168281cbd27a220380a01b3307012102c9950c622494c2e9ff5a003e33b690fe4832477d32c2d256c67eab8bf613b34effffffff02b6f50500000000001976a914bdf63990d6dc33d705b756e13dd135466c06b3b588ac845e0201000000001976a9145fb0e9755a3424efd2ba0587d20b1e98ee29814a88ac06241559"); + addTransactionTab(Network.BITCOIN, "p2sh", "0100000003a5ee1a0fd80dfbc3142df136ab56e082b799c13aa977c048bdf8f61bd158652c000000006b48304502203b0160de302cded63589a88214fe499a25aa1d86a2ea09129945cd632476a12c022100c77727daf0718307e184d55df620510cf96d4b5814ae3258519c0482c1ca82fa0121024f4102c1f1cf662bf99f2b034eb03edd4e6c96793cb9445ff519aab580649120ffffffff0fce901eb7b7551ba5f414735ff93b83a2a57403df11059ec88245fba2aaf1a0000000006a47304402204089adb8a1de1a9e22aa43b94d54f1e54dc9bea745d57df1a633e03dd9ede3c2022037d1e53e911ed7212186028f2e085f70524930e22eb6184af090ba4ab779a5b90121030644cb394bf381dbec91680bdf1be1986ad93cfb35603697353199fb285a119effffffff0fce901eb7b7551ba5f414735ff93b83a2a57403df11059ec88245fba2aaf1a0010000009300493046022100a07b2821f96658c938fa9c68950af0e69f3b2ce5f8258b3a6ad254d4bc73e11e022100e82fab8df3f7e7a28e91b3609f91e8ebf663af3a4dc2fd2abd954301a5da67e701475121022afc20bf379bc96a2f4e9e63ffceb8652b2b6a097f63fbee6ecec2a49a48010e2103a767c7221e9f15f870f1ad9311f5ab937d79fcaeee15bb2c722bca515581b4c052aeffffffff02a3b81b00000000001976a914ea00917f128f569cbdf79da5efcd9001671ab52c88ac80969800000000001976a9143dec0ead289be1afa8da127a7dbdd425a05e25f688ac00000000"); + addTransactionTab(Network.BITCOIN, "p2sh-p2wpkh", "01000000000101db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000001716001479091972186c449eb1ded22b78e40d009bdf0089feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac02473044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb012103ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a2687392040000"); + addTransactionTab(Network.BITCOIN, "p2sh-p2wsh", "01000000000101708256c5896fb3f00ef37601f8e30c5b460dbcd1fca1cd7199f9b56fc4ecd5400000000023220020615ae01ed1bc1ffaad54da31d7805d0bb55b52dfd3941114330368c1bbf69b4cffffffff01603edb0300000000160014bbef244bcad13cffb68b5cef3017c7423675552204004730440220010d2854b86b90b7c33661ca25f9d9f15c24b88c5c4992630f77ff004b998fb802204106fc3ec8481fa98e07b7e78809ac91b6ccaf60bf4d3f729c5a75899bb664a501473044022046d66321c6766abcb1366a793f9bfd0e11e0b080354f18188588961ea76c5ad002207262381a0661d66f5c39825202524c45f29d500c6476176cd910b1691176858701695221026ccfb8061f235cc110697c0bfb3afb99d82c886672f6b9b5393b25a434c0cbf32103befa190c0c22e2f53720b1be9476dcf11917da4665c44c9c71c3a2d28a933c352102be46dc245f58085743b1cc37c82f0d63a960efa43b5336534275fc469b49f4ac53ae00000000"); + addTransactionTab(Network.BITCOIN, "p2wpkh", "01000000000101109d2e41430bfdec7e6dfb02bf78b5827eeb717ef25210ff3203b0db8c76c9260000000000ffffffff01a032eb0500000000160014bbef244bcad13cffb68b5cef3017c742367555220247304402202f7cac3494e521018ae0be4ca18517639ef7c00658d42a9f938b2b344c8454e2022039a54218832fad5d14b331329d9042c51ee6be287e95e49ee5b96fda1f5ce13f0121026ccfb8061f235cc110697c0bfb3afb99d82c886672f6b9b5393b25a434c0cbf300000000"); + addTransactionTab(Network.BITCOIN, "p2wsh", "0100000000010193a2db37b841b2a46f4e9bb63fe9c1012da3ab7fe30b9f9c974242778b5af8980000000000ffffffff01806fb307000000001976a914bbef244bcad13cffb68b5cef3017c7423675552288ac040047304402203cdcaf02a44e37e409646e8a506724e9e1394b890cb52429ea65bac4cc2403f1022024b934297bcd0c21f22cee0e48751c8b184cc3a0d704cae2684e14858550af7d01483045022100feb4e1530c13e72226dc912dcd257df90d81ae22dbddb5a3c2f6d86f81d47c8e022069889ddb76388fa7948aaa018b2480ac36132009bb9cfade82b651e88b4b137a01695221026ccfb8061f235cc110697c0bfb3afb99d82c886672f6b9b5393b25a434c0cbf32103befa190c0c22e2f53720b1be9476dcf11917da4665c44c9c71c3a2d28a933c352102be46dc245f58085743b1cc37c82f0d63a960efa43b5336534275fc469b49f4ac53ae00000000"); + //addTransactionTab(Network.BITCOIN, "test1", "02000000000102ba4dc5a4a14bfaa941b7d115b379b5e15f960635cf694c178b9116763cbd63b11600000017160014fc164cbcac023f5eacfcead2d17d8768c41949affeffffff074d44d2856beb68ba52e8832da60a1682768c2421c2d9a8109ef4e66babd1fd1e000000171600148c3098be6b430859115f5ee99c84c368afecd0481500400002305310000000000017a914ffaf369c2212b178c7a2c21c9ccdd5d126e74c4187327f0300000000001976a914a7cda2e06b102a143ab606937a01d152e300cd3e88ac02473044022006da0ca227f765179219e08a33026b94e7cacff77f87b8cd8eb1b46d6dda11d6022064faa7912924fd23406b6ed3328f1bbbc3760dc51109a49c1b38bf57029d304f012103c6a2fcd030270427d4abe1041c8af929a9e2dbab07b243673453847ab842ee1f024730440220786316a16095105a0af28dccac5cf80f449dea2ea810a9559a89ecb989c2cb3d02205cbd9913d1217ffec144ae4f2bd895f16d778c2ec49ae9c929fdc8bcc2a2b1db0121024d4985241609d072a59be6418d700e87688f6c4d99a51ad68e66078211f076ee38820900"); + //addTransactionTab(Network.BITCOIN, "3of3-1s.psbt", "70736274ff0100550200000001294c4871c059bb76be81e94b78059ee2e0c9b1b47f38edb6b4e75916062394930000000000feffffff01f82a0000000000001976a914e65b294f890792f2c2725d488567018d660f0cf488ac701c09004f0102aa7ed3044b1635bb800000021bf4bfc48934b7966b39bdebb689525d9b8bfed5c8b16e8c58f9afe4641d6d5f03800b5dbec0355c9f0b5e8227bc903e9d0ff1fe6ced0dcfb6d416541c7412c4331406b57041300000800000008000000080020000804f0102aa7ed3042cd31dee80000002d544b2364010378f8c6cec85f6b7ed83a8203dcdbedb97e2625f431f897b837e0363428de8fcfbfe373c0d9e1e0cc8163d886764bafe71c5822eaa232981356589145f63394f300000800000008000000080020000804f0102aa7ed3049ec7d9f580000002793e04aff18b4e40ebc48bcdc6232c54c69cf7265a38fbd85b35705e34d2d42f03368e79aa2b2b7f736d156905a7a45891df07baa2d0b7f127a537908cb82deed514130a48af300000800000008000000080020000800001012b983a000000000000220020f64748dad1cbad107761aaed5c59f25aba006498d260b440e0a091691350c9aa010569532102f26969eb8d1da34d17d33ff99e2f020cc33b3d11d9798ec14f46b82bc455d3262103171d9b824205cd5db6e9353676a292ca954b24d8310a36fc983469ba3fb507a221037f3794f3be4c4acc086ac84d6902c025713eabf8890f20f44acf0b34e3c0f0f753ae220602f26969eb8d1da34d17d33ff99e2f020cc33b3d11d9798ec14f46b82bc455d3261c130a48af300000800000008000000080020000800000000000000000220603171d9b824205cd5db6e9353676a292ca954b24d8310a36fc983469ba3fb507a21c5f63394f300000800000008000000080020000800000000000000000220203171d9b824205cd5db6e9353676a292ca954b24d8310a36fc983469ba3fb507a24830450221008d27cc4b03bc543726e73b69e7980e7364d6f33f979a5cd9b92fb3d050666bd002204fc81fc9c67baf7c3b77041ed316714a9c117a5bdbb020e8c771ea3bdc342434012206037f3794f3be4c4acc086ac84d6902c025713eabf8890f20f44acf0b34e3c0f0f71c06b570413000008000000080000000800200008000000000000000000000"); + //addTransactionTab(Network.BITCOIN, "signer.psbt", "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f618765000000220202dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8872202023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d2010103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000"); + //addTransactionTab(Network.BITCOIN, "combiner.psbt", "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000002202029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01220202dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d7483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01010304010000000104475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae2206029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f10d90c6a4f000000800000008000000080220602dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d710d90c6a4f0000008000000080010000800001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887220203089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f012202023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e73473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d2010103040100000001042200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903010547522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae2206023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7310d90c6a4f000000800000008003000080220603089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc10d90c6a4f00000080000000800200008000220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000"); + addTransactionTab(Network.BITCOIN, "finalizer.psbt", "70736274ff01009a020000000258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd750000000000ffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d0100000000ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f00000000000100bb0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f6187650000000107da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752ae0001012000c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e8870107232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b20289030108da0400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00220203a9a4c37f5996d3aa25dbac6b570af0650394492942460b354753ed9eeca5877110d90c6a4f000000800000008004000080002202027f6399757d2eff55a136ad02c684b1838b6556e5f1b6b34282a94b6b5005109610d90c6a4f00000080000000800500008000"); } catch(Exception e) { log.error("Error opening examples", e); } } - private Tab addTransactionTab(String name, String string) throws ParseException, PSBTParseException, TransactionParseException { + private Tab addTransactionTab(Network network, String name, String string) throws ParseException, PSBTParseException, TransactionParseException { if(Utils.isBase64(string) && !Utils.isHex(string)) { - return addTransactionTab(name, Base64.getDecoder().decode(string)); + return addTransactionTab(network, name, Base64.getDecoder().decode(string)); } else if(Utils.isHex(string)) { - return addTransactionTab(name, Utils.hexToBytes(string)); + return addTransactionTab(network, name, Utils.hexToBytes(string)); } throw new ParseException("Input is not base64 or hex", 0); } - private Tab addTransactionTab(String name, byte[] bytes) throws PSBTParseException, ParseException, TransactionParseException { + private Tab addTransactionTab(Network network, String name, byte[] bytes) throws PSBTParseException, ParseException, TransactionParseException { if(PSBT.isPSBT(bytes)) { - //TODO: test this is called from a wallet tab - Wallet wallet = getWalletForCurrentTab(); - PSBT psbt = new PSBT(wallet.getNetwork(), bytes); - return addTransactionTab(name, psbt); + PSBT psbt = new PSBT(network, bytes); + return addTransactionTab(network, name, psbt); } if(Transaction.isTransaction(bytes)) { try { Transaction transaction = new Transaction(bytes); - return addTransactionTab(name, transaction); + return addTransactionTab(network, name, transaction); } catch(Exception e) { throw new TransactionParseException(e.getMessage()); } @@ -1027,19 +1055,19 @@ public class AppController implements Initializable { throw new ParseException("Not a valid PSBT or transaction", 0); } - private Tab addTransactionTab(String name, Transaction transaction) { - return addTransactionTab(name, transaction, null, null, null, null); + private Tab addTransactionTab(Network network, String name, Transaction transaction) { + return addTransactionTab(network, name, transaction, null, null, null, null); } - private Tab addTransactionTab(String name, PSBT psbt) { - return addTransactionTab(name, psbt.getTransaction(), psbt, null, null, null); + private Tab addTransactionTab(Network network, String name, PSBT psbt) { + return addTransactionTab(network, name, psbt.getTransaction(), psbt, null, null, null); } - private Tab addTransactionTab(BlockTransaction blockTransaction, TransactionView initialView, Integer initialIndex) { - return addTransactionTab(null, blockTransaction.getTransaction(), null, blockTransaction, initialView, initialIndex); + private Tab addTransactionTab(Network network, BlockTransaction blockTransaction, TransactionView initialView, Integer initialIndex) { + return addTransactionTab(network, null, blockTransaction.getTransaction(), null, blockTransaction, initialView, initialIndex); } - private Tab addTransactionTab(String name, Transaction transaction, PSBT psbt, BlockTransaction blockTransaction, TransactionView initialView, Integer initialIndex) { + private Tab addTransactionTab(Network network, String name, Transaction transaction, PSBT psbt, BlockTransaction blockTransaction, TransactionView initialView, Integer initialIndex) { for(Tab tab : tabs.getTabs()) { TabData tabData = (TabData)tab.getUserData(); if(tabData instanceof TransactionTabData) { @@ -1349,13 +1377,19 @@ public class AppController implements Initializable { @Subscribe public void viewTransaction(ViewTransactionEvent event) { - Tab tab = addTransactionTab(event.getBlockTransaction(), event.getInitialView(), event.getInitialIndex()); + //TODO:TESTNET we should be able to infer this from the network queried the txid from + NetworkDialog dlg = new NetworkDialog(); + Optional network = dlg.showAndWait(); + if (network.isEmpty()) { + return; + } + Tab tab = addTransactionTab(network.get(), event.getBlockTransaction(), event.getInitialView(), event.getInitialIndex()); tabs.getSelectionModel().select(tab); } @Subscribe public void viewPSBT(ViewPSBTEvent event) { - Tab tab = addTransactionTab(event.getLabel(), event.getPsbt()); + Tab tab = addTransactionTab(event.getPsbt().getNetwork(), event.getLabel(), event.getPsbt()); tabs.getSelectionModel().select(tab); } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileImportPane.java index d77a15d5..085f3f11 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileImportPane.java @@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.control; import com.google.gson.JsonParseException; import com.sparrowwallet.drongo.crypto.InvalidPasswordException; +import com.sparrowwallet.drongo.protocol.Network; import com.sparrowwallet.sparrow.io.FileImport; import com.sparrowwallet.sparrow.io.ImportException; import javafx.beans.property.SimpleStringProperty; @@ -23,6 +24,7 @@ import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; +import java.util.Optional; public abstract class FileImportPane extends TitledDescriptionPane { private static final Logger log = LoggerFactory.getLogger(FileImportPane.class); @@ -49,6 +51,13 @@ public abstract class FileImportPane extends TitledDescriptionPane { private void importFile() { Stage window = new Stage(); + //TODO:TESTNET - it would be nice to integrate this with the file select dialog + NetworkDialog dlg = new NetworkDialog(); + Optional network = dlg.showAndWait(); + if (network.isEmpty()) { + return; + } + FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Open " + importer.getWalletModel().toDisplayString() + " File"); fileChooser.getExtensionFilters().addAll( @@ -58,22 +67,22 @@ public abstract class FileImportPane extends TitledDescriptionPane { File file = fileChooser.showOpenDialog(window); if(file != null) { - importFile(file, null); + importFile(network.get(), file, null); } } - private void importFile(File file, String password) { + private void importFile(Network network, File file, String password) { if(file.exists()) { try { if(importer.isEncrypted(file) && password == null) { setDescription("Password Required"); showHideLink.setVisible(false); - setContent(getPasswordEntry(file)); + setContent(getPasswordEntry(network, file)); importButton.setDisable(true); setExpanded(true); } else { InputStream inputStream = new BufferedInputStream(new FileInputStream(file)); - importFile(file.getName(), inputStream, password); + importFile(network, file.getName(), inputStream, password); } } catch (Exception e) { log.error("Error importing file", e); @@ -93,9 +102,9 @@ public abstract class FileImportPane extends TitledDescriptionPane { } } - protected abstract void importFile(String fileName, InputStream inputStream, String password) throws ImportException; + protected abstract void importFile(Network network, String fileName, InputStream inputStream, String password) throws ImportException; - private Node getPasswordEntry(File file) { + private Node getPasswordEntry(Network network, File file) { CustomPasswordField passwordField = (CustomPasswordField) TextFields.createClearablePasswordField(); passwordField.setPromptText("Wallet password"); password.bind(passwordField.textProperty()); @@ -105,7 +114,7 @@ public abstract class FileImportPane extends TitledDescriptionPane { importEncryptedButton.setOnAction(event -> { showHideLink.setVisible(true); setExpanded(false); - importFile(file, password.get()); + importFile(network, file, password.get()); }); HBox contentBox = new HBox(); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileKeystoreImportPane.java index 2b55b755..7767c0bb 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileKeystoreImportPane.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.control; +import com.sparrowwallet.drongo.protocol.Network; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.sparrow.EventManager; @@ -19,8 +20,8 @@ public class FileKeystoreImportPane extends FileImportPane { this.importer = importer; } - protected void importFile(String fileName, InputStream inputStream, String password) throws ImportException { - Keystore keystore = importer.getKeystore(wallet.getScriptType(), inputStream, password); + protected void importFile(Network network, String fileName, InputStream inputStream, String password) throws ImportException { + Keystore keystore = importer.getKeystore(network, wallet.getScriptType(), inputStream, password); EventManager.get().post(new KeystoreImportEvent(keystore)); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletImportPane.java index 3c356dcf..fb904ca5 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletImportPane.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.control; +import com.sparrowwallet.drongo.protocol.Network; import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.event.WalletImportEvent; @@ -17,8 +18,8 @@ public class FileWalletImportPane extends FileImportPane { } @Override - protected void importFile(String fileName, InputStream inputStream, String password) throws ImportException { - Wallet wallet = importer.importWallet(inputStream, password); + protected void importFile(Network network, String fileName, InputStream inputStream, String password) throws ImportException { + Wallet wallet = importer.importWallet(network, inputStream, password); if(wallet.getName() == null) { wallet.setName(fileName); } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java index 1a4a6f8a..d70b0e57 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java @@ -28,6 +28,7 @@ import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Optional; public class FileWalletKeystoreImportPane extends FileImportPane { private static final Logger log = LoggerFactory.getLogger(FileWalletKeystoreImportPane.class); @@ -41,7 +42,7 @@ public class FileWalletKeystoreImportPane extends FileImportPane { this.importer = importer; } - protected void importFile(String fileName, InputStream inputStream, String password) throws ImportException { + protected void importFile(Network network, String fileName, InputStream inputStream, String password) throws ImportException { this.fileName = fileName; try { fileBytes = ByteStreams.toByteArray(inputStream); @@ -49,17 +50,16 @@ public class FileWalletKeystoreImportPane extends FileImportPane { throw new ImportException("Could not read file", e); } - setContent(getScriptTypeEntry()); + setContent(getScriptTypeEntry(network)); setExpanded(true); importButton.setDisable(true); } - private void importWallet(ScriptType scriptType) throws ImportException { + private void importWallet(Network network, ScriptType scriptType) throws ImportException { ByteArrayInputStream bais = new ByteArrayInputStream(fileBytes); - Keystore keystore = importer.getKeystore(scriptType, bais, ""); + Keystore keystore = importer.getKeystore(network, scriptType, bais, ""); - //TODO: use user input here - Wallet wallet = new Wallet(Network.BITCOIN); + Wallet wallet = new Wallet(network); wallet.setName(fileName); wallet.setPolicyType(PolicyType.SINGLE); wallet.setScriptType(scriptType); @@ -69,7 +69,7 @@ public class FileWalletKeystoreImportPane extends FileImportPane { EventManager.get().post(new WalletImportEvent(wallet)); } - private Node getScriptTypeEntry() { + private Node getScriptTypeEntry(Network network) { Label label = new Label("Script Type:"); ComboBox scriptTypeComboBox = new ComboBox<>(FXCollections.observableArrayList(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE))); scriptTypeComboBox.setValue(ScriptType.P2WPKH); @@ -82,7 +82,7 @@ public class FileWalletKeystoreImportPane extends FileImportPane { showHideLink.setVisible(true); setExpanded(false); try { - importWallet(scriptTypeComboBox.getValue()); + importWallet(network, scriptTypeComboBox.getValue()); } catch(ImportException e) { log.error("Error importing file", e); String errorMessage = e.getMessage(); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/MessageSignDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/MessageSignDialog.java index 531da7d2..a85a8e2e 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/MessageSignDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/MessageSignDialog.java @@ -191,8 +191,7 @@ public class MessageSignDialog extends Dialog { } private Address getAddress()throws InvalidAddressException { - //TODO: is wallet always valid??? - return Address.fromString(wallet.getNetwork(), address.getText()); + return Address.fromStringAnyNetwork(address.getText()); } private boolean isValidAddress() { @@ -299,8 +298,7 @@ public class MessageSignDialog extends Dialog { throw new IllegalArgumentException("Only single signature P2PKH, P2SH-P2WPKH or P2WPKH addresses can verify messages."); } - //TODO: wallet is not always valid!!! - Address signedMessageAddress = scriptType.getAddress(wallet.getNetwork(), signedMessageKey); + Address signedMessageAddress = scriptType.getAddress(providedAddress.getNetwork(), signedMessageKey); return providedAddress.equals(signedMessageAddress); } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/NetworkDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/NetworkDialog.java new file mode 100644 index 00000000..aa8c3a1d --- /dev/null +++ b/src/main/java/com/sparrowwallet/sparrow/control/NetworkDialog.java @@ -0,0 +1,45 @@ +package com.sparrowwallet.sparrow.control; + +import com.sparrowwallet.drongo.protocol.Network; +import com.sparrowwallet.sparrow.AppController; +import com.sparrowwallet.sparrow.glyphfont.FontAwesome5; +import java.util.Arrays; +import javafx.application.Platform; +import javafx.scene.control.*; +import javafx.scene.layout.VBox; +import javafx.scene.control.ComboBox; +import org.controlsfx.glyphfont.Glyph; + +public class NetworkDialog extends Dialog { + private final ComboBox networks; + + public NetworkDialog() { + this.networks = new ComboBox<>(); + networks.getItems().addAll(Arrays.asList(Network.values())); + networks.getSelectionModel().selectFirst(); + final DialogPane dialogPane = getDialogPane(); + AppController.setStageIcon(dialogPane.getScene().getWindow()); + + setTitle("Network"); + dialogPane.setHeaderText("Choose a network:"); + dialogPane.getStylesheets().add(AppController.class.getResource("general.css").toExternalForm()); + dialogPane.getButtonTypes().addAll(ButtonType.CANCEL); + dialogPane.setPrefWidth(380); + dialogPane.setPrefHeight(200); + + Glyph wallet = new Glyph(FontAwesome5.FONT_NAME, FontAwesome5.Glyph.PROJECT_DIAGRAM); + wallet.setFontSize(50); + dialogPane.setGraphic(wallet); + + final VBox content = new VBox(10); + content.getChildren().add(networks); + + dialogPane.setContent(content); + + final ButtonType okButtonType = new javafx.scene.control.ButtonType("Ok", ButtonBar.ButtonData.OK_DONE); + dialogPane.getButtonTypes().addAll(okButtonType); + + Platform.runLater(networks::requestFocus); + setResultConverter(dialogButton -> dialogButton == okButtonType ? networks.getValue() : null); + } +} diff --git a/src/main/java/com/sparrowwallet/sparrow/glyphfont/FontAwesome5.java b/src/main/java/com/sparrowwallet/sparrow/glyphfont/FontAwesome5.java index 64deb7f9..e68e1a1d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/glyphfont/FontAwesome5.java +++ b/src/main/java/com/sparrowwallet/sparrow/glyphfont/FontAwesome5.java @@ -34,6 +34,7 @@ public class FontAwesome5 extends GlyphFont { LOCK('\uf023'), LOCK_OPEN('\uf3c1'), PEN_FANCY('\uf5ac'), + PROJECT_DIAGRAM('\uf542'), QRCODE('\uf029'), QUESTION_CIRCLE('\uf059'), REPLY_ALL('\uf122'), diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java index 9fcbaf5e..76be67a0 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardMultisig.java @@ -33,7 +33,7 @@ public class ColdcardMultisig implements WalletImport, KeystoreFileImport, Walle } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(Network network, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { InputStreamReader reader = new InputStreamReader(inputStream); ColdcardKeystore cck = Storage.getGson().fromJson(reader, ColdcardKeystore.class); @@ -78,9 +78,8 @@ public class ColdcardMultisig implements WalletImport, KeystoreFileImport, Walle } @Override - public Wallet importWallet(InputStream inputStream, String password) throws ImportException { - //TODO: get from settings or user input - Wallet wallet = new Wallet(Network.BITCOIN); + public Wallet importWallet(Network network, InputStream inputStream, String password) throws ImportException { + Wallet wallet = new Wallet(network); wallet.setPolicyType(PolicyType.MULTI); int threshold = 2; diff --git a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardSinglesig.java b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardSinglesig.java index f016b066..ef4540ae 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/ColdcardSinglesig.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/ColdcardSinglesig.java @@ -5,6 +5,7 @@ import com.google.gson.JsonElement; import com.google.gson.reflect.TypeToken; import com.sparrowwallet.drongo.ExtendedKey; import com.sparrowwallet.drongo.KeyDerivation; +import com.sparrowwallet.drongo.protocol.Network; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.KeystoreSource; @@ -38,7 +39,7 @@ public class ColdcardSinglesig implements KeystoreFileImport { } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + public Keystore getKeystore(Network network, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { try { Gson gson = new Gson(); Type stringStringMap = new TypeToken>() { diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Config.java b/src/main/java/com/sparrowwallet/sparrow/io/Config.java index 9f256281..d44db84b 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Config.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Config.java @@ -2,7 +2,6 @@ package com.sparrowwallet.sparrow.io; import com.google.gson.*; import com.sparrowwallet.drongo.BitcoinUnit; -import com.sparrowwallet.drongo.protocol.Network; import com.sparrowwallet.sparrow.Mode; import com.sparrowwallet.sparrow.Theme; import org.slf4j.Logger; @@ -18,7 +17,6 @@ public class Config { public static final String CONFIG_FILENAME = "config"; - private Network network = Network.BITCOIN; private Mode mode; private BitcoinUnit bitcoinUnit; private Currency fiatCurrency; @@ -76,10 +74,6 @@ public class Config { return INSTANCE; } - - public Network getNetwork() { - return network; - } public Mode getMode() { return mode; diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java b/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java index 13cf0ae8..ac43dfeb 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java @@ -37,8 +37,8 @@ public class Electrum implements KeystoreFileImport, WalletImport, WalletExport } @Override - public Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException { - Wallet wallet = importWallet(inputStream, password); + public Keystore getKeystore(Network network, ScriptType scriptType, InputStream inputStream, String password) throws ImportException { + Wallet wallet = importWallet(network, inputStream, password); if(!wallet.getPolicyType().equals(PolicyType.SINGLE) || wallet.getKeystores().size() != 1) { throw new ImportException("Multisig wallet detected - import it using File > Import Wallet"); @@ -53,7 +53,7 @@ public class Electrum implements KeystoreFileImport, WalletImport, WalletExport } @Override - public Wallet importWallet(InputStream inputStream, String password) throws ImportException { + public Wallet importWallet(Network network, InputStream inputStream, String password) throws ImportException { Reader reader; if(password != null) { ECKey decryptionKey = Pbkdf2KeyDeriver.DEFAULT_INSTANCE.deriveECKey(password); @@ -118,8 +118,7 @@ public class Electrum implements KeystoreFileImport, WalletImport, WalletExport } } - //TODO: get from settings or user input - Wallet wallet = new Wallet(Network.BITCOIN); + Wallet wallet = new Wallet(network); ScriptType scriptType = null; for(ElectrumKeystore ek : ew.keystores.values()) { diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Hwi.java b/src/main/java/com/sparrowwallet/sparrow/io/Hwi.java index e28d2c24..aa8fe857 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Hwi.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Hwi.java @@ -70,7 +70,7 @@ public class Hwi { } public String getXpub(Device device, String passphrase, String derivationPath) throws ImportException { - //TODO: use --testnet if using testnet + //TODO:TESTNET use --testnet if using testnet try { String output; @@ -93,7 +93,7 @@ public class Hwi { } public String displayAddress(Device device, String passphrase, ScriptType scriptType, String derivationPath) throws DisplayAddressException { - //TODO: use --testnet if using testnet + //TODO:TESTNET use --testnet if using testnet try { if(!List.of(ScriptType.P2PKH, ScriptType.P2SH_P2WPKH, ScriptType.P2WPKH).contains(scriptType)) { throw new IllegalArgumentException("Cannot display address for script type " + scriptType + ": Only single sig types supported"); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreFileImport.java b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreFileImport.java index 6d7db71e..3a5ca810 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/KeystoreFileImport.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/KeystoreFileImport.java @@ -1,11 +1,11 @@ package com.sparrowwallet.sparrow.io; import com.sparrowwallet.drongo.protocol.ScriptType; +import com.sparrowwallet.drongo.protocol.Network; import com.sparrowwallet.drongo.wallet.Keystore; -import java.io.File; import java.io.InputStream; public interface KeystoreFileImport extends KeystoreImport, FileImport { - Keystore getKeystore(ScriptType scriptType, InputStream inputStream, String password) throws ImportException; + Keystore getKeystore(Network network, ScriptType scriptType, InputStream inputStream, String password) throws ImportException; } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Specter.java b/src/main/java/com/sparrowwallet/sparrow/io/Specter.java index 19306d2a..c02877d4 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Specter.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Specter.java @@ -48,14 +48,13 @@ public class Specter implements WalletImport, WalletExport { } @Override - public Wallet importWallet(InputStream inputStream, String password) throws ImportException { + public Wallet importWallet(Network network, InputStream inputStream, String password) throws ImportException { try { Gson gson = new Gson(); SpecterWallet specterWallet = gson.fromJson(new InputStreamReader(inputStream), SpecterWallet.class); if(specterWallet.descriptor != null) { - //TODO: get from settings or user input - OutputDescriptor outputDescriptor = OutputDescriptor.getOutputDescriptor(Network.BITCOIN, specterWallet.descriptor); + OutputDescriptor outputDescriptor = OutputDescriptor.getOutputDescriptor(network, specterWallet.descriptor); Wallet wallet = outputDescriptor.toWallet(); wallet.setName(specterWallet.label); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/WalletImport.java b/src/main/java/com/sparrowwallet/sparrow/io/WalletImport.java index bb516927..84976d39 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/WalletImport.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/WalletImport.java @@ -1,11 +1,11 @@ package com.sparrowwallet.sparrow.io; +import com.sparrowwallet.drongo.protocol.Network; import com.sparrowwallet.drongo.wallet.Wallet; -import java.io.File; import java.io.InputStream; public interface WalletImport extends Import, FileImport { String getWalletImportDescription(); - Wallet importWallet(InputStream inputStream, String password) throws ImportException; + Wallet importWallet(Network network, InputStream inputStream, String password) throws ImportException; } diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/settings.fxml b/src/main/resources/com/sparrowwallet/sparrow/wallet/settings.fxml index ff2724ef..0e92b0e5 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/settings.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/settings.fxml @@ -31,7 +31,7 @@
- +