diff --git a/test/services/coins/bitcoincash/bitcoincash_history_sample_data.dart b/test/services/coins/bitcoincash/bitcoincash_history_sample_data.dart new file mode 100644 index 000000000..e69de29bb diff --git a/test/services/coins/bitcoincash/bitcoincash_transaction_data_samples.dart b/test/services/coins/bitcoincash/bitcoincash_transaction_data_samples.dart new file mode 100644 index 000000000..148818b37 --- /dev/null +++ b/test/services/coins/bitcoincash/bitcoincash_transaction_data_samples.dart @@ -0,0 +1,375 @@ +import 'package:stackwallet/models/paymint/transactions_model.dart'; + +final transactionData = TransactionData.fromMap({ + "61fedb3cb994917d2852191785ab59cb0d177d55d860bf10fd671f6a0a83247c": tx1, + "9765cc2efa42ffdfb5ec86e6ae043de4cf2158a00ed19a182c4244bc548334ba": tx2, + "070b45d901243b5856a0cccce8c5f5f548c19aaa00cb0059b37a6a9a3632288a": tx3, + "84aecde036ebe013aa3bd2fcb4741db504c7c040d34f7c33732c967646991855": tx4, +}); + +final tx1 = Transaction( + txid: "61fedb3cb994917d2852191785ab59cb0d177d55d860bf10fd671f6a0a83247c", + confirmedStatus: true, + confirmations: 187, + txType: "Received", + amount: 7000000, + fees: 742, + height: 756720, + address: "12QZH44735UHWAXFgb4hfdq756GjzXtZG7", + timestamp: 1662544771, + worthNow: "0.00", + worthAtBlockTimestamp: "0.00", + inputSize: 1, + outputSize: 2, + inputs: [ + Input( + txid: "f716d010786225004b41e35dd5eebfb11a4e5ea116e1a48235e5d3a591650732", + vout: 0, + ), + ], + outputs: [ + Output( + scriptpubkeyAddress: "12QZH44735UHWAXFgb4hfdq756GjzXtZG7", + value: 7000000, + ), + Output( + scriptpubkeyAddress: "3E1n17NnhVmWTGNbvH6ffKVNFjYT4Jke7G", + value: 71445709, + ) + ], +); + +final tx2 = Transaction( + txid: "9765cc2efa42ffdfb5ec86e6ae043de4cf2158a00ed19a182c4244bc548334ba", + confirmedStatus: true, + confirmations: 175, + txType: "Sent", + amount: 3000000, + fees: 227000, + height: 756732, + address: "1DPrEZBKKVG1Pf4HXeuCkw2Xk65EunR7CM", + timestamp: 1662553616, + worthNow: "0.00", + worthAtBlockTimestamp: "0.0", + inputSize: 1, + outputSize: 2, + inputs: [ + Input( + txid: "61fedb3cb994917d2852191785ab59cb0d177d55d860bf10fd671f6a0a83247c", + vout: 0, + ), + ], + outputs: [ + Output( + scriptpubkeyAddress: "1DPrEZBKKVG1Pf4HXeuCkw2Xk65EunR7CM", + value: 3000000, + ), + Output( + scriptpubkeyAddress: "16GbR1Xau2hKFTr1STgB39NbP8CEkGZjYG", + value: 3773000, + ), + ], +); + +final tx3 = Transaction( + txid: "070b45d901243b5856a0cccce8c5f5f548c19aaa00cb0059b37a6a9a3632288a", + confirmedStatus: true, + confirmations: 177, + txType: "Received", + amount: 2000000, + fees: 227, + height: 756738, + address: "1DPrEZBKKVG1Pf4HXeuCkw2Xk65EunR7CM", + timestamp: 1662555788, + worthNow: "0.00", + worthAtBlockTimestamp: "0.0", + inputSize: 1, + outputSize: 2, + inputs: [ + Input( + txid: "9765cc2efa42ffdfb5ec86e6ae043de4cf2158a00ed19a182c4244bc548334ba", + vout: 0, + ), + ], + outputs: [ + Output( + scriptpubkeyAddress: "1DPrEZBKKVG1Pf4HXeuCkw2Xk65EunR7CM", + value: 2000000, + ), + Output( + scriptpubkeyAddress: "16GbR1Xau2hKFTr1STgB39NbP8CEkGZjYG", + value: 1772773, + ), + ], +); + +final tx4 = Transaction( + txid: "84aecde036ebe013aa3bd2fcb4741db504c7c040d34f7c33732c967646991855", + confirmedStatus: false, + confirmations: 0, + txType: "Received", + amount: 4000000, + fees: 400, + height: 757303, + address: "1PQaBto5KmiW3R2YeexYYoDWksMpEvhYZE", + timestamp: 1662893734, + worthNow: "0.00", + worthAtBlockTimestamp: "0.00", + inputSize: 1, + outputSize: 2, + inputs: [ + Input( + txid: "070b45d901243b5856a0cccce8c5f5f548c19aaa00cb0059b37a6a9a3632288a", + vout: 0, + ), + Input( + txid: "9765cc2efa42ffdfb5ec86e6ae043de4cf2158a00ed19a182c4244bc548334ba", + vout: 0, + ), + ], + outputs: [ + Output( + scriptpubkeyAddress: "1JHcZyhgctuDCznjkxR51pQzKEJUujuc2j", + value: 999600, + ), + Output( + scriptpubkeyAddress: "1PQaBto5KmiW3R2YeexYYoDWksMpEvhYZE", + value: 4000000, + ) + ], +); + +final tx1Raw = { + "in_mempool": false, + "in_orphanpool": false, + "txid": "61fedb3cb994917d2852191785ab59cb0d177d55d860bf10fd671f6a0a83247c", + "size": 372, + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": + "f716d010786225004b41e35dd5eebfb11a4e5ea116e1a48235e5d3a591650732", + "vout": 1, + "scriptSig": { + "asm": + "0 3045022100d80e1d056e8787d7fac8e59ce14d56a2dbb2aceb43da1fee47e687e318049abd02204bb06be6e8af85250b93e0f5377da535557176557563a4d0121b607ffbf3e7c1[ALL|FORKID] 304402200c528edd5f1c0aa169178f5a4c1ec5044559326f1608db6987398bdc0761aaae02205a94bb7f8dac69400823a0093e0303eaa2905b9fadbb8bbb111c3fef0a452ef0[ALL|FORKID] 522103ff1450283f08568acdb4d5f569f32e4cd4d8c1960ea049a205436f69f9916df8210230ee6aec65bc0db7e9cf507b33067f681047e180e91906e1fde1bb549f233b24210366058482ecccb47075be9d1d3edb46df331c04fa5126cd6fd9dc6cee071237b453ae", + "hex": + "00483045022100d80e1d056e8787d7fac8e59ce14d56a2dbb2aceb43da1fee47e687e318049abd02204bb06be6e8af85250b93e0f5377da535557176557563a4d0121b607ffbf3e7c14147304402200c528edd5f1c0aa169178f5a4c1ec5044559326f1608db6987398bdc0761aaae02205a94bb7f8dac69400823a0093e0303eaa2905b9fadbb8bbb111c3fef0a452ef0414c69522103ff1450283f08568acdb4d5f569f32e4cd4d8c1960ea049a205436f69f9916df8210230ee6aec65bc0db7e9cf507b33067f681047e180e91906e1fde1bb549f233b24210366058482ecccb47075be9d1d3edb46df331c04fa5126cd6fd9dc6cee071237b453ae" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.07, + "n": 0, + "scriptPubKey": { + "asm": + "OP_DUP OP_HASH160 0f6ca2ddb50a473f809440f77d3d931335ac2940 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9140f6ca2ddb50a473f809440f77d3d931335ac294088ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": ["12QZH44735UHWAXFgb4hfdq756GjzXtZG7"] + } + }, + { + "value": 0.71445709, + "n": 1, + "scriptPubKey": { + "asm": "OP_HASH160 872dcab340b7a8500b2585781e51e9217f11dced OP_EQUAL", + "hex": "a914872dcab340b7a8500b2585781e51e9217f11dced87", + "reqSigs": 1, + "type": "scripthash", + "addresses": ["3E1n17NnhVmWTGNbvH6ffKVNFjYT4Jke7G"] + } + } + ], + "blockhash": + "00000000000000000529d5816d2f9c97cfbe8c06bb87e9a15d9e778281ff9225", + "confirmations": 187, + "time": 1662544771, + "blocktime": 1662544771, + "hex": + "010000000132076591a5d3e53582a4e116a15e4e1ab1bfeed55de3414b0025627810d016f701000000fdfd0000483045022100d80e1d056e8787d7fac8e59ce14d56a2dbb2aceb43da1fee47e687e318049abd02204bb06be6e8af85250b93e0f5377da535557176557563a4d0121b607ffbf3e7c14147304402200c528edd5f1c0aa169178f5a4c1ec5044559326f1608db6987398bdc0761aaae02205a94bb7f8dac69400823a0093e0303eaa2905b9fadbb8bbb111c3fef0a452ef0414c69522103ff1450283f08568acdb4d5f569f32e4cd4d8c1960ea049a205436f69f9916df8210230ee6aec65bc0db7e9cf507b33067f681047e180e91906e1fde1bb549f233b24210366058482ecccb47075be9d1d3edb46df331c04fa5126cd6fd9dc6cee071237b453aeffffffff02c0cf6a00000000001976a9140f6ca2ddb50a473f809440f77d3d931335ac294088accd2c42040000000017a914872dcab340b7a8500b2585781e51e9217f11dced8700000000" +}; + +final tx2Raw = { + "in_mempool": false, + "in_orphanpool": false, + "txid": "9765cc2efa42ffdfb5ec86e6ae043de4cf2158a00ed19a182c4244bc548334ba", + "size": 225, + "version": 2, + "locktime": 0, + "vin": [ + { + "txid": + "61fedb3cb994917d2852191785ab59cb0d177d55d860bf10fd671f6a0a83247c", + "vout": 0, + "scriptSig": { + "asm": + "304402207b3301ec0ab0c7dbba32690b71e369a6872ff2d0c0cacaddc831bb04d22cef7102206e0bb6d039c408e301d49978aa34597f57d075b9a69e1a9f120e08af159b167a[ALL|FORKID] 02cb6cdf3e5758112206b4b02f21838b3d8a26c601a88030f3c5705e357d8e4ea8", + "hex": + "47304402207b3301ec0ab0c7dbba32690b71e369a6872ff2d0c0cacaddc831bb04d22cef7102206e0bb6d039c408e301d49978aa34597f57d075b9a69e1a9f120e08af159b167a412102cb6cdf3e5758112206b4b02f21838b3d8a26c601a88030f3c5705e357d8e4ea8" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.03, + "n": 0, + "scriptPubKey": { + "asm": + "OP_DUP OP_HASH160 87f3c240183ef0f3efe4b056029dd16d3e3d5d4f OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91487f3c240183ef0f3efe4b056029dd16d3e3d5d4f88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": ["1DPrEZBKKVG1Pf4HXeuCkw2Xk65EunR7CM"] + } + }, + { + "value": 0.03773, + "n": 1, + "scriptPubKey": { + "asm": + "OP_DUP OP_HASH160 7fa80c90c0f8aa021074702c06b3300c0b247244 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9147fa80c90c0f8aa021074702c06b3300c0b24724488ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": ["1Cdz8cpH3ZRuZViuah32YaTkNGryCS3DZj"] + } + } + ], + "blockhash": + "000000000000000005d25c8d3722e4486c486bbf864f9261631993afab557832", + "confirmations": 175, + "time": 1662553616, + "blocktime": 1662553616, + "hex": + "02000000017c24830a6a1f67fd10bf60d8557d170dcb59ab85171952287d9194b93cdbfe61000000006a47304402207b3301ec0ab0c7dbba32690b71e369a6872ff2d0c0cacaddc831bb04d22cef7102206e0bb6d039c408e301d49978aa34597f57d075b9a69e1a9f120e08af159b167a412102cb6cdf3e5758112206b4b02f21838b3d8a26c601a88030f3c5705e357d8e4ea8ffffffff02c0c62d00000000001976a91487f3c240183ef0f3efe4b056029dd16d3e3d5d4f88ac48923900000000001976a9147fa80c90c0f8aa021074702c06b3300c0b24724488ac00000000" +}; + +final tx3Raw = { + "in_mempool": false, + "in_orphanpool": false, + "txid": "070b45d901243b5856a0cccce8c5f5f548c19aaa00cb0059b37a6a9a3632288a", + "size": 226, + "version": 2, + "locktime": 0, + "vin": [ + { + "txid": + "9765cc2efa42ffdfb5ec86e6ae043de4cf2158a00ed19a182c4244bc548334ba", + "vout": 1, + "scriptSig": { + "asm": + "3045022100ed38dc64e40a5cfe137d38fbe9b7c4fe8a09ef923d7f999f35c65b029aa233ac02206f119c8d881a1b475697ec1eef815cde2e0e456ce4e234c5762fc7ddbe04ac27[ALL|FORKID] 029845663b31ebf3136039db97b3413b939b61c5bef45e4ee23544165a28ed452b", + "hex": + "483045022100ed38dc64e40a5cfe137d38fbe9b7c4fe8a09ef923d7f999f35c65b029aa233ac02206f119c8d881a1b475697ec1eef815cde2e0e456ce4e234c5762fc7ddbe04ac274121029845663b31ebf3136039db97b3413b939b61c5bef45e4ee23544165a28ed452b" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.02, + "n": 0, + "scriptPubKey": { + "asm": + "OP_DUP OP_HASH160 87f3c240183ef0f3efe4b056029dd16d3e3d5d4f OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91487f3c240183ef0f3efe4b056029dd16d3e3d5d4f88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": ["1DPrEZBKKVG1Pf4HXeuCkw2Xk65EunR7CM"] + } + }, + { + "value": 0.01772773, + "n": 1, + "scriptPubKey": { + "asm": + "OP_DUP OP_HASH160 39cb987d75cbe99ec577de2f1918ff2b3539491a OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a91439cb987d75cbe99ec577de2f1918ff2b3539491a88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": ["16GbR1Xau2hKFTr1STgB39NbP8CEkGZjYG"] + } + } + ], + "blockhash": + "00000000000000000227adf51d47ac640c7353e873a398901ecf9becbf5988d7", + "confirmations": 179, + "time": 1662555788, + "blocktime": 1662555788, + "hex": + "0200000001ba348354bc44422c189ad10ea05821cfe43d04aee686ecb5dfff42fa2ecc6597010000006b483045022100ed38dc64e40a5cfe137d38fbe9b7c4fe8a09ef923d7f999f35c65b029aa233ac02206f119c8d881a1b475697ec1eef815cde2e0e456ce4e234c5762fc7ddbe04ac274121029845663b31ebf3136039db97b3413b939b61c5bef45e4ee23544165a28ed452bffffffff0280841e00000000001976a91487f3c240183ef0f3efe4b056029dd16d3e3d5d4f88ace50c1b00000000001976a91439cb987d75cbe99ec577de2f1918ff2b3539491a88ac00000000" +}; + +final tx4Raw = { + "in_mempool": false, + "in_orphanpool": false, + "txid": "84aecde036ebe013aa3bd2fcb4741db504c7c040d34f7c33732c967646991855", + "size": 360, + "version": 1, + "locktime": 757301, + "vin": [ + { + "txid": + "070b45d901243b5856a0cccce8c5f5f548c19aaa00cb0059b37a6a9a3632288a", + "vout": 0, + "scriptSig": { + "asm": + "95a4d53e9059dc478b2f79dc486b4dd1ea2f34f3f2f870ba26a9c16530305ddc3e25b1d1d5adc42df75b4666b9fe6ec5b41813c0e82a579ce2167f6f7ed1b305[ALL|FORKID] 02d0825e4d527c9c24e0d423187055904f91218c82652b3fe575a212fef15531fd", + "hex": + "4195a4d53e9059dc478b2f79dc486b4dd1ea2f34f3f2f870ba26a9c16530305ddc3e25b1d1d5adc42df75b4666b9fe6ec5b41813c0e82a579ce2167f6f7ed1b305412102d0825e4d527c9c24e0d423187055904f91218c82652b3fe575a212fef15531fd" + }, + "sequence": 4294967294 + }, + { + "txid": + "9765cc2efa42ffdfb5ec86e6ae043de4cf2158a00ed19a182c4244bc548334ba", + "vout": 0, + "scriptSig": { + "asm": + "f2557ee7ae3eaf6488cc24972c73578ffc6ea2db047ffc4ff0b220f5d4efe491de01e1024ee77dc88d2cfa2f44b686bf394bd2a7114aac4fac48007547e2d313[ALL|FORKID] 02d0825e4d527c9c24e0d423187055904f91218c82652b3fe575a212fef15531fd", + "hex": + "41f2557ee7ae3eaf6488cc24972c73578ffc6ea2db047ffc4ff0b220f5d4efe491de01e1024ee77dc88d2cfa2f44b686bf394bd2a7114aac4fac48007547e2d313412102d0825e4d527c9c24e0d423187055904f91218c82652b3fe575a212fef15531fd" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.009996, + "n": 0, + "scriptPubKey": { + "asm": + "OP_DUP OP_HASH160 bd9e7c204b6d0d90ba018250fafa398d5ec1b39d OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914bd9e7c204b6d0d90ba018250fafa398d5ec1b39d88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": ["1JHcZyhgctuDCznjkxR51pQzKEJUujuc2j"] + } + }, + { + "value": 0.04, + "n": 1, + "scriptPubKey": { + "asm": + "OP_DUP OP_HASH160 f5c809c469d24bc0bf4f6a17a9218df1a79cd247 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914f5c809c469d24bc0bf4f6a17a9218df1a79cd24788ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": ["1PQaBto5KmiW3R2YeexYYoDWksMpEvhYZE"] + } + } + ], + "blockhash": + "000000000000000005aa6b3094801ec56f36f74d4b25cad38b22dc3d24cd3e43", + "confirmations": 1, + "time": 1662893734, + "blocktime": 1662893734, + "hex": + "01000000028a2832369a6a7ab35900cb00aa9ac148f5f5c5e8cccca056583b2401d9450b0700000000644195a4d53e9059dc478b2f79dc486b4dd1ea2f34f3f2f870ba26a9c16530305ddc3e25b1d1d5adc42df75b4666b9fe6ec5b41813c0e82a579ce2167f6f7ed1b305412102d0825e4d527c9c24e0d423187055904f91218c82652b3fe575a212fef15531fdfeffffffba348354bc44422c189ad10ea05821cfe43d04aee686ecb5dfff42fa2ecc6597000000006441f2557ee7ae3eaf6488cc24972c73578ffc6ea2db047ffc4ff0b220f5d4efe491de01e1024ee77dc88d2cfa2f44b686bf394bd2a7114aac4fac48007547e2d313412102d0825e4d527c9c24e0d423187055904f91218c82652b3fe575a212fef15531fdfeffffff02b0400f00000000001976a914bd9e7c204b6d0d90ba018250fafa398d5ec1b39d88ac00093d00000000001976a914f5c809c469d24bc0bf4f6a17a9218df1a79cd24788ac358e0b00" +}; diff --git a/test/services/coins/bitcoincash/bitcoincash_utxo_sample_data.dart b/test/services/coins/bitcoincash/bitcoincash_utxo_sample_data.dart new file mode 100644 index 000000000..54ab1c37b --- /dev/null +++ b/test/services/coins/bitcoincash/bitcoincash_utxo_sample_data.dart @@ -0,0 +1,84 @@ +import 'package:stackwallet/models/paymint/utxo_model.dart'; + +final Map>> batchGetUTXOResponse0 = { + "some id 0": [ + { + "tx_pos": 0, + "value": 7000000, + "tx_hash": + "61fedb3cb994917d2852191785ab59cb0d177d55d860bf10fd671f6a0a83247c", + "height": 756720 + }, + { + "tx_pos": 0, + "value": 3000000, + "tx_hash": + "9765cc2efa42ffdfb5ec86e6ae043de4cf2158a00ed19a182c4244bc548334ba", + "height": 756732 + }, + ], + "some id 1": [ + { + "tx_pos": 1, + "value": 2000000, + "tx_hash": + "070b45d901243b5856a0cccce8c5f5f548c19aaa00cb0059b37a6a9a3632288a", + "height": 756738 + }, + ], + "some id 2": [], +}; + +final utxoList = [ + UtxoObject( + txid: "9765cc2efa42ffdfb5ec86e6ae043de4cf2158a00ed19a182c4244bc548334ba", + vout: 0, + status: Status( + confirmed: true, + confirmations: 175, + blockHeight: 756732, + blockTime: 1662553616, + blockHash: + "000000000000000005d25c8d3722e4486c486bbf864f9261631993afab557832", + ), + value: 3000000, + fiatWorth: "\$0", + txName: "1DPrEZBKKVG1Pf4HXeuCkw2Xk65EunR7CM", + blocked: false, + isCoinbase: false, + ), + UtxoObject( + txid: "f716d010786225004b41e35dd5eebfb11a4e5ea116e1a48235e5d3a591650732", + vout: 1, + status: Status( + confirmed: true, + confirmations: 11867, + blockHeight: 745443, + blockTime: 1655792385, + blockHash: + "000000000000000000065c982f4d86a402e7182d0c6a49fa6cfbdaf67a57f566", + ), + value: 78446451, + fiatWorth: "\$0", + txName: "3E1n17NnhVmWTGNbvH6ffKVNFjYT4Jke7G", + blocked: false, + isCoinbase: false, + ), + UtxoObject( + txid: "070b45d901243b5856a0cccce8c5f5f548c19aaa00cb0059b37a6a9a3632288a", + vout: 0, + status: Status( + confirmed: true, + confirmations: 572, + blockHeight: 756738, + blockTime: 1662555788, + blockHash: + "00000000000000000227adf51d47ac640c7353e873a398901ecf9becbf5988d7", + ), + value: 2000000, + fiatWorth: "\$0", + txName: "1DPrEZBKKVG1Pf4HXeuCkw2Xk65EunR7CM", + blocked: false, + isCoinbase: false, + ), +]; diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart new file mode 100644 index 000000000..0e39892b1 --- /dev/null +++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart @@ -0,0 +1,2925 @@ +import 'package:bitcoindart/bitcoindart.dart'; +import 'package:decimal/decimal.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:hive/hive.dart'; +import 'package:hive_test/hive_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; +import 'package:stackwallet/electrumx_rpc/electrumx.dart'; +import 'package:stackwallet/hive/db.dart'; +import 'package:stackwallet/models/paymint/fee_object_model.dart'; +import 'package:stackwallet/models/paymint/transactions_model.dart'; +import 'package:stackwallet/models/paymint/utxo_model.dart'; +import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'; +import 'package:stackwallet/services/price.dart'; +import 'package:stackwallet/services/transaction_notification_tracker.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; + +// import '../../../cached_electrumx_test.mocks.dart'; +// import '../../../screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart'; +// import '../firo/firo_wallet_test.mocks.dart'; + +import 'bitcoincash_history_sample_data.dart'; +import 'bitcoincash_transaction_data_samples.dart'; +import 'bitcoincash_utxo_sample_data.dart'; +import 'bitcoincash_wallet_test.mocks.dart'; +import 'bitcoincash_wallet_test_parameters.dart'; + +@GenerateMocks( + [ElectrumX, CachedElectrumX, PriceAPI, TransactionNotificationTracker]) +void main() { + group("bitcoincash constants", () { + test("bitcoincash minimum confirmations", () async { + expect(MINIMUM_CONFIRMATIONS, 3); + }); + test("bitcoincash dust limit", () async { + expect(DUST_LIMIT, 1000000); + }); + test("bitcoincash mainnet genesis block hash", () async { + expect(GENESIS_HASH_MAINNET, + "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); + }); + }); + + test("bitcoincash DerivePathType enum", () { + expect(DerivePathType.values.length, 1); + expect(DerivePathType.values.toString(), "[DerivePathType.bip44]"); + }); + + group("bip32 node/root", () { + test("getBip32Root", () { + final root = getBip32Root(TEST_MNEMONIC, bitcoincash); + expect(root.toWIF(), ROOT_WIF); + }); + + test("basic getBip32Node", () { + final node = + getBip32Node(0, 0, TEST_MNEMONIC, bitcoincash, DerivePathType.bip44); + expect(node.toWIF(), NODE_WIF_44); + }); + }); + + group("validate mainnet bitcoincash addresses", () { + MockElectrumX? client; + MockCachedElectrumX? cachedClient; + MockPriceAPI? priceAPI; + FakeSecureStorage? secureStore; + MockTransactionNotificationTracker? tracker; + + BitcoinCashWallet? mainnetWallet; + + setUp(() { + client = MockElectrumX(); + cachedClient = MockCachedElectrumX(); + priceAPI = MockPriceAPI(); + secureStore = FakeSecureStorage(); + tracker = MockTransactionNotificationTracker(); + + mainnetWallet = BitcoinCashWallet( + walletId: "validateAddressMainNet", + walletName: "validateAddressMainNet", + coin: Coin.bitcoincash, + client: client!, + cachedClient: cachedClient!, + tracker: tracker!, + priceAPI: priceAPI, + secureStore: secureStore, + ); + }); + + test("valid mainnet legacy/p2pkh address type", () { + expect( + mainnetWallet?.addressType( + address: "DBYiFr1BRc2zB19p8jxdSu6DvFGTdWvkVF"), + DerivePathType.bip44); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("invalid base58 address type", () { + expect( + () => mainnetWallet?.addressType( + address: "mhqpGtwhcR6gFuuRjLTpHo41919QfuGy8Y"), + throwsArgumentError); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("invalid bech32 address type", () { + expect( + () => mainnetWallet?.addressType( + address: "tb1qzzlm6mnc8k54mx6akehl8p9ray8r439va5ndyq"), + throwsArgumentError); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("address has no matching script", () { + expect( + () => mainnetWallet?.addressType( + address: "mpMk94ETazqonHutyC1v6ajshgtP8oiFKU"), + throwsArgumentError); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("valid mainnet bitcoincash legacy/p2pkh address", () { + expect( + mainnetWallet?.validateAddress("DBYiFr1BRc2zB19p8jxdSu6DvFGTdWvkVF"), + true); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("invalid mainnet bitcoincash legacy/p2pkh address", () { + expect( + mainnetWallet?.validateAddress("mhqpGtwhcR6gFuuRjLTpHo41919QfuGy8Y"), + false); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + }); + + group("testNetworkConnection", () { + MockElectrumX? client; + MockCachedElectrumX? cachedClient; + MockPriceAPI? priceAPI; + FakeSecureStorage? secureStore; + MockTransactionNotificationTracker? tracker; + + BitcoinCashWallet? bch; + + setUp(() { + client = MockElectrumX(); + cachedClient = MockCachedElectrumX(); + priceAPI = MockPriceAPI(); + secureStore = FakeSecureStorage(); + tracker = MockTransactionNotificationTracker(); + + bch = BitcoinCashWallet( + walletId: "testNetworkConnection", + walletName: "testNetworkConnection", + coin: Coin.bitcoincash, + client: client!, + cachedClient: cachedClient!, + tracker: tracker!, + priceAPI: priceAPI, + secureStore: secureStore, + ); + }); + + test("attempted connection fails due to server error", () async { + when(client?.ping()).thenAnswer((_) async => false); + final bool? result = await bch?.testNetworkConnection(); + expect(result, false); + expect(secureStore?.interactions, 0); + verify(client?.ping()).called(1); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("attempted connection fails due to exception", () async { + when(client?.ping()).thenThrow(Exception); + final bool? result = await bch?.testNetworkConnection(); + expect(result, false); + expect(secureStore?.interactions, 0); + verify(client?.ping()).called(1); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("attempted connection test success", () async { + when(client?.ping()).thenAnswer((_) async => true); + final bool? result = await bch?.testNetworkConnection(); + expect(result, true); + expect(secureStore?.interactions, 0); + verify(client?.ping()).called(1); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + }); + + group("basic getters, setters, and functions", () { + final bchcoin = Coin.bitcoincash; + // final dtestcoin = Coin.bitcoincashTestNet; + final testWalletId = "DOGEtestWalletID"; + final testWalletName = "DOGEWallet"; + + MockElectrumX? client; + MockCachedElectrumX? cachedClient; + MockPriceAPI? priceAPI; + FakeSecureStorage? secureStore; + MockTransactionNotificationTracker? tracker; + + BitcoinCashWallet? bch; + + setUp(() async { + client = MockElectrumX(); + cachedClient = MockCachedElectrumX(); + priceAPI = MockPriceAPI(); + secureStore = FakeSecureStorage(); + tracker = MockTransactionNotificationTracker(); + + bch = BitcoinCashWallet( + walletId: testWalletId, + walletName: testWalletName, + coin: bchcoin, + client: client!, + cachedClient: cachedClient!, + tracker: tracker!, + priceAPI: priceAPI, + secureStore: secureStore, + ); + }); + + test("get networkType main", () async { + expect(bch?.coin, bchcoin); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("get networkType test", () async { + bch = BitcoinCashWallet( + walletId: testWalletId, + walletName: testWalletName, + coin: bchcoin, + client: client!, + cachedClient: cachedClient!, + tracker: tracker!, + priceAPI: priceAPI, + secureStore: secureStore, + ); + expect(bch?.coin, bchcoin); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("get cryptoCurrency", () async { + expect(Coin.bitcoincash, Coin.bitcoincash); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("get coinName", () async { + expect(Coin.bitcoincash, Coin.bitcoincash); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("get coinTicker", () async { + expect(Coin.bitcoincash, Coin.bitcoincash); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("get and set walletName", () async { + expect(Coin.bitcoincash, Coin.bitcoincash); + bch?.walletName = "new name"; + expect(bch?.walletName, "new name"); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("estimateTxFee", () async { + expect(bch?.estimateTxFee(vSize: 356, feeRatePerKB: 1), 356); + expect(bch?.estimateTxFee(vSize: 356, feeRatePerKB: 900), 356); + expect(bch?.estimateTxFee(vSize: 356, feeRatePerKB: 999), 356); + expect(bch?.estimateTxFee(vSize: 356, feeRatePerKB: 1000), 356); + expect(bch?.estimateTxFee(vSize: 356, feeRatePerKB: 1001), 712); + expect(bch?.estimateTxFee(vSize: 356, feeRatePerKB: 1699), 712); + expect(bch?.estimateTxFee(vSize: 356, feeRatePerKB: 2000), 712); + expect(bch?.estimateTxFee(vSize: 356, feeRatePerKB: 12345), 4628); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("get fees succeeds", () async { + when(client?.ping()).thenAnswer((_) async => true); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_TESTNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.estimateFee(blocks: 1)) + .thenAnswer((realInvocation) async => Decimal.zero); + when(client?.estimateFee(blocks: 5)) + .thenAnswer((realInvocation) async => Decimal.one); + when(client?.estimateFee(blocks: 20)) + .thenAnswer((realInvocation) async => Decimal.ten); + + final fees = await bch?.fees; + expect(fees, isA()); + expect(fees?.slow, 1000000000); + expect(fees?.medium, 100000000); + expect(fees?.fast, 0); + + verify(client?.estimateFee(blocks: 1)).called(1); + verify(client?.estimateFee(blocks: 5)).called(1); + verify(client?.estimateFee(blocks: 20)).called(1); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("get fees fails", () async { + when(client?.ping()).thenAnswer((_) async => true); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_TESTNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.estimateFee(blocks: 1)) + .thenAnswer((realInvocation) async => Decimal.zero); + when(client?.estimateFee(blocks: 5)) + .thenAnswer((realInvocation) async => Decimal.one); + when(client?.estimateFee(blocks: 20)) + .thenThrow(Exception("some exception")); + + bool didThrow = false; + try { + await bch?.fees; + } catch (_) { + didThrow = true; + } + + expect(didThrow, true); + + verify(client?.estimateFee(blocks: 1)).called(1); + verify(client?.estimateFee(blocks: 5)).called(1); + verify(client?.estimateFee(blocks: 20)).called(1); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("get maxFee", () async { + when(client?.ping()).thenAnswer((_) async => true); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_TESTNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.estimateFee(blocks: 20)) + .thenAnswer((realInvocation) async => Decimal.zero); + when(client?.estimateFee(blocks: 5)) + .thenAnswer((realInvocation) async => Decimal.one); + when(client?.estimateFee(blocks: 1)) + .thenAnswer((realInvocation) async => Decimal.ten); + + final maxFee = await bch?.maxFee; + expect(maxFee, 1000000000); + + verify(client?.estimateFee(blocks: 1)).called(1); + verify(client?.estimateFee(blocks: 5)).called(1); + verify(client?.estimateFee(blocks: 20)).called(1); + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + }); + + group("DogeWallet service class functions that depend on shared storage", () { + final bchcoin = Coin.bitcoincash; + // final dtestcoin = Coin.bitcoincashTestNet; + final testWalletId = "DOGEtestWalletID"; + final testWalletName = "DOGEWallet"; + + bool hiveAdaptersRegistered = false; + + MockElectrumX? client; + MockCachedElectrumX? cachedClient; + MockPriceAPI? priceAPI; + FakeSecureStorage? secureStore; + MockTransactionNotificationTracker? tracker; + + BitcoinCashWallet? bch; + + setUp(() async { + await setUpTestHive(); + if (!hiveAdaptersRegistered) { + hiveAdaptersRegistered = true; + + // Registering Transaction Model Adapters + Hive.registerAdapter(TransactionDataAdapter()); + Hive.registerAdapter(TransactionChunkAdapter()); + Hive.registerAdapter(TransactionAdapter()); + Hive.registerAdapter(InputAdapter()); + Hive.registerAdapter(OutputAdapter()); + + // Registering Utxo Model Adapters + Hive.registerAdapter(UtxoDataAdapter()); + Hive.registerAdapter(UtxoObjectAdapter()); + Hive.registerAdapter(StatusAdapter()); + + final wallets = await Hive.openBox('wallets'); + await wallets.put('currentWalletName', testWalletName); + } + + client = MockElectrumX(); + cachedClient = MockCachedElectrumX(); + priceAPI = MockPriceAPI(); + secureStore = FakeSecureStorage(); + tracker = MockTransactionNotificationTracker(); + + bch = BitcoinCashWallet( + walletId: testWalletId, + walletName: testWalletName, + coin: bchcoin, + client: client!, + cachedClient: cachedClient!, + tracker: tracker!, + priceAPI: priceAPI, + secureStore: secureStore, + ); + }); + + // test("initializeWallet no network", () async { + // when(client?.ping()).thenAnswer((_) async => false); + // await Hive.openBox(testWalletId); + // await Hive.openBox(DB.boxNamePrefs); + // expect(bch?.initializeNew(), false); + // expect(secureStore?.interactions, 0); + // verify(client?.ping()).called(0); + // verifyNoMoreInteractions(client); + // verifyNoMoreInteractions(cachedClient); + // verifyNoMoreInteractions(priceAPI); + // }); + + // test("initializeExisting no network exception", () async { + // when(client?.ping()).thenThrow(Exception("Network connection failed")); + // // bch?.initializeNew(); + // expect(bch?.initializeExisting(), false); + // expect(secureStore?.interactions, 0); + // verify(client?.ping()).called(1); + // verifyNoMoreInteractions(client); + // verifyNoMoreInteractions(cachedClient); + // verifyNoMoreInteractions(priceAPI); + // }); + + test("initializeNew mainnet throws bad network", () async { + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_TESTNET, + "hash_function": "sha256", + "services": [] + }); + + await Hive.openBox(testWalletId); + await Hive.openBox(DB.boxNamePrefs); + + expectLater(() => bch?.initializeNew(), throwsA(isA())) + .then((_) { + expect(secureStore?.interactions, 0); + verifyNever(client?.ping()).called(0); + verify(client?.getServerFeatures()).called(1); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(priceAPI); + }); + }); + + test("initializeNew throws mnemonic overwrite exception", () async { + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + await secureStore?.write( + key: "${testWalletId}_mnemonic", value: "some mnemonic"); + + await Hive.openBox(testWalletId); + await Hive.openBox(DB.boxNamePrefs); + + expectLater(() => bch?.initializeNew(), throwsA(isA())) + .then((_) { + expect(secureStore?.interactions, 2); + verifyNever(client?.ping()).called(0); + verify(client?.getServerFeatures()).called(1); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(priceAPI); + }); + }); + + test("initializeExisting testnet throws bad network", () async { + when(client?.ping()).thenAnswer((_) async => true); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + + bch = BitcoinCashWallet( + walletId: testWalletId, + walletName: testWalletName, + coin: bchcoin, + client: client!, + cachedClient: cachedClient!, + tracker: tracker!, + priceAPI: priceAPI, + secureStore: secureStore, + ); + + await Hive.openBox(testWalletId); + await Hive.openBox(DB.boxNamePrefs); + + expectLater(() => bch?.initializeNew(), throwsA(isA())) + .then((_) { + expect(secureStore?.interactions, 0); + verifyNever(client?.ping()).called(0); + verify(client?.getServerFeatures()).called(1); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(priceAPI); + }); + }); + + // test("getCurrentNode", () async { + // // when(priceAPI?.getbitcoincashPrice(baseCurrency: "USD")) + // // .thenAnswer((realInvocation) async => Decimal.fromInt(10)); + // when(client?.ping()).thenAnswer((_) async => true); + // when(client?.getServerFeatures()).thenAnswer((_) async => { + // "hosts": {}, + // "pruning": null, + // "server_version": "Unit tests", + // "protocol_min": "1.4", + // "protocol_max": "1.4.2", + // "genesis_hash": GENESIS_HASH_MAINNET, + // "hash_function": "sha256", + // "services": [] + // }); + // // await DebugService.instance.init(); + // expect(bch?.initializeExisting(), true); + // + // bool didThrow = false; + // try { + // await bch?.getCurrentNode(); + // } catch (_) { + // didThrow = true; + // } + // // expect no nodes on a fresh wallet unless set in db externally + // expect(didThrow, true); + // + // // set node + // final wallet = await Hive.openBox(testWalletId); + // await wallet.put("nodes", { + // "default": { + // "id": "some nodeID", + // "ipAddress": "some address", + // "port": "9000", + // "useSSL": true, + // } + // }); + // await wallet.put("activeNodeName", "default"); + // + // // try fetching again + // final node = await bch?.getCurrentNode(); + // expect(node.toString(), + // "ElectrumXNode: {address: some address, port: 9000, name: default, useSSL: true}"); + // + // verify(client?.ping()).called(1); + // verify(client?.getServerFeatures()).called(1); + // verifyNoMoreInteractions(client); + // verifyNoMoreInteractions(cachedClient); + // verifyNoMoreInteractions(priceAPI); + // }); + + // test("initializeWallet new main net wallet", () async { + // when(priceAPI?.getbitcoincashPrice(baseCurrency: "USD")) + // .thenAnswer((realInvocation) async => Decimal.fromInt(10)); + // when(client?.ping()).thenAnswer((_) async => true); + // when(client?.getServerFeatures()).thenAnswer((_) async => { + // "hosts": {}, + // "pruning": null, + // "server_version": "Unit tests", + // "protocol_min": "1.4", + // "protocol_max": "1.4.2", + // "genesis_hash": GENESIS_HASH_MAINNET, + // "hash_function": "sha256", + // "services": [] + // }); + // expect(await bch?.initializeWallet(), true); + // + // final wallet = await Hive.openBox(testWalletId); + // + // expect(await wallet.get("addressBookEntries"), {}); + // expect(await wallet.get('notes'), null); + // expect(await wallet.get("id"), testWalletId); + // expect(await wallet.get("preferredFiatCurrency"), null); + // expect(await wallet.get("blocked_tx_hashes"), ["0xdefault"]); + // + // final changeAddressesP2PKH = await wallet.get("changeAddressesP2PKH"); + // expect(changeAddressesP2PKH, isA>()); + // expect(changeAddressesP2PKH.length, 1); + // expect(await wallet.get("changeIndexP2PKH"), 0); + // + // final receivingAddressesP2PKH = + // await wallet.get("receivingAddressesP2PKH"); + // expect(receivingAddressesP2PKH, isA>()); + // expect(receivingAddressesP2PKH.length, 1); + // expect(await wallet.get("receivingIndexP2PKH"), 0); + // + // final p2pkhReceiveDerivations = jsonDecode(await secureStore?.read( + // key: "${testWalletId}_receiveDerivationsP2PKH")); + // expect(p2pkhReceiveDerivations.length, 1); + // + // final p2pkhChangeDerivations = jsonDecode(await secureStore.read( + // key: "${testWalletId}_changeDerivationsP2PKH")); + // expect(p2pkhChangeDerivations.length, 1); + // + // expect(secureStore?.interactions, 10); + // expect(secureStore?.reads, 7); + // expect(secureStore?.writes, 3); + // expect(secureStore?.deletes, 0); + // verify(client?.ping()).called(1); + // verify(client?.getServerFeatures()).called(1); + // verifyNoMoreInteractions(client); + // verifyNoMoreInteractions(cachedClient); + // verifyNoMoreInteractions(priceAPI); + // }); + + // // test("initializeWallet existing main net wallet", () async { + // // when(priceAPI?.getbitcoincashPrice(baseCurrency: "USD")) + // // .thenAnswer((realInvocation) async => Decimal.fromInt(10)); + // // when(client?.ping()).thenAnswer((_) async => true); + // // when(client?.getBatchHistory(args: anyNamed("args"))) + // // .thenAnswer((_) async => {}); + // // when(client?.getServerFeatures()).thenAnswer((_) async => { + // // "hosts": {}, + // // "pruning": null, + // // "server_version": "Unit tests", + // // "protocol_min": "1.4", + // // "protocol_max": "1.4.2", + // // "genesis_hash": GENESIS_HASH_MAINNET, + // // "hash_function": "sha256", + // // "services": [] + // // }); + // // // init new wallet + // // expect(bch?.initializeNew(), true); + // // + // // // fetch data to compare later + // // final newWallet = await Hive.openBox(testWalletId); + // // + // // final addressBookEntries = await newWallet.get("addressBookEntries"); + // // final notes = await newWallet.get('notes'); + // // final wID = await newWallet.get("id"); + // // final currency = await newWallet.get("preferredFiatCurrency"); + // // final blockedHashes = await newWallet.get("blocked_tx_hashes"); + // // + // // final changeAddressesP2PKH = await newWallet.get("changeAddressesP2PKH"); + // // final changeIndexP2PKH = await newWallet.get("changeIndexP2PKH"); + // // + // // final receivingAddressesP2PKH = + // // await newWallet.get("receivingAddressesP2PKH"); + // // final receivingIndexP2PKH = await newWallet.get("receivingIndexP2PKH"); + // // + // // final p2pkhReceiveDerivations = jsonDecode(await secureStore?.read( + // // key: "${testWalletId}_receiveDerivationsP2PKH")); + // // + // // final p2pkhChangeDerivations = jsonDecode(await secureStore?.read( + // // key: "${testWalletId}_changeDerivationsP2PKH")); + // // + // // // exit new wallet + // // await bch?.exit(); + // // + // // // open existing/created wallet + // // bch = BitcoinCashWallet( + // // walletId: testWalletId, + // // walletName: testWalletName, + // // coin: dtestcoin, + // // client: client!, + // // cachedClient: cachedClient!, + // // priceAPI: priceAPI, + // // secureStore: secureStore, + // // ); + // // + // // // init existing + // // expect(bch?.initializeExisting(), true); + // // + // // // compare data to ensure state matches state of previously closed wallet + // // final wallet = await Hive.openBox(testWalletId); + // // + // // expect(await wallet.get("addressBookEntries"), addressBookEntries); + // // expect(await wallet.get('notes'), notes); + // // expect(await wallet.get("id"), wID); + // // expect(await wallet.get("preferredFiatCurrency"), currency); + // // expect(await wallet.get("blocked_tx_hashes"), blockedHashes); + // // + // // expect(await wallet.get("changeAddressesP2PKH"), changeAddressesP2PKH); + // // expect(await wallet.get("changeIndexP2PKH"), changeIndexP2PKH); + // // + // // expect( + // // await wallet.get("receivingAddressesP2PKH"), receivingAddressesP2PKH); + // // expect(await wallet.get("receivingIndexP2PKH"), receivingIndexP2PKH); + // // + // // expect( + // // jsonDecode(await secureStore?.read( + // // key: "${testWalletId}_receiveDerivationsP2PKH")), + // // p2pkhReceiveDerivations); + // // + // // expect( + // // jsonDecode(await secureStore?.read( + // // key: "${testWalletId}_changeDerivationsP2PKH")), + // // p2pkhChangeDerivations); + // // + // // expect(secureStore?.interactions, 12); + // // expect(secureStore?.reads, 9); + // // expect(secureStore?.writes, 3); + // // expect(secureStore?.deletes, 0); + // // verify(client?.ping()).called(2); + // // verify(client?.getServerFeatures()).called(1); + // // verifyNoMoreInteractions(client); + // // verifyNoMoreInteractions(cachedClient); + // // verifyNoMoreInteractions(priceAPI); + // // }); + + test("get current receiving addresses", () async { + bch = BitcoinCashWallet( + walletId: testWalletId, + walletName: testWalletName, + coin: bchcoin, + client: client!, + cachedClient: cachedClient!, + tracker: tracker!, + priceAPI: priceAPI, + secureStore: secureStore, + ); + when(client?.ping()).thenAnswer((_) async => true); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_TESTNET, + "hash_function": "sha256", + "services": [] + }); + + await Hive.openBox(testWalletId); + await Hive.openBox(DB.boxNamePrefs); + + await bch?.initializeNew(); + await bch?.initializeExisting(); + expect( + Address.validateAddress( + await bch!.currentReceivingAddress, bitcoincashtestnet), + true); + expect( + Address.validateAddress( + await bch!.currentReceivingAddress, bitcoincashtestnet), + true); + expect( + Address.validateAddress( + await bch!.currentReceivingAddress, bitcoincashtestnet), + true); + + verifyNever(client?.ping()).called(0); + verify(client?.getServerFeatures()).called(1); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(priceAPI); + }); + + test("get allOwnAddresses", () async { + bch = BitcoinCashWallet( + walletId: testWalletId, + walletName: testWalletName, + coin: bchcoin, + client: client!, + cachedClient: cachedClient!, + tracker: tracker!, + priceAPI: priceAPI, + secureStore: secureStore, + ); + when(client?.ping()).thenAnswer((_) async => true); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_TESTNET, + "hash_function": "sha256", + "services": [] + }); + + await Hive.openBox(testWalletId); + await Hive.openBox(DB.boxNamePrefs); + + await bch?.initializeNew(); + await bch?.initializeExisting(); + final addresses = await bch?.allOwnAddresses; + expect(addresses, isA>()); + expect(addresses?.length, 2); + + for (int i = 0; i < 2; i++) { + expect( + Address.validateAddress(addresses![i], bitcoincashtestnet), true); + } + + verifyNever(client?.ping()).called(0); + verify(client?.getServerFeatures()).called(1); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(priceAPI); + }); + + // test("get utxos and balances", () async { + // bch = BitcoinCashWallet( + // walletId: testWalletId, + // walletName: testWalletName, + // coin: dtestcoin, + // client: client!, + // cachedClient: cachedClient!, + // tracker: tracker!, + // priceAPI: priceAPI, + // secureStore: secureStore, + // ); + // when(client?.ping()).thenAnswer((_) async => true); + // when(client?.getServerFeatures()).thenAnswer((_) async => { + // "hosts": {}, + // "pruning": null, + // "server_version": "Unit tests", + // "protocol_min": "1.4", + // "protocol_max": "1.4.2", + // "genesis_hash": GENESIS_HASH_TESTNET, + // "hash_function": "sha256", + // "services": [] + // }); + // + // await Hive.openBox(testWalletId); + // await Hive.openBox(DB.boxNamePrefs); + // + // when(client?.getBatchUTXOs(args: anyNamed("args"))) + // .thenAnswer((_) async => batchGetUTXOResponse0); + // + // when(client?.estimateFee(blocks: 20)) + // .thenAnswer((realInvocation) async => Decimal.zero); + // when(client?.estimateFee(blocks: 5)) + // .thenAnswer((realInvocation) async => Decimal.one); + // when(client?.estimateFee(blocks: 1)) + // .thenAnswer((realInvocation) async => Decimal.ten); + // + // when(cachedClient?.getTransaction( + // txHash: tx1.txid, + // coin: Coin.bitcoincashTestNet, + // )).thenAnswer((_) async => tx1Raw); + // when(cachedClient?.getTransaction( + // txHash: tx2.txid, + // coin: Coin.bitcoincashTestNet, + // )).thenAnswer((_) async => tx2Raw); + // when(cachedClient?.getTransaction( + // txHash: tx3.txid, + // coin: Coin.bitcoincashTestNet, + // )).thenAnswer((_) async => tx3Raw); + // when(cachedClient?.getTransaction( + // txHash: tx4.txid, + // coin: Coin.bitcoincashTestNet, + // )).thenAnswer((_) async => tx4Raw); + // + // await bch?.initializeNew(); + // await bch?.initializeExisting(); + // + // final utxoData = await bch?.utxoData; + // expect(utxoData, isA()); + // expect(utxoData.toString(), + // r"{totalUserCurrency: $103.2173, satoshiBalance: 1032173000, bitcoinBalance: null, unspentOutputArray: [{txid: 86198a91805b6c53839a6a97736c434a5a2f85d68595905da53df7df59b9f01a, vout: 0, value: 800000000, fiat: $80, blocked: false, status: {confirmed: true, blockHash: e52cabb4445eb9ceb3f4f8d68cc64b1ede8884ce560296c27826a48ecc477370, blockHeight: 4274457, blockTime: 1655755742, confirmations: 100}}, {txid: a4b6bd97a4b01b4305d0cf02e9bac6b7c37cda2f8e9dfe291ce4170b810ed469, vout: 0, value: 72173000, fiat: $7.2173, blocked: false, status: {confirmed: false, blockHash: bd239f922b3ecec299a90e4d1ce389334e8df4b95470fb5919966b0b650bb95b, blockHeight: 4270459, blockTime: 1655500912, confirmations: 0}}, {txid: 68c159dcc2f962cbc61f7dd3c8d0dcc14da8adb443811107115531c853fc0c60, vout: 1, value: 100000000, fiat: $10, blocked: false, status: {confirmed: false, blockHash: 9fee9b9446cfe81abb1a17bec56e6c160d9a6527e5b68b1141a827573bc2649f, blockHeight: 4255659, blockTime: 1654553247, confirmations: 0}}, {txid: 628a78606058ce4036aee3907e042742156c1894d34419578de5671b53ea5800, vout: 0, value: 60000000, fiat: $6, blocked: false, status: {confirmed: true, blockHash: bc461ab43e3a80d9a4d856ee9ff70f41d86b239d5f0581ffd6a5c572889a6b86, blockHeight: 4270352, blockTime: 1652888705, confirmations: 100}}]}"); + // + // final outputs = await bch?.unspentOutputs; + // expect(outputs, isA>()); + // expect(outputs?.length, 4); + // + // final availableBalance = await bch?.availableBalance; + // expect(availableBalance, Decimal.parse("8.6")); + // + // final totalBalance = await bch?.totalBalance; + // expect(totalBalance, Decimal.parse("10.32173")); + // + // final pendingBalance = await bch?.pendingBalance; + // expect(pendingBalance, Decimal.parse("1.72173")); + // + // final balanceMinusMaxFee = await bch?.balanceMinusMaxFee; + // expect(balanceMinusMaxFee, Decimal.parse("7.6")); + // + // verify(client?.ping()).called(1); + // verify(client?.getServerFeatures()).called(1); + // verify(client?.estimateFee(blocks: 1)).called(1); + // verify(client?.estimateFee(blocks: 5)).called(1); + // verify(client?.estimateFee(blocks: 20)).called(1); + // verify(client?.getBatchUTXOs(args: anyNamed("args"))).called(1); + // verify(cachedClient?.getTransaction( + // txHash: tx1.txid, + // coin: Coin.bitcoincashTestNet, + // )).called(1); + // verify(cachedClient?.getTransaction( + // txHash: tx2.txid, + // coin: Coin.bitcoincashTestNet, + // )).called(1); + // verify(cachedClient?.getTransaction( + // txHash: tx3.txid, + // coin: Coin.bitcoincashTestNet, + // )).called(1); + // verify(cachedClient?.getTransaction( + // txHash: tx4.txid, + // coin: Coin.bitcoincashTestNet, + // )).called(1); + // + // verifyNoMoreInteractions(client); + // verifyNoMoreInteractions(cachedClient); + // verifyNoMoreInteractions(priceAPI); + // }); + // + // // test("get utxos - multiple batches", () async { + // // bch = BitcoinCashWallet( + // // walletId: testWalletId, + // // walletName: testWalletName, + // // coin: dtestcoin, + // // client: client!, + // // cachedClient: cachedClient!, + // // priceAPI: priceAPI, + // // secureStore: secureStore, + // // ); + // // when(client?.ping()).thenAnswer((_) async => true); + // // when(client?.getServerFeatures()).thenAnswer((_) async => { + // // "hosts": {}, + // // "pruning": null, + // // "server_version": "Unit tests", + // // "protocol_min": "1.4", + // // "protocol_max": "1.4.2", + // // "genesis_hash": GENESIS_HASH_TESTNET, + // // "hash_function": "sha256", + // // "services": [] + // // }); + // // + // // when(client?.getBatchUTXOs(args: anyNamed("args"))) + // // .thenAnswer((_) async => {}); + // // + // // when(priceAPI?.getbitcoincashPrice(baseCurrency: "USD")) + // // .thenAnswer((realInvocation) async => Decimal.fromInt(10)); + // // + // // await bch?.initializeWallet(); + // // + // // // add some extra addresses to make sure we have more than the single batch size of 10 + // // final wallet = await Hive.openBox(testWalletId); + // // final addresses = await wallet.get("receivingAddressesP2PKH"); + // // addresses.add("DQaAi9R58GXMpDyhePys6hHCuif4fhc1sN"); + // // addresses.add("DBVhuF8QgeuxU2pssxzMgJqPhGCx5qyVkD"); + // // addresses.add("DCAokB2CXXPWC2JPj6jrK6hxANwTF2m21x"); + // // addresses.add("D6Y9brE3jUGPrqLmSEWh6yQdgY5b7ZkTib"); + // // addresses.add("DKdtobt3M5b3kQWZf1zRUZn3Ys6JTQwbPL"); + // // addresses.add("DBYiFr1BRc2zB19p8jxdSu6DvFGTdWvkVF"); + // // addresses.add("DE5ffowvbHPzzY6aRVGpzxR2QqikXxUKPG"); + // // addresses.add("DA97TLg1741J2aLK6z9bVZoWysgQbMR45K"); + // // addresses.add("DGGmf9q4PKcJXauPRstsFetu9DjW1VSBYk"); + // // addresses.add("D9bXqnTtufcb6oJyuZniCXbst8MMLzHxUd"); + // // addresses.add("DA6nv8M4kYL4RxxKrcsPaPUA1KrFA7CTfN"); + // // await wallet.put("receivingAddressesP2PKH", addresses); + // // + // // final utxoData = await bch?.utxoData; + // // expect(utxoData, isA()); + // // + // // final outputs = await bch?.unspentOutputs; + // // expect(outputs, isA>()); + // // expect(outputs?.length, 0); + // // + // // verify(client?.ping()).called(1); + // // verify(client?.getServerFeatures()).called(1); + // // verify(client?.getBatchUTXOs(args: anyNamed("args"))).called(2); + // // verify(priceAPI?.getbitcoincashPrice(baseCurrency: "USD")).called(1); + // // + // // verifyNoMoreInteractions(client); + // // verifyNoMoreInteractions(cachedClient); + // // verifyNoMoreInteractions(priceAPI); + // // }); + // + test("get utxos fails", () async { + bch = BitcoinCashWallet( + walletId: testWalletId, + walletName: testWalletName, + coin: bchcoin, + client: client!, + cachedClient: cachedClient!, + tracker: tracker!, + priceAPI: priceAPI, + secureStore: secureStore, + ); + when(client?.ping()).thenAnswer((_) async => true); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_TESTNET, + "hash_function": "sha256", + "services": [] + }); + + await Hive.openBox(testWalletId); + await Hive.openBox(DB.boxNamePrefs); + + when(client?.getBatchUTXOs(args: anyNamed("args"))) + .thenThrow(Exception("some exception")); + + await bch?.initializeNew(); + await bch?.initializeExisting(); + + final utxoData = await bch?.utxoData; + expect(utxoData, isA()); + expect(utxoData.toString(), + r"{totalUserCurrency: 0.00, satoshiBalance: 0, bitcoinBalance: 0, unspentOutputArray: []}"); + + final outputs = await bch?.unspentOutputs; + expect(outputs, isA>()); + expect(outputs?.length, 0); + + verifyNever(client?.ping()).called(0); + verify(client?.getServerFeatures()).called(1); + verify(client?.getBatchUTXOs(args: anyNamed("args"))).called(1); + + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(priceAPI); + }); + + test("chain height fetch, update, and get", () async { + bch = BitcoinCashWallet( + walletId: testWalletId, + walletName: testWalletName, + coin: bchcoin, + client: client!, + cachedClient: cachedClient!, + tracker: tracker!, + priceAPI: priceAPI, + secureStore: secureStore, + ); + when(client?.ping()).thenAnswer((_) async => true); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_TESTNET, + "hash_function": "sha256", + "services": [] + }); + + await Hive.openBox(testWalletId); + await Hive.openBox(DB.boxNamePrefs); + + await bch?.initializeNew(); + await bch?.initializeExisting(); + + // get stored + expect(await bch?.storedChainHeight, 0); + + // fetch fails + when(client?.getBlockHeadTip()).thenThrow(Exception("Some exception")); + expect(await bch?.chainHeight, -1); + + // fetch succeeds + when(client?.getBlockHeadTip()).thenAnswer((realInvocation) async => { + "height": 100, + "hex": "some block hex", + }); + expect(await bch?.chainHeight, 100); + + // update + await bch?.updateStoredChainHeight(newHeight: 1000); + + // fetch updated + expect(await bch?.storedChainHeight, 1000); + + verifyNever(client?.ping()).called(0); + verify(client?.getServerFeatures()).called(1); + verify(client?.getBlockHeadTip()).called(2); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("getTxCount succeeds", () async { + when(client?.getHistory( + scripthash: + "64953f7db441a21172de206bf70b920c8c718ed4f03df9a85073c0400be0053c")) + .thenAnswer((realInvocation) async => [ + { + "height": 4270352, + "tx_hash": + "7b34e60cc37306f866667deb67b14096f4ea2add941fd6e2238a639000642b82" + }, + { + "height": 4274457, + "tx_hash": + "9cd994199f9ee58c823a03bab24da87c25e0157cb42c226e191aadadbb96e452" + } + ]); + + final count = + await bch?.getTxCount(address: "D6biRASajCy7GcJ8R6ZP4RE94fNRerJLCC"); + + expect(count, 2); + + verify(client?.getHistory( + scripthash: + "64953f7db441a21172de206bf70b920c8c718ed4f03df9a85073c0400be0053c")) + .called(1); + + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("getTxCount fails", () async { + when(client?.getHistory( + scripthash: + "64953f7db441a21172de206bf70b920c8c718ed4f03df9a85073c0400be0053c")) + .thenThrow(Exception("some exception")); + + bool didThrow = false; + try { + await bch?.getTxCount(address: "D6biRASajCy7GcJ8R6ZP4RE94fNRerJLCC"); + } catch (_) { + didThrow = true; + } + expect(didThrow, true); + + verify(client?.getHistory( + scripthash: + "64953f7db441a21172de206bf70b920c8c718ed4f03df9a85073c0400be0053c")) + .called(1); + + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("_checkCurrentReceivingAddressesForTransactions succeeds", () async { + when(client?.ping()).thenAnswer((_) async => true); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.getHistory(scripthash: anyNamed("scripthash"))) + .thenAnswer((realInvocation) async => [ + { + "height": 4270385, + "tx_hash": + "c07f740ad72c0dd759741f4c9ab4b1586a22bc16545584364ac9b3d845766271" + }, + { + "height": 4270459, + "tx_hash": + "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a" + } + ]); + + await Hive.openBox(testWalletId); + await Hive.openBox(DB.boxNamePrefs); + + await bch?.initializeNew(); + await bch?.initializeExisting(); + + bool didThrow = false; + try { + await bch?.checkCurrentReceivingAddressesForTransactions(); + } catch (_) { + didThrow = true; + } + expect(didThrow, false); + + verify(client?.getHistory(scripthash: anyNamed("scripthash"))).called(1); + verify(client?.getServerFeatures()).called(1); + verifyNever(client?.ping()).called(0); + + expect(secureStore?.interactions, 11); + expect(secureStore?.reads, 7); + expect(secureStore?.writes, 4); + expect(secureStore?.deletes, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(priceAPI); + }); + + test("_checkCurrentReceivingAddressesForTransactions fails", () async { + when(client?.ping()).thenAnswer((_) async => true); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.getHistory(scripthash: anyNamed("scripthash"))) + .thenThrow(Exception("some exception")); + + await Hive.openBox(testWalletId); + await Hive.openBox(DB.boxNamePrefs); + + await bch?.initializeNew(); + await bch?.initializeExisting(); + + bool didThrow = false; + try { + await bch?.checkCurrentReceivingAddressesForTransactions(); + } catch (_) { + didThrow = true; + } + expect(didThrow, true); + + verify(client?.getHistory(scripthash: anyNamed("scripthash"))).called(1); + verify(client?.getServerFeatures()).called(1); + verifyNever(client?.ping()).called(0); + + expect(secureStore?.interactions, 8); + expect(secureStore?.reads, 5); + expect(secureStore?.writes, 3); + expect(secureStore?.deletes, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(priceAPI); + }); + + test("_checkCurrentChangeAddressesForTransactions succeeds", () async { + when(client?.ping()).thenAnswer((_) async => true); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.getHistory(scripthash: anyNamed("scripthash"))) + .thenAnswer((realInvocation) async => [ + { + "height": 4286283, + "tx_hash": + "4c119685401e28982283e644c57d84fde6aab83324012e35c9b49e6efd99b49b" + }, + { + "height": 4286295, + "tx_hash": + "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a" + } + ]); + + await Hive.openBox(testWalletId); + await Hive.openBox(DB.boxNamePrefs); + + await bch?.initializeNew(); + await bch?.initializeExisting(); + + bool didThrow = false; + try { + await bch?.checkCurrentChangeAddressesForTransactions(); + } catch (_) { + didThrow = true; + } + expect(didThrow, false); + + verify(client?.getHistory(scripthash: anyNamed("scripthash"))).called(1); + verify(client?.getServerFeatures()).called(1); + verifyNever(client?.ping()).called(0); + + expect(secureStore?.interactions, 11); + expect(secureStore?.reads, 7); + expect(secureStore?.writes, 4); + expect(secureStore?.deletes, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("_checkCurrentChangeAddressesForTransactions fails", () async { + when(client?.ping()).thenAnswer((_) async => true); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.getHistory(scripthash: anyNamed("scripthash"))) + .thenThrow(Exception("some exception")); + + await Hive.openBox(testWalletId); + await Hive.openBox(DB.boxNamePrefs); + + await bch?.initializeNew(); + await bch?.initializeExisting(); + + bool didThrow = false; + try { + await bch?.checkCurrentChangeAddressesForTransactions(); + } catch (_) { + didThrow = true; + } + expect(didThrow, true); + + verify(client?.getHistory(scripthash: anyNamed("scripthash"))).called(1); + verify(client?.getServerFeatures()).called(1); + verifyNever(client?.ping()).called(0); + + expect(secureStore?.interactions, 8); + expect(secureStore?.reads, 5); + expect(secureStore?.writes, 3); + expect(secureStore?.deletes, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(priceAPI); + }); + + // test("getAllTxsToWatch", () async { + // TestWidgetsFlutterBinding.ensureInitialized(); + // var notifications = {"show": 0}; + // const MethodChannel('dexterous.com/flutter/local_notifications') + // .setMockMethodCallHandler((call) async { + // notifications[call.method]++; + // }); + // + // bch?.pastUnconfirmedTxs = { + // "88b7b5077d940dde1bc63eba37a09dec8e7b9dad14c183a2e879a21b6ec0ac1c", + // "b39bac02b65af46a49e2985278fe24ca00dd5d627395d88f53e35568a04e10fa", + // }; + // + // await bch?.getAllTxsToWatch(transactionData); + // expect(notifications.length, 1); + // expect(notifications["show"], 3); + // + // expect(bch?.unconfirmedTxs, { + // "b2f75a017a7435f1b8c2e080a865275d8f80699bba68d8dce99a94606e7b3528", + // 'dcca229760b44834478f0b266c9b3f5801e0139fdecacdc0820e447289a006d3', + // }); + // + // expect(secureStore?.interactions, 0); + // verifyNoMoreInteractions(client); + // verifyNoMoreInteractions(cachedClient); + // verifyNoMoreInteractions(priceAPI); + // }); + // + // test("refreshIfThereIsNewData true A", () async { + // when(client?.getTransaction( + // txHash: + // "a4b6bd97a4b01b4305d0cf02e9bac6b7c37cda2f8e9dfe291ce4170b810ed469", + // )).thenAnswer((_) async => tx2Raw); + // when(client?.getTransaction( + // txHash: + // "86198a91805b6c53839a6a97736c434a5a2f85d68595905da53df7df59b9f01a", + // )).thenAnswer((_) async => tx1Raw); + // + // bch = BitcoinCashWallet( + // walletId: testWalletId, + // walletName: testWalletName, + // coin: dtestcoin, + // client: client!, + // cachedClient: cachedClient!, + // priceAPI: priceAPI, + // secureStore: secureStore, + // ); + // final wallet = await Hive.openBox(testWalletId); + // await wallet.put('receivingAddressesP2PKH', []); + // + // await wallet.put('changeAddressesP2PKH', []); + // + // bch?.unconfirmedTxs = { + // "a4b6bd97a4b01b4305d0cf02e9bac6b7c37cda2f8e9dfe291ce4170b810ed469", + // "86198a91805b6c53839a6a97736c434a5a2f85d68595905da53df7df59b9f01a" + // }; + // + // final result = await bch?.refreshIfThereIsNewData(); + // + // expect(result, true); + // + // verify(client?.getTransaction( + // txHash: + // "a4b6bd97a4b01b4305d0cf02e9bac6b7c37cda2f8e9dfe291ce4170b810ed469", + // )).called(1); + // verify(client?.getTransaction( + // txHash: + // "86198a91805b6c53839a6a97736c434a5a2f85d68595905da53df7df59b9f01a", + // )).called(1); + // + // expect(secureStore?.interactions, 0); + // verifyNoMoreInteractions(client); + // verifyNoMoreInteractions(cachedClient); + // verifyNoMoreInteractions(priceAPI); + // }); + // + // test("refreshIfThereIsNewData true B", () async { + // // when(priceAPI.getbitcoincashPrice(baseCurrency: "USD")) + // // .thenAnswer((_) async => Decimal.fromInt(10)); + // + // when(client?.getBatchHistory(args: anyNamed("args"))) + // .thenAnswer((realInvocation) async { + // final uuids = Map>.from(realInvocation + // .namedArguments.values.first as Map) + // .keys + // .toList(growable: false); + // return { + // uuids[0]: [ + // { + // "tx_hash": + // "351a94874379a5444c8891162472acf66de538a1abc647d4753f3e1eb5ec66f9", + // "height": 4286305 + // }, + // { + // "tx_hash": + // "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a", + // "height": 4286295 + // } + // ], + // uuids[1]: [ + // { + // "tx_hash": + // "4c119685401e28982283e644c57d84fde6aab83324012e35c9b49e6efd99b49b", + // "height": 4286283 + // } + // ], + // }; + // }); + // + // when(client?.getTransaction( + // txHash: + // "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a", + // )).thenAnswer((_) async => tx2Raw); + // when(client?.getTransaction( + // txHash: + // "4c119685401e28982283e644c57d84fde6aab83324012e35c9b49e6efd99b49b", + // )).thenAnswer((_) async => tx1Raw); + // + // when(cachedClient?.getTransaction( + // txHash: + // "351a94874379a5444c8891162472acf66de538a1abc647d4753f3e1eb5ec66f9", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx3Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "351a94874379a5444c8891162472acf66de538a1abc647d4753f3e1eb5ec66f9", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx3Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "4c119685401e28982283e644c57d84fde6aab83324012e35c9b49e6efd99b49b", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx1Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "4493caff0e1b4f248e3c6219e7f288cfdb46c32b72a77aec469098c5f7f5154e", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx5Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "e095cbe5531d174c3fc5c9c39a0e6ba2769489cdabdc17b35b2e3a33a3c2fc61", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx6Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "d3054c63fe8cfafcbf67064ec66b9fbe1ac293860b5d6ffaddd39546658b72de", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx7Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "7b34e60cc37306f866667deb67b14096f4ea2add941fd6e2238a639000642b82", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx4Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "a70c6f0690fa84712dc6b3d20ee13862fe015a08cf2dc8949c4300d49c3bdeb5", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx8Raw); + // + // bch = BitcoinCashWallet( + // walletId: testWalletId, + // walletName: testWalletName, + // coin: dtestcoin, + // client: client!, + // cachedClient: cachedClient!, + // priceAPI: priceAPI, + // secureStore: secureStore, + // ); + // final wallet = await Hive.openBox(testWalletId); + // await wallet.put('receivingAddressesP2PKH', []); + // + // await wallet.put('changeAddressesP2PKH', []); + // + // bch?.unconfirmedTxs = { + // "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a", + // }; + // + // final result = await bch?.refreshIfThereIsNewData(); + // + // expect(result, true); + // + // verify(client?.getBatchHistory(args: anyNamed("args"))).called(2); + // verify(client?.getTransaction( + // txHash: + // "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a", + // )).called(1); + // verify(cachedClient?.getTransaction( + // txHash: anyNamed("tx_hash"), + // verbose: true, + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .called(9); + // // verify(priceAPI?.getbitcoincashPrice(baseCurrency: "USD")).called(1); + // + // expect(secureStore?.interactions, 0); + // verifyNoMoreInteractions(client); + // verifyNoMoreInteractions(cachedClient); + // verifyNoMoreInteractions(priceAPI); + // }); + + // test("refreshIfThereIsNewData false A", () async { + // // when(priceAPI.getbitcoincashPrice(baseCurrency: "USD")) + // // .thenAnswer((_) async => Decimal.fromInt(10)); + // + // when(client?.getBatchHistory(args: anyNamed("args"))) + // .thenAnswer((realInvocation) async { + // final uuids = Map>.from(realInvocation + // .namedArguments.values.first as Map) + // .keys + // .toList(growable: false); + // return { + // uuids[0]: [ + // { + // "tx_hash": + // "351a94874379a5444c8891162472acf66de538a1abc647d4753f3e1eb5ec66f9", + // "height": 4286305 + // }, + // { + // "tx_hash": + // "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a", + // "height": 4286295 + // } + // ], + // uuids[1]: [ + // { + // "tx_hash": + // "4c119685401e28982283e644c57d84fde6aab83324012e35c9b49e6efd99b49b", + // "height": 4286283 + // } + // ], + // }; + // }); + // + // when(client?.getTransaction( + // txHash: + // "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a", + // )).thenAnswer((_) async => tx2Raw); + // when(client?.getTransaction( + // txHash: + // "4c119685401e28982283e644c57d84fde6aab83324012e35c9b49e6efd99b49b", + // )).thenAnswer((_) async => tx1Raw); + // + // when(cachedClient?.getTransaction( + // txHash: + // "4c119685401e28982283e644c57d84fde6aab83324012e35c9b49e6efd99b49b", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx1Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx2Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "351a94874379a5444c8891162472acf66de538a1abc647d4753f3e1eb5ec66f9", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx3Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "4493caff0e1b4f248e3c6219e7f288cfdb46c32b72a77aec469098c5f7f5154e", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx5Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "7b34e60cc37306f866667deb67b14096f4ea2add941fd6e2238a639000642b82", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx4Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "e095cbe5531d174c3fc5c9c39a0e6ba2769489cdabdc17b35b2e3a33a3c2fc61", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx6Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "d3054c63fe8cfafcbf67064ec66b9fbe1ac293860b5d6ffaddd39546658b72de", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx7Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "a70c6f0690fa84712dc6b3d20ee13862fe015a08cf2dc8949c4300d49c3bdeb5", + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx8Raw); + // + // bch = BitcoinCashWallet( + // walletId: testWalletId, + // walletName: testWalletName, + // coin: dtestcoin, + // client: client!, + // cachedClient: cachedClient!, + // tracker: tracker!, + // priceAPI: priceAPI, + // secureStore: secureStore, + // ); + // final wallet = await Hive.openBox(testWalletId); + // await wallet.put('receivingAddressesP2PKH', []); + // + // await wallet.put('changeAddressesP2PKH', []); + // + // bch?.unconfirmedTxs = { + // "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a", + // "351a94874379a5444c8891162472acf66de538a1abc647d4753f3e1eb5ec66f9" + // }; + // + // final result = await bch?.refreshIfThereIsNewData(); + // + // expect(result, false); + // + // verify(client?.getBatchHistory(args: anyNamed("args"))).called(2); + // verify(client?.getTransaction( + // txHash: + // "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a", + // )).called(1); + // verify(cachedClient?.getTransaction( + // txHash: anyNamed("tx_hash"), + // verbose: true, + // coin: Coin.bitcoincashTestNet, + // callOutSideMainIsolate: false)) + // .called(15); + // // verify(priceAPI.getbitcoincashPrice(baseCurrency: "USD")).called(1); + // + // expect(secureStore?.interactions, 0); + // verifyNoMoreInteractions(client); + // verifyNoMoreInteractions(cachedClient); + // verifyNoMoreInteractions(priceAPI); + // }); + + // // test("refreshIfThereIsNewData false B", () async { + // // when(client?.getBatchHistory(args: anyNamed("args"))) + // // .thenThrow(Exception("some exception")); + // // + // // when(client?.getTransaction( + // // txHash: + // // "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a", + // // )).thenAnswer((_) async => tx2Raw); + // // + // // bch = BitcoinCashWallet( + // // walletId: testWalletId, + // // walletName: testWalletName, + // // coin: dtestcoin, + // // client: client!, + // // cachedClient: cachedClient!, + // // tracker: tracker!, + // // priceAPI: priceAPI, + // // secureStore: secureStore, + // // ); + // // final wallet = await Hive.openBox(testWalletId); + // // await wallet.put('receivingAddressesP2PKH', []); + // // + // // await wallet.put('changeAddressesP2PKH', []); + // // + // // bch?.unconfirmedTxs = { + // // "82da70c660daf4d42abd403795d047918c4021ff1d706b61790cda01a1c5ae5a", + // // }; + // // + // // final result = await bch?.refreshIfThereIsNewData(); + // // + // // expect(result, false); + // // + // // verify(client?.getBatchHistory(args: anyNamed("args"))).called(1); + // // verify(client?.getTransaction( + // // txHash: + // // "a4b6bd97a4b01b4305d0cf02e9bac6b7c37cda2f8e9dfe291ce4170b810ed469", + // // )).called(1); + // // + // // expect(secureStore?.interactions, 0); + // // verifyNoMoreInteractions(client); + // // verifyNoMoreInteractions(cachedClient); + // // verifyNoMoreInteractions(priceAPI); + // // }); + + test("fullRescan succeeds", () async { + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.getBatchHistory(args: historyBatchArgs0)) + .thenAnswer((_) async => historyBatchResponse); + when(client?.getBatchHistory(args: historyBatchArgs1)) + .thenAnswer((_) async => historyBatchResponse); + when(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash)) + .thenAnswer((realInvocation) async {}); + + final wallet = await Hive.openBox(testWalletId); + + // restore so we have something to rescan + await bch?.recoverFromMnemonic( + mnemonic: TEST_MNEMONIC, + maxUnusedAddressGap: 2, + maxNumberOfIndexesToCheck: 1000, + height: 4000); + + // fetch valid wallet data + final preReceivingAddressesP2PKH = + await wallet.get('receivingAddressesP2PKH'); + final preChangeAddressesP2PKH = await wallet.get('changeAddressesP2PKH'); + final preReceivingIndexP2PKH = await wallet.get('receivingIndexP2PKH'); + final preChangeIndexP2PKH = await wallet.get('changeIndexP2PKH'); + final preUtxoData = await wallet.get('latest_utxo_model'); + final preReceiveDerivationsStringP2PKH = await secureStore?.read( + key: "${testWalletId}_receiveDerivationsP2PKH"); + final preChangeDerivationsStringP2PKH = await secureStore?.read( + key: "${testWalletId}_changeDerivationsP2PKH"); + + // destroy the data that the rescan will fix + await wallet.put( + 'receivingAddressesP2PKH', ["some address", "some other address"]); + await wallet + .put('changeAddressesP2PKH', ["some address", "some other address"]); + + await wallet.put('receivingIndexP2PKH', 123); + await wallet.put('changeIndexP2PKH', 123); + await secureStore?.write( + key: "${testWalletId}_receiveDerivationsP2PKH", value: "{}"); + await secureStore?.write( + key: "${testWalletId}_changeDerivationsP2PKH", value: "{}"); + + bool hasThrown = false; + try { + await bch?.fullRescan(2, 1000); + } catch (_) { + hasThrown = true; + } + expect(hasThrown, false); + + // fetch wallet data again + final receivingAddressesP2PKH = + await wallet.get('receivingAddressesP2PKH'); + final changeAddressesP2PKH = await wallet.get('changeAddressesP2PKH'); + final receivingIndexP2PKH = await wallet.get('receivingIndexP2PKH'); + final changeIndexP2PKH = await wallet.get('changeIndexP2PKH'); + final utxoData = await wallet.get('latest_utxo_model'); + final receiveDerivationsStringP2PKH = await secureStore?.read( + key: "${testWalletId}_receiveDerivationsP2PKH"); + final changeDerivationsStringP2PKH = await secureStore?.read( + key: "${testWalletId}_changeDerivationsP2PKH"); + + expect(preReceivingAddressesP2PKH, receivingAddressesP2PKH); + expect(preChangeAddressesP2PKH, changeAddressesP2PKH); + expect(preReceivingIndexP2PKH, receivingIndexP2PKH); + expect(preChangeIndexP2PKH, changeIndexP2PKH); + expect(preUtxoData, utxoData); + expect(preReceiveDerivationsStringP2PKH, receiveDerivationsStringP2PKH); + expect(preChangeDerivationsStringP2PKH, changeDerivationsStringP2PKH); + + verify(client?.getServerFeatures()).called(1); + verify(client?.getBatchHistory(args: historyBatchArgs0)).called(2); + verify(client?.getBatchHistory(args: historyBatchArgs1)).called(2); + verify(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash)) + .called(1); + + expect(secureStore?.writes, 9); + expect(secureStore?.reads, 12); + expect(secureStore?.deletes, 2); + + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("get mnemonic list", () async { + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.getBatchHistory(args: historyBatchArgs0)) + .thenAnswer((_) async => emptyHistoryBatchResponse); + when(client?.getBatchHistory(args: historyBatchArgs1)) + .thenAnswer((_) async => emptyHistoryBatchResponse); + + final wallet = await Hive.openBox(testWalletId); + + // add maxNumberOfIndexesToCheck and height + await bch?.recoverFromMnemonic( + mnemonic: TEST_MNEMONIC, + maxUnusedAddressGap: 2, + maxNumberOfIndexesToCheck: 1000, + height: 4000); + + expect(await bch?.mnemonic, TEST_MNEMONIC.split(" ")); + + verify(client?.getServerFeatures()).called(1); + verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1); + verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); + + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test( + "recoverFromMnemonic using empty seed on mainnet fails due to bad genesis hash match", + () async { + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_TESTNET, + "hash_function": "sha256", + "services": [] + }); + + bool hasThrown = false; + try { + await bch?.recoverFromMnemonic( + mnemonic: TEST_MNEMONIC, + maxUnusedAddressGap: 2, + maxNumberOfIndexesToCheck: 1000, + height: 4000); + } catch (_) { + hasThrown = true; + } + expect(hasThrown, true); + + verify(client?.getServerFeatures()).called(1); + + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(priceAPI); + }); + + test( + "recoverFromMnemonic using empty seed on testnet fails due to bad genesis hash match", + () async { + bch = BitcoinCashWallet( + walletId: testWalletId, + walletName: testWalletName, + coin: Coin.bitcoincashTestNet, + client: client!, + cachedClient: cachedClient!, + tracker: tracker!, + priceAPI: priceAPI, + secureStore: secureStore, + ); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + + bool hasThrown = false; + try { + await bch?.recoverFromMnemonic( + mnemonic: TEST_MNEMONIC, + maxUnusedAddressGap: 2, + maxNumberOfIndexesToCheck: 1000, + height: 4000); + } catch (_) { + hasThrown = true; + } + expect(hasThrown, true); + + verify(client?.getServerFeatures()).called(1); + + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(priceAPI); + }); + + test( + "recoverFromMnemonic using empty seed on mainnet fails due to attempted overwrite of mnemonic", + () async { + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + + await secureStore?.write( + key: "${testWalletId}_mnemonic", value: "some mnemonic words"); + + bool hasThrown = false; + try { + await bch?.recoverFromMnemonic( + mnemonic: TEST_MNEMONIC, + maxUnusedAddressGap: 2, + maxNumberOfIndexesToCheck: 1000, + height: 4000); + } catch (_) { + hasThrown = true; + } + expect(hasThrown, true); + + verify(client?.getServerFeatures()).called(1); + + expect(secureStore?.interactions, 2); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(priceAPI); + }); + + test("recoverFromMnemonic using non empty seed on mainnet succeeds", + () async { + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.getBatchHistory(args: historyBatchArgs0)) + .thenAnswer((_) async => historyBatchResponse); + when(client?.getBatchHistory(args: historyBatchArgs1)) + .thenAnswer((_) async => historyBatchResponse); + + final wallet = await Hive.openBox(testWalletId); + + bool hasThrown = false; + try { + await bch?.recoverFromMnemonic( + mnemonic: TEST_MNEMONIC, + maxUnusedAddressGap: 2, + maxNumberOfIndexesToCheck: 1000, + height: 4000); + } catch (_) { + hasThrown = true; + } + expect(hasThrown, false); + + verify(client?.getServerFeatures()).called(1); + verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1); + verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); + + expect(secureStore?.interactions, 6); + expect(secureStore?.writes, 3); + expect(secureStore?.reads, 3); + expect(secureStore?.deletes, 0); + + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("fullRescan succeeds", () async { + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.getBatchHistory(args: historyBatchArgs0)) + .thenAnswer((_) async => historyBatchResponse); + when(client?.getBatchHistory(args: historyBatchArgs1)) + .thenAnswer((_) async => historyBatchResponse); + when(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash)) + .thenAnswer((realInvocation) async {}); + + final wallet = await Hive.openBox(testWalletId); + + // restore so we have something to rescan + await bch?.recoverFromMnemonic( + mnemonic: TEST_MNEMONIC, + maxUnusedAddressGap: 2, + maxNumberOfIndexesToCheck: 1000, + height: 4000); + + // fetch valid wallet data + final preReceivingAddressesP2PKH = + await wallet.get('receivingAddressesP2PKH'); + final preChangeAddressesP2PKH = await wallet.get('changeAddressesP2PKH'); + final preReceivingIndexP2PKH = await wallet.get('receivingIndexP2PKH'); + final preChangeIndexP2PKH = await wallet.get('changeIndexP2PKH'); + final preUtxoData = await wallet.get('latest_utxo_model'); + final preReceiveDerivationsStringP2PKH = await secureStore?.read( + key: "${testWalletId}_receiveDerivationsP2PKH"); + final preChangeDerivationsStringP2PKH = await secureStore?.read( + key: "${testWalletId}_changeDerivationsP2PKH"); + + // destroy the data that the rescan will fix + await wallet.put( + 'receivingAddressesP2PKH', ["some address", "some other address"]); + await wallet + .put('changeAddressesP2PKH', ["some address", "some other address"]); + + await wallet.put('receivingIndexP2PKH', 123); + await wallet.put('changeIndexP2PKH', 123); + await secureStore?.write( + key: "${testWalletId}_receiveDerivationsP2PKH", value: "{}"); + await secureStore?.write( + key: "${testWalletId}_changeDerivationsP2PKH", value: "{}"); + + bool hasThrown = false; + try { + await bch?.fullRescan(2, 1000); + } catch (_) { + hasThrown = true; + } + expect(hasThrown, false); + + // fetch wallet data again + final receivingAddressesP2PKH = + await wallet.get('receivingAddressesP2PKH'); + final changeAddressesP2PKH = await wallet.get('changeAddressesP2PKH'); + final receivingIndexP2PKH = await wallet.get('receivingIndexP2PKH'); + final changeIndexP2PKH = await wallet.get('changeIndexP2PKH'); + final utxoData = await wallet.get('latest_utxo_model'); + final receiveDerivationsStringP2PKH = await secureStore?.read( + key: "${testWalletId}_receiveDerivationsP2PKH"); + final changeDerivationsStringP2PKH = await secureStore?.read( + key: "${testWalletId}_changeDerivationsP2PKH"); + + expect(preReceivingAddressesP2PKH, receivingAddressesP2PKH); + expect(preChangeAddressesP2PKH, changeAddressesP2PKH); + expect(preReceivingIndexP2PKH, receivingIndexP2PKH); + expect(preChangeIndexP2PKH, changeIndexP2PKH); + expect(preUtxoData, utxoData); + expect(preReceiveDerivationsStringP2PKH, receiveDerivationsStringP2PKH); + expect(preChangeDerivationsStringP2PKH, changeDerivationsStringP2PKH); + + verify(client?.getServerFeatures()).called(1); + verify(client?.getBatchHistory(args: historyBatchArgs0)).called(2); + verify(client?.getBatchHistory(args: historyBatchArgs1)).called(2); + verify(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash)) + .called(1); + + expect(secureStore?.writes, 9); + expect(secureStore?.reads, 12); + expect(secureStore?.deletes, 2); + + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("fullRescan fails", () async { + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + + when(client?.getBatchHistory(args: historyBatchArgs0)) + .thenAnswer((_) async => historyBatchResponse); + when(client?.getBatchHistory(args: historyBatchArgs1)) + .thenAnswer((_) async => historyBatchResponse); + when(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash)) + .thenAnswer((realInvocation) async {}); + + final wallet = await Hive.openBox(testWalletId); + + // restore so we have something to rescan + await bch?.recoverFromMnemonic( + mnemonic: TEST_MNEMONIC, + maxUnusedAddressGap: 2, + maxNumberOfIndexesToCheck: 1000, + height: 4000); + + // fetch wallet data + final preReceivingAddressesP2PKH = + await wallet.get('receivingAddressesP2PKH'); + + final preChangeAddressesP2PKH = await wallet.get('changeAddressesP2PKH'); + final preReceivingIndexP2PKH = await wallet.get('receivingIndexP2PKH'); + final preChangeIndexP2PKH = await wallet.get('changeIndexP2PKH'); + final preUtxoData = await wallet.get('latest_utxo_model'); + final preReceiveDerivationsStringP2PKH = await secureStore?.read( + key: "${testWalletId}_receiveDerivationsP2PKH"); + final preChangeDerivationsStringP2PKH = await secureStore?.read( + key: "${testWalletId}_changeDerivationsP2PKH"); + + when(client?.getBatchHistory(args: historyBatchArgs0)) + .thenThrow(Exception("fake exception")); + + bool hasThrown = false; + try { + await bch?.fullRescan(2, 1000); + } catch (_) { + hasThrown = true; + } + expect(hasThrown, true); + + // fetch wallet data again + final receivingAddressesP2PKH = + await wallet.get('receivingAddressesP2PKH'); + + final changeAddressesP2PKH = await wallet.get('changeAddressesP2PKH'); + final receivingIndexP2PKH = await wallet.get('receivingIndexP2PKH'); + final changeIndexP2PKH = await wallet.get('changeIndexP2PKH'); + final utxoData = await wallet.get('latest_utxo_model'); + final receiveDerivationsStringP2PKH = await secureStore?.read( + key: "${testWalletId}_receiveDerivationsP2PKH"); + final changeDerivationsStringP2PKH = await secureStore?.read( + key: "${testWalletId}_changeDerivationsP2PKH"); + + expect(preReceivingAddressesP2PKH, receivingAddressesP2PKH); + expect(preChangeAddressesP2PKH, changeAddressesP2PKH); + expect(preReceivingIndexP2PKH, receivingIndexP2PKH); + expect(preChangeIndexP2PKH, changeIndexP2PKH); + expect(preUtxoData, utxoData); + expect(preReceiveDerivationsStringP2PKH, receiveDerivationsStringP2PKH); + expect(preChangeDerivationsStringP2PKH, changeDerivationsStringP2PKH); + + verify(client?.getServerFeatures()).called(1); + verify(client?.getBatchHistory(args: historyBatchArgs0)).called(2); + verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); + verify(cachedClient?.clearSharedTransactionCache(coin: Coin.bitcoincash)) + .called(1); + + expect(secureStore?.writes, 7); + expect(secureStore?.reads, 12); + expect(secureStore?.deletes, 4); + + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + // // test("fetchBuildTxData succeeds", () async { + // // when(client.getServerFeatures()).thenAnswer((_) async => { + // // "hosts": {}, + // // "pruning": null, + // // "server_version": "Unit tests", + // // "protocol_min": "1.4", + // // "protocol_max": "1.4.2", + // // "genesis_hash": GENESIS_HASH_MAINNET, + // // "hash_function": "sha256", + // // "services": [] + // // }); + // // when(client.getBatchHistory(args: historyBatchArgs0)) + // // .thenAnswer((_) async => historyBatchResponse); + // // when(client.getBatchHistory(args: historyBatchArgs1)) + // // .thenAnswer((_) async => historyBatchResponse); + // // when(cachedClient.getTransaction( + // // tx_hash: + // // "339dac760e4c9c81ed30a7fde7062785cb20712b18e108accdc39800f884fda9", + // // coinName: "bitcoincash", + // // callOutSideMainIsolate: false)) + // // .thenAnswer((_) async => tx9Raw); + // // when(cachedClient.getTransaction( + // // tx_hash: + // // "c2edf283df75cc2724320b866857a82d80266a59d69ab5a7ca12033adbffa44e", + // // coinName: "bitcoincash", + // // callOutSideMainIsolate: false)) + // // .thenAnswer((_) async => tx10Raw); + // // when(cachedClient.getTransaction( + // // tx_hash: + // // "d0c451513bee7d96cb88824d9d720e6b5b90073721b4985b439687f894c3989c", + // // coinName: "bitcoincash", + // // callOutSideMainIsolate: false)) + // // .thenAnswer((_) async => tx11Raw); + // // + // // // recover to fill data + // // await bch.recoverFromMnemonic( + // // mnemonic: TEST_MNEMONIC, + // // maxUnusedAddressGap: 2, + // // maxNumberOfIndexesToCheck: 1000, + // // height: 4000); + // // + // // // modify addresses to trigger all change code branches + // // final chg44 = + // // await secureStore.read(key: testWalletId + "_changeDerivationsP2PKH"); + // // await secureStore.write( + // // key: testWalletId + "_changeDerivationsP2PKH", + // // value: chg44.replaceFirst("1vFHF5q21GccoBwrB4zEUAs9i3Bfx797U", + // // "D5cQWPnhM3RRJVDz8wWC5jWt3PRCfg1zA6")); + // // + // // final data = await bch.fetchBuildTxData(utxoList); + // // + // // expect(data.length, 3); + // // expect( + // // data["339dac760e4c9c81ed30a7fde7062785cb20712b18e108accdc39800f884fda9"] + // // .length, + // // 2); + // // expect( + // // data["c2edf283df75cc2724320b866857a82d80266a59d69ab5a7ca12033adbffa44e"] + // // .length, + // // 3); + // // expect( + // // data["d0c451513bee7d96cb88824d9d720e6b5b90073721b4985b439687f894c3989c"] + // // .length, + // // 2); + // // expect( + // // data["339dac760e4c9c81ed30a7fde7062785cb20712b18e108accdc39800f884fda9"] + // // ["output"], + // // isA()); + // // expect( + // // data["c2edf283df75cc2724320b866857a82d80266a59d69ab5a7ca12033adbffa44e"] + // // ["output"], + // // isA()); + // // expect( + // // data["d0c451513bee7d96cb88824d9d720e6b5b90073721b4985b439687f894c3989c"] + // // ["output"], + // // isA()); + // // expect( + // // data["339dac760e4c9c81ed30a7fde7062785cb20712b18e108accdc39800f884fda9"] + // // ["keyPair"], + // // isA()); + // // expect( + // // data["c2edf283df75cc2724320b866857a82d80266a59d69ab5a7ca12033adbffa44e"] + // // ["keyPair"], + // // isA()); + // // expect( + // // data["d0c451513bee7d96cb88824d9d720e6b5b90073721b4985b439687f894c3989c"] + // // ["keyPair"], + // // isA()); + // // expect( + // // data["c2edf283df75cc2724320b866857a82d80266a59d69ab5a7ca12033adbffa44e"] + // // ["redeemScript"], + // // isA()); + // // + // // // modify addresses to trigger all receiving code branches + // // final rcv44 = await secureStore.read( + // // key: testWalletId + "_receiveDerivationsP2PKH"); + // // await secureStore.write( + // // key: testWalletId + "_receiveDerivationsP2PKH", + // // value: rcv44.replaceFirst("1RMSPixoLPuaXuhR2v4HsUMcRjLncKDaw", + // // "D5cQWPnhM3RRJVDz8wWC5jWt3PRCfg1zA6")); + // // + // // final data2 = await bch.fetchBuildTxData(utxoList); + // // + // // expect(data2.length, 3); + // // expect( + // // data2["339dac760e4c9c81ed30a7fde7062785cb20712b18e108accdc39800f884fda9"] + // // .length, + // // 2); + // // expect( + // // data2["c2edf283df75cc2724320b866857a82d80266a59d69ab5a7ca12033adbffa44e"] + // // .length, + // // 3); + // // expect( + // // data2["d0c451513bee7d96cb88824d9d720e6b5b90073721b4985b439687f894c3989c"] + // // .length, + // // 2); + // // expect( + // // data2["339dac760e4c9c81ed30a7fde7062785cb20712b18e108accdc39800f884fda9"] + // // ["output"], + // // isA()); + // // expect( + // // data2["c2edf283df75cc2724320b866857a82d80266a59d69ab5a7ca12033adbffa44e"] + // // ["output"], + // // isA()); + // // expect( + // // data2["d0c451513bee7d96cb88824d9d720e6b5b90073721b4985b439687f894c3989c"] + // // ["output"], + // // isA()); + // // expect( + // // data2["339dac760e4c9c81ed30a7fde7062785cb20712b18e108accdc39800f884fda9"] + // // ["keyPair"], + // // isA()); + // // expect( + // // data2["c2edf283df75cc2724320b866857a82d80266a59d69ab5a7ca12033adbffa44e"] + // // ["keyPair"], + // // isA()); + // // expect( + // // data2["d0c451513bee7d96cb88824d9d720e6b5b90073721b4985b439687f894c3989c"] + // // ["keyPair"], + // // isA()); + // // expect( + // // data2["c2edf283df75cc2724320b866857a82d80266a59d69ab5a7ca12033adbffa44e"] + // // ["redeemScript"], + // // isA()); + // // + // // verify(client.getServerFeatures()).called(1); + // // verify(cachedClient.getTransaction( + // // tx_hash: + // // "339dac760e4c9c81ed30a7fde7062785cb20712b18e108accdc39800f884fda9", + // // coinName: "bitcoincash", + // // callOutSideMainIsolate: false)) + // // .called(2); + // // verify(cachedClient.getTransaction( + // // tx_hash: + // // "c2edf283df75cc2724320b866857a82d80266a59d69ab5a7ca12033adbffa44e", + // // coinName: "bitcoincash", + // // callOutSideMainIsolate: false)) + // // .called(2); + // // verify(cachedClient.getTransaction( + // // tx_hash: + // // "d0c451513bee7d96cb88824d9d720e6b5b90073721b4985b439687f894c3989c", + // // coinName: "bitcoincash", + // // callOutSideMainIsolate: false)) + // // .called(2); + // // verify(client.getBatchHistory(args: historyBatchArgs0)).called(1); + // // verify(client.getBatchHistory(args: historyBatchArgs1)).called(1); + // // + // // expect(secureStore.interactions, 38); + // // expect(secureStore.writes, 13); + // // expect(secureStore.reads, 25); + // // expect(secureStore.deletes, 0); + // // + // // verifyNoMoreInteractions(client); + // // verifyNoMoreInteractions(cachedClient); + // // verifyNoMoreInteractions(priceAPI); + // // }); + + // test("fetchBuildTxData throws", () async { + // when(client?.getServerFeatures()).thenAnswer((_) async => { + // "hosts": {}, + // "pruning": null, + // "server_version": "Unit tests", + // "protocol_min": "1.4", + // "protocol_max": "1.4.2", + // "genesis_hash": GENESIS_HASH_MAINNET, + // "hash_function": "sha256", + // "services": [] + // }); + // when(client?.getBatchHistory(args: historyBatchArgs0)) + // .thenAnswer((_) async => historyBatchResponse); + // when(client?.getBatchHistory(args: historyBatchArgs1)) + // .thenAnswer((_) async => historyBatchResponse); + // when(cachedClient?.getTransaction( + // txHash: + // "2087ce09bc316877c9f10971526a2bffa3078d52ea31752639305cdcd8230703", + // coin: Coin.bitcoincash, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx9Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "ed32c967a0e86d51669ac21c2bb9bc9c50f0f55fbacdd8db21d0a986fba93bd7", + // coin: Coin.bitcoincash, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx10Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "3f0032f89ac44b281b50314cff3874c969c922839dddab77ced54e86a21c3fd4", + // coin: Coin.bitcoincash, + // callOutSideMainIsolate: false)) + // .thenThrow(Exception("some exception")); + // + // // recover to fill data + // await bch?.recoverFromMnemonic( + // mnemonic: TEST_MNEMONIC, + // maxUnusedAddressGap: 2, + // maxNumberOfIndexesToCheck: 1000, + // height: 4000); + // + // bool didThrow = false; + // try { + // await bch?.fetchBuildTxData(utxoList); + // } catch (_) { + // didThrow = true; + // } + // expect(didThrow, true); + // + // verify(client?.getServerFeatures()).called(1); + // verify(cachedClient?.getTransaction( + // txHash: + // "2087ce09bc316877c9f10971526a2bffa3078d52ea31752639305cdcd8230703", + // coin: Coin.bitcoincash, + // callOutSideMainIsolate: false)) + // .called(1); + // verify(cachedClient?.getTransaction( + // txHash: + // "ed32c967a0e86d51669ac21c2bb9bc9c50f0f55fbacdd8db21d0a986fba93bd7", + // coin: Coin.bitcoincash, + // callOutSideMainIsolate: false)) + // .called(1); + // verify(cachedClient?.getTransaction( + // txHash: + // "3f0032f89ac44b281b50314cff3874c969c922839dddab77ced54e86a21c3fd4", + // coin: Coin.bitcoincash, + // callOutSideMainIsolate: false)) + // .called(1); + // verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1); + // verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); + // + // expect(secureStore?.interactions, 14); + // expect(secureStore?.writes, 7); + // expect(secureStore?.reads, 7); + // expect(secureStore?.deletes, 0); + // + // verifyNoMoreInteractions(client); + // verifyNoMoreInteractions(cachedClient); + // verifyNoMoreInteractions(priceAPI); + // }); + + // test("build transaction succeeds", () async { + // when(client?.getServerFeatures()).thenAnswer((_) async => { + // "hosts": {}, + // "pruning": null, + // "server_version": "Unit tests", + // "protocol_min": "1.4", + // "protocol_max": "1.4.2", + // "genesis_hash": GENESIS_HASH_MAINNET, + // "hash_function": "sha256", + // "services": [] + // }); + // when(client?.getBatchHistory(args: historyBatchArgs0)) + // .thenAnswer((_) async => historyBatchResponse); + // when(client?.getBatchHistory(args: historyBatchArgs1)) + // .thenAnswer((_) async => historyBatchResponse); + // when(cachedClient?.getTransaction( + // txHash: + // "e9673acb3bfa928f92a7d5a545151a672e9613fdf972f3849e16094c1ed28268", + // coin: Coin.bitcoincash, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx9Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "fa5bfa4eb581bedb28ca96a65ee77d8e81159914b70d5b7e215994221cc02a63", + // coin: Coin.bitcoincash, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx10Raw); + // when(cachedClient?.getTransaction( + // txHash: + // "694617f0000499be2f6af5f8d1ddbcf1a70ad4710c0cee6f33a13a64bba454ed", + // coin: Coin.bitcoincash, + // callOutSideMainIsolate: false)) + // .thenAnswer((_) async => tx11Raw); + // + // // recover to fill data + // await bch?.recoverFromMnemonic( + // mnemonic: TEST_MNEMONIC, + // maxUnusedAddressGap: 2, + // maxNumberOfIndexesToCheck: 1000, + // height: 4000); + // + // // modify addresses to properly mock data to build a tx + // final rcv44 = await secureStore?.read( + // key: testWalletId + "_receiveDerivationsP2PKH"); + // await secureStore?.write( + // key: testWalletId + "_receiveDerivationsP2PKH", + // value: rcv44?.replaceFirst("1RMSPixoLPuaXuhR2v4HsUMcRjLncKDaw", + // "D5cQWPnhM3RRJVDz8wWC5jWt3PRCfg1zA6")); + // + // final data = await bch?.fetchBuildTxData(utxoList); + // + // final txData = await bch?.buildTransaction( + // utxosToUse: utxoList, + // utxoSigningData: data!, + // recipients: ["DS7cKFKdfbarMrYjFBQqEcHR5km6D51c74"], + // satoshiAmounts: [13000]); + // + // expect(txData?.length, 2); + // expect(txData?["hex"], isA()); + // expect(txData?["vSize"], isA()); + // + // verify(client?.getServerFeatures()).called(1); + // verify(cachedClient?.getTransaction( + // txHash: + // "d3054c63fe8cfafcbf67064ec66b9fbe1ac293860b5d6ffaddd39546658b72de", + // coin: Coin.bitcoincash, + // callOutSideMainIsolate: false)) + // .called(1); + // verify(cachedClient?.getTransaction( + // txHash: + // "fa5bfa4eb581bedb28ca96a65ee77d8e81159914b70d5b7e215994221cc02a63", + // coin: Coin.bitcoincash, + // callOutSideMainIsolate: false)) + // .called(1); + // verify(cachedClient?.getTransaction( + // txHash: + // "694617f0000499be2f6af5f8d1ddbcf1a70ad4710c0cee6f33a13a64bba454ed", + // coin: Coin.bitcoincash, + // callOutSideMainIsolate: false)) + // .called(1); + // verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1); + // verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); + // + // expect(secureStore?.interactions, 26); + // expect(secureStore?.writes, 10); + // expect(secureStore?.reads, 16); + // expect(secureStore?.deletes, 0); + // + // verifyNoMoreInteractions(client); + // verifyNoMoreInteractions(cachedClient); + // verifyNoMoreInteractions(priceAPI); + // }); + + test("confirmSend error 1", () async { + bool didThrow = false; + try { + await bch?.confirmSend(txData: 1); + } catch (_) { + didThrow = true; + } + + expect(didThrow, true); + + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("confirmSend error 2", () async { + bool didThrow = false; + try { + await bch?.confirmSend(txData: 2); + } catch (_) { + didThrow = true; + } + + expect(didThrow, true); + + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("confirmSend some other error code", () async { + bool didThrow = false; + try { + await bch?.confirmSend(txData: 42); + } catch (_) { + didThrow = true; + } + + expect(didThrow, true); + + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("confirmSend no hex", () async { + bool didThrow = false; + try { + await bch?.confirmSend(txData: {"some": "strange map"}); + } catch (_) { + didThrow = true; + } + + expect(didThrow, true); + + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("confirmSend fails due to vSize being greater than fee", () async { + bool didThrow = false; + try { + await bch + ?.confirmSend(txData: {"hex": "a string", "fee": 1, "vSize": 10}); + } catch (_) { + didThrow = true; + } + + expect(didThrow, true); + + verify(client?.broadcastTransaction( + rawTx: "a string", requestID: anyNamed("requestID"))) + .called(1); + + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("confirmSend fails when broadcast transactions throws", () async { + when(client?.broadcastTransaction( + rawTx: "a string", requestID: anyNamed("requestID"))) + .thenThrow(Exception("some exception")); + + bool didThrow = false; + try { + await bch + ?.confirmSend(txData: {"hex": "a string", "fee": 10, "vSize": 10}); + } catch (_) { + didThrow = true; + } + + expect(didThrow, true); + + verify(client?.broadcastTransaction( + rawTx: "a string", requestID: anyNamed("requestID"))) + .called(1); + + expect(secureStore?.interactions, 0); + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("refresh wallet mutex locked", () async { + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.getBatchHistory(args: historyBatchArgs0)) + .thenAnswer((_) async => historyBatchResponse); + when(client?.getBatchHistory(args: historyBatchArgs1)) + .thenAnswer((_) async => historyBatchResponse); + + final wallet = await Hive.openBox(testWalletId); + + // recover to fill data + await bch?.recoverFromMnemonic( + mnemonic: TEST_MNEMONIC, + maxUnusedAddressGap: 2, + maxNumberOfIndexesToCheck: 1000, + height: 4000); + + bch?.refreshMutex = true; + + await bch?.refresh(); + + verify(client?.getServerFeatures()).called(1); + verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1); + verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); + + expect(secureStore?.interactions, 6); + expect(secureStore?.writes, 3); + expect(secureStore?.reads, 3); + expect(secureStore?.deletes, 0); + + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + test("refresh wallet throws", () async { + when(client?.getBlockHeadTip()).thenThrow(Exception("some exception")); + when(client?.getServerFeatures()).thenAnswer((_) async => { + "hosts": {}, + "pruning": null, + "server_version": "Unit tests", + "protocol_min": "1.4", + "protocol_max": "1.4.2", + "genesis_hash": GENESIS_HASH_MAINNET, + "hash_function": "sha256", + "services": [] + }); + when(client?.getBatchHistory(args: historyBatchArgs0)) + .thenAnswer((_) async => historyBatchResponse); + when(client?.getBatchHistory(args: historyBatchArgs1)) + .thenAnswer((_) async => historyBatchResponse); + when(client?.getHistory(scripthash: anyNamed("scripthash"))) + .thenThrow(Exception("some exception")); + + final wallet = await Hive.openBox(testWalletId); + + // recover to fill data + await bch?.recoverFromMnemonic( + mnemonic: TEST_MNEMONIC, + maxUnusedAddressGap: 2, + maxNumberOfIndexesToCheck: 1000, + height: 4000); + + await bch?.refresh(); + + verify(client?.getServerFeatures()).called(1); + verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1); + verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); + verify(client?.getBlockHeadTip()).called(1); + verify(client?.getHistory(scripthash: anyNamed("scripthash"))).called(1); + + expect(secureStore?.interactions, 6); + expect(secureStore?.writes, 3); + expect(secureStore?.reads, 3); + expect(secureStore?.deletes, 0); + + verifyNoMoreInteractions(client); + verifyNoMoreInteractions(cachedClient); + verifyNoMoreInteractions(tracker); + verifyNoMoreInteractions(priceAPI); + }); + + // test("refresh wallet normally", () async { + // when(client?.getBlockHeadTip()).thenAnswer((realInvocation) async => + // {"height": 520481, "hex": "some block hex"}); + // when(client?.getServerFeatures()).thenAnswer((_) async => { + // "hosts": {}, + // "pruning": null, + // "server_version": "Unit tests", + // "protocol_min": "1.4", + // "protocol_max": "1.4.2", + // "genesis_hash": GENESIS_HASH_MAINNET, + // "hash_function": "sha256", + // "services": [] + // }); + // when(client?.getBatchHistory(args: historyBatchArgs0)) + // .thenAnswer((_) async => historyBatchResponse); + // when(client?.getBatchHistory(args: historyBatchArgs1)) + // .thenAnswer((_) async => historyBatchResponse); + // when(client?.getHistory(scripthash: anyNamed("scripthash"))) + // .thenAnswer((_) async => []); + // when(client?.estimateFee(blocks: anyNamed("blocks"))) + // .thenAnswer((_) async => Decimal.one); + // // when(priceAPI?.getPricesAnd24hChange(baseCurrency: "USD")) + // // .thenAnswer((_) async => Decimal.one); + // + // await Hive.openBox(testWalletId); + // await Hive.openBox(DB.boxNamePrefs); + // + // // recover to fill data + // await bch?.recoverFromMnemonic( + // mnemonic: TEST_MNEMONIC, + // maxUnusedAddressGap: 2, + // maxNumberOfIndexesToCheck: 1000, + // height: 4000); + // + // when(client?.getBatchHistory(args: anyNamed("args"))) + // .thenAnswer((_) async => {}); + // when(client?.getBatchUTXOs(args: anyNamed("args"))) + // .thenAnswer((_) async => emptyHistoryBatchResponse); + // + // await bch?.refresh(); + // + // verify(client?.getServerFeatures()).called(1); + // verify(client?.getBatchHistory(args: historyBatchArgs0)).called(1); + // verify(client?.getBatchHistory(args: historyBatchArgs1)).called(1); + // verify(client?.getBatchHistory(args: anyNamed("args"))).called(1); + // verify(client?.getBatchUTXOs(args: anyNamed("args"))).called(1); + // verify(client?.getHistory(scripthash: anyNamed("scripthash"))).called(2); + // verify(client?.estimateFee(blocks: anyNamed("blocks"))).called(3); + // verify(client?.getBlockHeadTip()).called(1); + // // verify(priceAPI?.getPricesAnd24hChange(baseCurrency: "USD")).called(2); + // + // expect(secureStore?.interactions, 6); + // expect(secureStore?.writes, 2); + // expect(secureStore?.reads, 2); + // expect(secureStore?.deletes, 0); + // + // verifyNoMoreInteractions(client); + // verifyNoMoreInteractions(cachedClient); + // verifyNoMoreInteractions(priceAPI); + // }); + }); + + tearDown(() async { + await tearDownTestHive(); + }); +} diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart new file mode 100644 index 000000000..e69de29bb diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test_parameters.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test_parameters.dart new file mode 100644 index 000000000..3fbfbdaaa --- /dev/null +++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test_parameters.dart @@ -0,0 +1,14 @@ +const TEST_MNEMONIC = + "orbit claim toss supreme sweet kit puppy gown lounge letter illness planet"; + +const ROOT_WIF = "KxpP3c45bRPbPzecYfistA5u3Z4SSGCCiCS4pjWrS5LF1g4mXC66"; +const NODE_WIF_44 = "KyaVkL3X4jUdq16CBrTR72VyQkLuczNyi9v6ztwZKdTm3dt7x57o"; + +const ISOLATE_DERIVE_EXPECTED_TESTNET = + "{receive: {0: {p2pkh: {publicKey: 02846b24e2489b571e1eacae66dad5144f0194fa97fd33f9969674e6c031718191, wif: cVtvaWqNU1rzTwydotGXCwyxTB3x1KWTH67wu3xDoZT86WNQmBid, address: mpMk94ETazqonHutyC1v6ajshgtP8oiFKU}, p2sh: {publicKey: 03ef135d7987f25e5f904b5a7f1e9dcb3d4b787ae5b315afea51314e23b7ca7c54, wif: cUtApy1f3uon5zmauEGPMiXEX6no1p4tnHKR796VV5aQdo1ECzRh, address: 2N3GrCAFdpgJ4pJLepapKqiSmNwDYLkrU8W}, p2wpkh: {publicKey: 03f7a172264d89eb8c706bb887d411430fa8111f07348b537131ce6d83109e2f46, wif: cU1E2J1eHbQh36TCtsqneAsKaXRwRhSs74GEDPXWCGY7f1xpsymM, address: tb1qnf2qmetsr53tezq8qwspzdjnxplmjny4n5pxz3}}, 1: {p2pkh: {publicKey: 02057e72d0dc2b448b846a96a88b2ce9cfb9b9b0657a9634e7112cf080aabe3473, wif: cQNo7vPrfJ7qEPCKoSe7T1iST117Lm8dSJUvYwuC9vQpZ2zwbgv6, address: mpaW4y1dv42R9RTHgPQv1XSqJfYw52NJYy}, p2sh: {publicKey: 03027202d42383a043f1a70f1e8fc634391e08e097f66fabb88288e59f48e70a38, wif: cUnEnjizxjEgXgJMxR1SPxQBXC3mRBcQ9bEoY9ApxSD8ihVcQceh, address: 2Mvi3i2QYkrRrQd22WW4brHVtF2zAhdVwi3}, p2wpkh: {publicKey: 02bfbf552a8d5bb4bca1284a138119719a1a92b22aecef7e3967d5c3208ad5f152, wif: cPa85quZsdsXk17BP3pq2CuWKDp93JquL71tQgKYA27B2grQcic9, address: tb1qc6krkzn284rv2ugch2p9te0xw7egq4jk8gzqe5}}}, change: {0: {p2pkh: {publicKey: 03068667e3c60e6e77470a30724f0641b44d20e333c045a49a8c79ce8d453fc10b, wif: cQPpPV8136qx1KzYVSPmgY7CtJdV1QNU2bg9gAhn8E76Z23avf1i, address: mup6rf8QxcVQgUMQoGxHj8wQxskhrA4QiN}, p2sh: {publicKey: 02c9977033bac46cfd3847be81ec392582a10cb924efdfe433c7d35ffb3066c334, wif: cUtApy1f3uon5zmauEGPMiXEX6no1p4tnHKR796VV5aQdo1ECzRh, address: 2N4iiKohmeKYtiexoj3p6cshEY3DKdbaK9G}, p2wpkh: {publicKey: 030d81edda8fb383fffc8c2654e82b68dd6d074c6e97324de2f20a4c8eb73d9d79, wif: cQAZ6KVEnpDMfcgDx9M4mZYtknSUYRrCKbREfEYvdQus5hfuPKGr, address: tb1qhndp7nnlamv3w9sqjhz7tdlk2es0nyaj0dwnsh}}, 1: {p2pkh: {publicKey: 0354205a454c3a20813069bda67f7be96748a2a88550070697c0d61568212481cf, wif: cV3fSc57dkYmRvDQtAFJBSDJGMosGPYEyV4GbhP2AMw8A8YxgUyT, address: n24iGgnpskxApuVRzJ72q85ALQxPjBr8iW}, p2sh: {publicKey: 02309f858514e761c88153c9af3d44b70b5e8d06e76afcb73203da101e252fb1ce, wif: cUnEnjizxjEgXgJMxR1SPxQBXC3mRBcQ9bEoY9ApxSD8ihVcQceh, address: 2MzB56pivdE59u5mG9dcrno8UBVEHjpx8Md}, p2wpkh: {publicKey: 03b9d6f01c3303073a51992f4eaeb9be2db46f2696eb8bc336b4459959a4e63ad1, wif: cSss3AT1v5KyFNXbqQo9qFCLCmKPX2eJnBoQe2Hk9jzZFzMz5MdG, address: tb1qh45hl46hvnafr6hkcs6a5xgtkukjuh6v4cnssv}}}}"; + +const FILL_ADDRESSES_EXPECTED_CHANGE_MAINNET = + "{0: {p2pkh: {publicKey: 02a1a969c63ed41662a23afc640f76ee4a53c35fba4a13ff871931849abdc0670c, wif: Kws4oRj4Z3uT4WNejbuLsWvqTeso4dGciVu75jjd5fa36Tst48ER, address: 1JfZd6cSNr924p4ZwewG1CeRw7AqoYQ6uE}, p2sh: {publicKey: 020cebf05d41da01c00fbb7f7c04cf85741188da0e5ee22ae9fac6e7b5098b8cac, wif: L3jFGqrCRMENcCofASf8m6vMNfYutxdqLe733NwEyXiKTBkkgqyg, address: 3ANTVqufTH1tLAuoQHhng8jndRsA9hcNy7}, p2wpkh: {publicKey: 0301def02c073852fc8c28182749be431ac22a2699b51c896fbc48457107c10c65, wif: L3UwhkWiXSAyCWYVjaFCyMhGcqeDU8soCmqhuFYFadcVQepKKcjy, address: bc1qwt76574cgnhjv0nx4f52qylyla0t50d60znk5u}}, 1: {p2pkh: {publicKey: 02617b5f7868bd0402a3e3ff6fa224aede55f13218bbef9987467455d068d629cd, wif: KzDwZXPyNhPix2nV5wri4QaGj6Tge7znvf49D5tgL7EvAnYV6Pas, address: 1vFHF5q21GccoBwrB4zEUAs9i3Bfx797U}, p2sh: {publicKey: 03b4c1e17b7257850fd2c0cf69acd397616835de29867cfe047bf1064b9803f773, wif: L1v4hFFe8EvUX7DBVxnfh7Y22A8nNwh7py42vfr5TU1yAAa9Eadb, address: 3LNBen8sNa6kXsWuMc6tynHBQr3vUHn3nL}, p2wpkh: {publicKey: 038b646c426ed75204bd92f55f0519fb89c41a503844aecf187a55eb00a5d8b5eb, wif: L1jQHTyFP4sNyqdKeooJzw3AUghPeSmGoW7UmZwDsS1Js4UxiGyh, address: bc1qn2x7h96kufgfjxtkhsnq03jqwqde8zasffqvd2}}, 2: {p2pkh: {publicKey: 031643235b0355ac366ade3ec125e466be42602a6167ba1cc68f39c38929f3c785, wif: KzqPH523RyAKwzRDg8PqjvNVDV8Fex2qrKxwwLGcvc9XZHfvaErb, address: 1EwEMkfeivF8nEkG3tWhBSqibnDjoREBoF}, p2sh: {publicKey: 02312b44be7de07c21bed9bd8b0c2f3d64be41c5f5120a463fcb85371b3f44cce1, wif: KxxRzHcF6QkApcLtbyxeyQrHgnstCqCPPfLiLfJhee9PVinisekA, address: 3MPyLcCkGPKyZULKSzkYDZQxxMmG8HNRPi}, p2wpkh: {publicKey: 031a10a60de8563b1be55e8274538d6ec6375d19764e81303999de2605634ea15a, wif: L2u4AYxEKkDamcXjAfXviuTPuRuWe1aN9zXEX1PSpzrmqGtSHQqe, address: bc1qpcn5wd2cx7syc28r0t4w4ym8yy6fck87nrxn4p}}, 3: {p2pkh: {publicKey: 02f552c7b15e90df9ff99f35e8b5bd84eff0bdef6cb6c75e13d1df81d334c6b786, wif: Kxi7qVxEqwaBhR3tuewpfi8EDqqR7fBzgQUDambVWGPEP3oG9JUM, address: 1MifgAa6CzqmTF4euVSD2DivD3xUGDbuA5}, p2sh: {publicKey: 02a7ba8279be4c182292b855cbf4349dba68f8a776b9b8e04e05585ac9f605e7f1, wif: L3qZiaviwh76RvKj5i69vu75upS3E62qmEk6BSJRgSVjw7FmJNDW, address: 34pa7nXRZ3XahoFKhhnaLy4DqzfC9v5aSm}, p2wpkh: {publicKey: 03d712c240ccd578b8fb59acf88a8fbacf2ab14301a900e7907c739244e61029bd, wif: L3ezWHMUvdwprhChDVn7iVV8otpLUBrdkZB7X97GEbiVZbxJkDPc, address: bc1qemkha74vvmlz8yg56tesswpz77wg07m9wu23sc}}, 4: {p2pkh: {publicKey: 03d86c453c6b8ef6239db8fc270c76a9b08faf2c58f3de74cbe2cb0bc0cef7139a, wif: KzNpx8vgcNbYcqPZxHFwvKSRwPpyZNhmF4Eqa4k1wuWJZovwaXNC, address: 1BxYVw7u85QWVoVCHJAJkCCZZjWeXYW6EA}, p2sh: {publicKey: 020e9095a31b9c1e580b3773d34d1f752f9c4de42feb1c3480f5234a2392762fbc, wif: Ky6NQbHkhBLS3LDLmCuu3TFBVU1HNah7TYUiLhmc3u8HdZgpKYSs, address: 33tciSXesiShRULW4bds5BE8358GsJc8CA}, p2wpkh: {publicKey: 02908673d298d4929a724ff9627c3fc710e27f0d727fbb0f2741c00dac1d792120, wif: L5QYEMxjY42c9JnpEQCDUbqCUfZ1vKoELe41rREuGzszcZgzVepx, address: bc1qpl7rh3ykw5h9823wv3uw0jrehlty6dfjp65ykt}}, 5: {p2pkh: {publicKey: 0368fda0552db99cfac045f57327cecd9b365d8813982dda051f1156ceefacd80b, wif: Ky8KYn2vMmWiMw6QEnE6JsM3uwQgAZBjiUHB938MVtnSgpiDjh7o, address: 14g637PwocgKr3S949WDitY7Bj3L1Bttcb}, p2sh: {publicKey: 03a1c4977ec9e9e02ba011cf56cee34c1617a7e05e85183a4207efd6425079a914, wif: KzDtpdJFLQWLSRdiEzhrqE8rzDaRi43tkxJ6K9ANeGcExQMNWYLz, address: 34Z5gAgPiUsfA9VHdAss2AD5h5Xk5TEp9K}, p2wpkh: {publicKey: 028c44701f2e918ba9853737aa1c6c7b5302a4c9198bf0eb22a75fb6fd3ef4dc9e, wif: Kx7wWb9xvNTaiWkzEmLqJ7gsQEaD6VPJTodr71rQwtpCU5dZDbEP, address: bc1q0ja83w4jwplrxjggcy8ltnrz70qrhnsmfwjv47}}, 6: {p2pkh: {publicKey: 03844bb44c430540dd2fd42630200a059f06480e024b7a06ea628b5094f48b944f, wif: Kwe6hMa7t9qcWW7fHBFTpBDDyzBdWzkHjhngiTLRKZzBjUqqppRJ, address: 1JNghjiaNWrWgvAJnmGyyFEbQMWV35QT1D}, p2sh: {publicKey: 03add39947c251a1f42f2fe4dbf41ea6dfed2bcf56bbe5ab6c44213235b68a1d0a, wif: L27TRwwmSB98trgkBduvx1yKvmYbu77ffcF6BQKADfD94vNwvW4W, address: 3AnduCZuFcXFtBjnz7Y6vRJBwYvfeNKJtR}, p2wpkh: {publicKey: 02883642dad55a3f5003440ff7e066c97624539841643e900db80eaac7ebab7270, wif: L4sisqYU1xSzbnx25xuyLefifGL5BoGDXh5Vsex9UCBSDHhFYt8h, address: bc1qdjjssjd6vl6e3egqts7qxcj6dqrs6krgj4dv3q}}, 7: {p2pkh: {publicKey: 03487700edb11cf39b095b17da1f44f702398bd707dfdace4d88ee0227a48c8a0c, wif: L3UmMi9h8RQ8Y8jKATFjum77kc9ng6Jr71fq1H9rGxxdspKGXt12, address: 1Q1FMnBJxQ5uh2UDQbvwQ1y1KMpqVd3whq}, p2sh: {publicKey: 03a600d4880ce8a53287f25b6534f97a689ba7006f665ad1fe3e2bb8d3c9620ec5, wif: KwDwKEifSPJeQKTFonmyBTvCNuApuT9y3s7PqmnFkZBFkxSaQ6BQ, address: 3J9GqZ2b5raBNyGmuBg8ttyg5x8zaqSrMp}, p2wpkh: {publicKey: 035b91a2c439d6cc34a706449b8d9843721cc499aec4b38ebdd211978a52431fc0, wif: KzJZE96Hjwn2dtuYpBgMoR9s86TgQ3apRsNTxGZTpyW2RVA6HppV, address: bc1qs2df496wpp4339qjuypc2l2r6e0z7vndz70ac7}}, 8: {p2pkh: {publicKey: 0254ff6bad342ae9af2e04ee9d876682771ad86a76336a817eadb2e4e5bf68070a, wif: KxhFsZNv8XDUxLECR9y965eWFSGBbc2FrTkRvuyRPwPM9xxeCfV4, address: 1JD8uzAKQo9DgR2om6gS98S92cgqscZ3Ur}, p2sh: {publicKey: 02f574d6a16300e4d497647814fd2b0fa2eaba32af19fcf65821f70743bc566f9d, wif: KypeLKRPCoN9eZQ8awgBca47JyD6scST44Pg4woLpDiyT3hy9wZA, address: 3BqGdLjubq2vAGRDNRkxk5uMqd6FPoMg7N}, p2wpkh: {publicKey: 0227cb798c29365364027e5df67f6890985fd89ecbca571e51bb6260272cc66ec1, wif: Kxrpxu5kNAdy9jqz7etcCg716gsEk1K5weiMLKg1fhLPdxitvzsy, address: bc1qhpvcc08dxa7m5ztkxsfsplmj69yzsg6p3dna63}}, 9: {p2pkh: {publicKey: 02b8b1a447c71bb4ed82fd3719ec9e665df5c9c6e31c7a14beb56c65f355a08bc4, wif: Ky9kWxSwqBQP9ShkZNCfLwDqpzqnDEvQG3NjfYY3A3VFE4nPLqrs, address: 16EpYJQoM1K2ZKFUEMBAJubiNsMghkvBUx}, p2sh: {publicKey: 03f6cc36b17f382490d1a08bc9f7c28302c704c69cb6c153d2828710cd93a1c215, wif: L1zutoVai5EqS2LoAaEq16R2rcooiP6HAdA5zETwbvuYBky3neKw, address: 3HBjEYyPH9H8JvuVbibNaZ2bJyD8564r1Y}, p2wpkh: {publicKey: 030f021f31d9eac4279f8ae12a512885769978dc93a74e0e4c91eba994a7d02cda, wif: L26bxcZZ8PLaa23X9myLgzh3hAYxjQ9MsSfiz49yiEdys7dzr66z, address: bc1q6hxsggrtcrvcdxpzu7e8qv2m9md3zaghjjsxut}}}"; + +const FILL_ADDRESSES_EXPECTED_RECEIVING_MAINNET = + "{0: {p2pkh: {publicKey: 0359bc5f4918d68ab3730886c4fdebec1cfdeba9db1170582da7072183d7afce99, wif: KyaVkL3X4jUdq16CBrTR72VyQkLuczNyi9v6ztwZKdTm3dt7x57o, address: 1GDtrDP62zQETQESHt48Z82afXWcvX8qNv}, p2sh: {publicKey: 02addc76ef5845c0e74e5ada1d97568d0ee76856031e60a084f6f6a0e7be51d84b, wif: L3jFGqrCRMENcCofASf8m6vMNfYutxdqLe733NwEyXiKTBkkgqyg, address: 3AV74rKfibWmvX34F99yEvUcG4LLQ9jZZk}, p2wpkh: {publicKey: 02e5b585efaec9e6486f4b8afb3415ffd71a89566c1f84bb5331c4cddc905b7555, wif: KzCvDQSH6qqUFhPnbM42zbLK3qPeHXKVVpc6A5bAqADanHQFqypQ, address: bc1qz36w7sv4lnt09saurf94lwk5tc6qsyhky9yfgm}}, 1: {p2pkh: {publicKey: 036070efb466bfbf689efe1e7a27fa405bdbb16fa4c836f7b71feeb7ec9f5c5db4, wif: L3aA8PRqcj1iuZnQMJ3M5x68zhywgwgGbzPtDsQMBWRmqUaKyyBQ, address: 1RMSPixoLPuaXuhR2v4HsUMcRjLncKDaw}, p2sh: {publicKey: 02b8f46d7741d709bc1dc81386edaf4e6dad8b78b1fb9ec0c5b1f8e08e7d72f395, wif: L1v4hFFe8EvUX7DBVxnfh7Y22A8nNwh7py42vfr5TU1yAAa9Eadb, address: 3Ggn4xZmXjMCDUdQSTjxTi1PdVrtDGUy5Z}, p2wpkh: {publicKey: 03627f4374d7c992c40d743786028f94b1e1ca354b94ffa776b51ba50c80fba1d7, wif: L5gAb3ABSYTBTL85FhoRxHa7dJMtz9sVLHWkEY7kYKXT2cDg71Ym, address: bc1qggtj4ka8jsaj44hhd5mpamx7mp34m2d3w7k0m0}}, 2: {p2pkh: {publicKey: 03f2171f073a8fbf5b844a20e5b6ae356a07e9e6dc5af24cd4b3e54a1599eb4137, wif: L27AJt6ZRU4D3sf7Ls1HLq2ruF8c6iYq9iJVvW8Xm2kMKrKcPwzZ, address: 1Mu5SqaUBHB1HkyvEtjHjrNQVaai2MoFFz}, p2sh: {publicKey: 024e6d7230df59dc28f94ab7bd45c5aed53ac0ea96e8a1ee46edcca5594fa3ec66, wif: KxxRzHcF6QkApcLtbyxeyQrHgnstCqCPPfLiLfJhee9PVinisekA, address: 3K8CQxXWp2kjbGcnub4sh935H5s1AfrFmp}, p2wpkh: {publicKey: 0365b55bdae2d0ada31bfc73371f7106e0e20563dff0763c48da8ce2ca70346bd8, wif: KxttkPfRdY9uwEqgHGPo9d7Bb3qTsBzHSgmv8EVTS2Gbh88GgJZQ, address: bc1qsegc09enu2ts4dg7lnxee6tv8fy78m89cfzdy9}}, 3: {p2pkh: {publicKey: 020d00dd73194f8f087a3740594f2eeaa545224fb634462e06d281ad5759e77cbd, wif: L5Mdvj7tkY4Sx5JTiB1WtQJPogqXGLunaFAubAQMvuAK3TjuXXxD, address: 16d7AeqhmspaMyeJKF3cDwxjkLUTFZQdTn}, p2sh: {publicKey: 038d2aec8c0da1bafc3e51fe7fdd3aa60f121983071d97ed754c05f24c54d7d09b, wif: L3qZiaviwh76RvKj5i69vu75upS3E62qmEk6BSJRgSVjw7FmJNDW, address: 3QwDpsqwb5VfKQVUVLzaDwgC51pea1ymHr}, p2wpkh: {publicKey: 02f144cd8c1d6966db09da86bf662933480ad6e7f2862f7878780f21bc1448d563, wif: Ky9zeEcFB7td3dPYCiXxrMPCQkKyfm4feaWp5PAWxY7kBwCccUxz, address: bc1q3h5llpmhvr89el03dktd936jqsn7t6pytr2nlr}}, 4: {p2pkh: {publicKey: 038d6142ee0db16d4ff23c95d1c157428d48e11fae7752ddacaf6cccce6db61fc6, wif: Ky41iFhmo2Y5mYp1UALsYqRhhKajEy7AxLJcSDYRVdwW7iv3vmTK, address: 1EFyHH7G4Hk8aCjGWPer1Qc9e8iZsbfZC8}, p2sh: {publicKey: 03a1624a73009c17ceefe299ca998ee941b501692b2f3a032e037b50726415c78b, wif: Ky6NQbHkhBLS3LDLmCuu3TFBVU1HNah7TYUiLhmc3u8HdZgpKYSs, address: 38YQK65m9A278nCbWKTx3EJtyK9Vega1Z9}, p2wpkh: {publicKey: 031e816e4a35c686ee30387e01c26341927806674986a57ee5755114f3ee59d560, wif: L5AiWbctHW9EyaD5vyzCrxKmKppdMwdRFTvB1TUKLWvibo5R3QXa, address: bc1qj69ku48uu6lqu6uhd62a37zvuwta2dlc28frxc}}, 5: {p2pkh: {publicKey: 024697dbd5ad644c285fb9ce25a38d0f8b48de9dfbda146eba8f5659184fb2779c, wif: L3yze1iu58vmF7GyoUHqnmYCm4qLsBoGiyRgBPbt68gB3kKnQfCv, address: 16ZbDHYV97o6xeXoQMWus1a8NMNyxqHZon}, p2sh: {publicKey: 021b442ef944676b70e6ef23ecb932c015b6934ff5d094db88820735be36f6d807, wif: KzDtpdJFLQWLSRdiEzhrqE8rzDaRi43tkxJ6K9ANeGcExQMNWYLz, address: 3LFx71JddSzs8qE51P4JHHjxsgiSTZdk4z}, p2wpkh: {publicKey: 0307ffe6b1c0dfca40b6126140691a4d907a053dcfd97b816cc7ff86775486e612, wif: L3F1KPjtaA4uyfcmMSH2sFWs2TW2aX6Lcn8vetrdqtwgKgvfvVGg, address: bc1ql66zvg82lk425g8j4jx5flt255n8a9up328z3l}}, 6: {p2pkh: {publicKey: 02a5087e407ad853720a7010c1870bbc35a9ee09d90777c617801c983aaccc8523, wif: L1fLMxyhSKSsLskB3iBcfbfCinVr6MRE9YYVKXfCbLjPLZLAUpb7, address: 1FzukoiU7vXb7invLNLCCLAFdfK2gmP45A}, p2sh: {publicKey: 02d4f8bc88178a215b5c95e079b7c1ff0b62ec2884d5ffa71122683557a16615f3, wif: L27TRwwmSB98trgkBduvx1yKvmYbu77ffcF6BQKADfD94vNwvW4W, address: 3GpAXutnaxCYuV2MSgSiXQTSafE7Aouifs}, p2wpkh: {publicKey: 03f7eb3138cbaa7baabdef7b903ff1a3369a8d7937c15ae17dac7084aa4cfd8afe, wif: KyWW73wu11xVnmFKMzq9AuxQ3TXw2KjwCzxUa9WbYx2Ee5oh2Nk1, address: bc1q4ev5cas22cn8rna3a7je238p3plgqqdjv9xt0e}}, 7: {p2pkh: {publicKey: 0366efa2d1624fd9ff0d9feffa39ff47c10ef196fe209421dcebf5d07dcb8907ce, wif: KwxWpA4scQ7RVKDFKjXvKWn6PdVXpr6nzW9T6ju6VP3MmjBRb5eK, address: 13qhwGjBzshL724ZZNv2C2XmUNpFoDLx4Z}, p2sh: {publicKey: 03b08cabbcaa97c20bf30e0830c8c7a2361ba63d1ba987032ee7cd97d666b62692, wif: KwDwKEifSPJeQKTFonmyBTvCNuApuT9y3s7PqmnFkZBFkxSaQ6BQ, address: 39ZZhvQJGwohf2ndBGXYWW31t1E91j9wcB}, p2wpkh: {publicKey: 03a353139ce07e31b33f1c5b0ece6f08ac117339a1a56aa1b3af011216cf2cbf88, wif: KwL9LaYjNvwWiYgDiUBLnVW7W5j2FyWqmzrioTA2QRgwdz6bUTQH, address: bc1q96wmh0qc2lwauzxv7la206d03zysc9zfw3ajkd}}, 8: {p2pkh: {publicKey: 032234e3903ebcd72c081119fe4b4c2d98e3fd3940b5b6cd7737f5f4d3240dcb7d, wif: L5kwyvViXwBcFqzJL5cffcJR7S1vEHxHuKHAQrAq6FtknvJG4Cx3, address: 1LPGD9sExsBMTLGxnTTEDYBHrtRSZCKNrN}, p2sh: {publicKey: 02c1ca19626e4784b2ce19b68d2887e4c9c733176db189e536b71a79c07178b4af, wif: KypeLKRPCoN9eZQ8awgBca47JyD6scST44Pg4woLpDiyT3hy9wZA, address: 3FXRAzFAgVMDcqbv6WE9Ki7yBACrRAh2Wn}, p2wpkh: {publicKey: 020fd4e2cd43f98366dd60fcc8902564c532c9396c35ebb840b63c965deed16330, wif: L4EgRsvLsju7uVXsTEchYnGdwmFrxhbE9SkMuvnaMDSMxmopNg8C, address: bc1q354ttmgwjzjf7jmym2aw9p5geeq9lhk8vcffap}}, 9: {p2pkh: {publicKey: 03dd5e2f3b828bdc2653ce7a7ce34ebfa8118077b647bdf4922c5d15f4546dc419, wif: Ky4f8LEYkXMkLiYX4t2PR6V2vJigyCoYTYATu4B5pnjDDywUD2U7, address: 13GXUQDr91Z5prRxAQQFHUvKNqs2hEWrkJ}, p2sh: {publicKey: 034a4cf3a57083ade346ecaab24dc931e2a991107c7c42cf170d1c6e3b84560e68, wif: L1zutoVai5EqS2LoAaEq16R2rcooiP6HAdA5zETwbvuYBky3neKw, address: 3FstRy5yCE7a3wCNS8SgFKi4SF3zWK8vB6}, p2wpkh: {publicKey: 020cb048fc44a2db09be875ccd938634c557b19e2062fbc55372783be1116737e7, wif: KyDq3LHf9NkUWChPxVEAV3dQkX89GJWUkSw8cSVLooXronEwKouy, address: bc1qn99xewnyhqcleyj03f2y0crdhqmxhm5cmextw8}}}";