2022-11-30 14:05:56 +00:00
import ' package:decimal/decimal.dart ' ;
2022-11-29 17:25:39 +00:00
import ' package:flutter_test/flutter_test.dart ' ;
2022-11-30 13:06:31 +00:00
import ' package:hive/hive.dart ' ;
import ' package:hive_test/hive_test.dart ' ;
2022-11-29 17:25:39 +00:00
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 ' ;
2022-11-30 13:06:31 +00:00
import ' package:stackwallet/models/models.dart ' ;
2022-11-29 17:25:39 +00:00
import ' package:stackwallet/services/coins/particl/particl_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 ' ;
2022-11-30 14:05:56 +00:00
import ' package:tuple/tuple.dart ' ;
2022-11-29 17:25:39 +00:00
2022-11-30 13:06:31 +00:00
import ' particl_history_sample_data.dart ' ;
2022-12-11 11:48:24 +00:00
import ' particl_transaction_data_samples.dart ' ;
import ' particl_utxo_sample_data.dart ' ;
2022-11-29 17:25:39 +00:00
import ' particl_wallet_test.mocks.dart ' ;
import ' particl_wallet_test_parameters.dart ' ;
@ GenerateMocks (
[ ElectrumX , CachedElectrumX , PriceAPI , TransactionNotificationTracker ] )
void main ( ) {
group ( " particl constants " , ( ) {
test ( " particl minimum confirmations " , ( ) async {
2022-11-29 21:27:32 +00:00
expect ( MINIMUM_CONFIRMATIONS ,
1 ) ; // TODO confirm particl minimum confirmations
2022-11-29 17:25:39 +00:00
} ) ;
test ( " particl dust limit " , ( ) async {
2022-11-29 21:27:32 +00:00
expect ( DUST_LIMIT , 294 ) ; // TODO confirm particl dust limit
2022-11-29 17:25:39 +00:00
} ) ;
test ( " particl mainnet genesis block hash " , ( ) async {
expect ( GENESIS_HASH_MAINNET ,
2022-11-29 20:27:15 +00:00
" 0000ee0784c195317ac95623e22fddb8c7b8825dc3998e0bb924d66866eccf4c " ) ;
} ) ;
test ( " particl testnet genesis block hash " , ( ) async {
expect ( GENESIS_HASH_TESTNET ,
" 0000594ada5310b367443ee0afd4fa3d0bbd5850ea4e33cdc7d6a904a7ec7c90 " ) ;
2022-11-29 17:25:39 +00:00
} ) ;
} ) ;
test ( " particl DerivePathType enum " , ( ) {
2022-12-09 15:24:39 +00:00
expect ( DerivePathType . values . length , 2 ) ;
2022-11-29 17:25:39 +00:00
expect ( DerivePathType . values . toString ( ) ,
2022-12-09 15:24:39 +00:00
" [DerivePathType.bip44, DerivePathType.bip84] " ) ;
2022-11-29 17:25:39 +00:00
} ) ;
group ( " bip32 node/root " , ( ) {
test ( " getBip32Root " , ( ) {
2022-11-29 18:55:24 +00:00
final root = getBip32Root ( TEST_MNEMONIC , particl ) ;
2022-11-29 17:25:39 +00:00
expect ( root . toWIF ( ) , ROOT_WIF ) ;
} ) ;
// test("getBip32NodeFromRoot", () {
2022-11-29 18:55:24 +00:00
// final root = getBip32Root(TEST_MNEMONIC, particl);
2022-11-29 17:25:39 +00:00
// // two mainnet
// final node44 = getBip32NodeFromRoot(0, 0, root, DerivePathType.bip44);
// expect(node44.toWIF(), NODE_WIF_44);
// final node49 = getBip32NodeFromRoot(0, 0, root, DerivePathType.bip49);
// expect(node49.toWIF(), NODE_WIF_49);
// // and one on testnet
// final node84 = getBip32NodeFromRoot(
// 0, 0, getBip32Root(TEST_MNEMONIC, testnet), DerivePathType.bip84);
// expect(node84.toWIF(), NODE_WIF_84);
// // a bad derive path
// bool didThrow = false;
// try {
// getBip32NodeFromRoot(0, 0, root, null);
// } catch (_) {
// didThrow = true;
// }
// expect(didThrow, true);
// // finally an invalid network
// didThrow = false;
// final invalidNetwork = NetworkType(
// messagePrefix: '\x18hello world\n',
// bech32: 'gg',
// bip32: Bip32Type(public: 0x055521e, private: 0x055555),
// pubKeyHash: 0x55,
// scriptHash: 0x55,
// wif: 0x00);
// try {
// getBip32NodeFromRoot(0, 0, getBip32Root(TEST_MNEMONIC, invalidNetwork),
// DerivePathType.bip44);
// } catch (_) {
// didThrow = true;
// }
// expect(didThrow, true);
// });
2022-12-11 11:48:24 +00:00
//TODO Testnet not setup
2022-11-29 17:25:39 +00:00
// test("basic getBip32Node", () {
// final node =
// getBip32Node(0, 0, TEST_MNEMONIC, testnet, DerivePathType.bip84);
// expect(node.toWIF(), NODE_WIF_84);
// });
} ) ;
2022-11-29 20:27:15 +00:00
group ( " validate mainnet particl addresses " , ( ) {
2022-11-29 17:25:39 +00:00
MockElectrumX ? client ;
MockCachedElectrumX ? cachedClient ;
MockPriceAPI ? priceAPI ;
late FakeSecureStorage secureStore ;
MockTransactionNotificationTracker ? tracker ;
2022-11-29 21:27:32 +00:00
ParticlWallet ?
mainnetWallet ; // TODO reimplement testnet, see 9baa30c1a40b422bb5f4746efc1220b52691ace6 and sneurlax/stack_wallet#ec399ade0aef1d9ab2dd78876a2d20819dae4ba0
2022-11-29 17:25:39 +00:00
setUp ( ( ) {
client = MockElectrumX ( ) ;
cachedClient = MockCachedElectrumX ( ) ;
priceAPI = MockPriceAPI ( ) ;
secureStore = FakeSecureStorage ( ) ;
tracker = MockTransactionNotificationTracker ( ) ;
2022-11-29 19:41:11 +00:00
mainnetWallet = ParticlWallet (
2022-11-29 17:25:39 +00:00
walletId: " validateAddressMainNet " ,
walletName: " validateAddressMainNet " ,
coin: Coin . particl ,
client: client ! ,
cachedClient: cachedClient ! ,
tracker: tracker ! ,
priceAPI: priceAPI ,
secureStore: secureStore ,
) ;
} ) ;
2022-11-29 20:27:15 +00:00
test ( " valid mainnet particl legacy/p2pkh address " , ( ) {
expect (
mainnetWallet ? . validateAddress ( " Pi9W46PhXkNRusar2KVMbXftYpGzEYGcSa " ) ,
true ) ;
2022-11-30 13:06:31 +00:00
expect ( secureStore . interactions , 0 ) ;
2022-11-29 20:27:15 +00:00
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
test ( " valid mainnet particl legacy/p2pkh address type " , ( ) {
2022-11-29 17:25:39 +00:00
expect (
mainnetWallet ? . addressType (
2022-11-29 20:27:15 +00:00
address: " Pi9W46PhXkNRusar2KVMbXftYpGzEYGcSa " ) ,
2022-11-29 17:25:39 +00:00
DerivePathType . bip44 ) ;
2022-11-30 13:06:31 +00:00
expect ( secureStore . interactions , 0 ) ;
2022-11-29 17:25:39 +00:00
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( tracker ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-11-29 20:27:15 +00:00
test ( " valid mainnet particl p2wpkh address " , ( ) {
2022-11-29 17:25:39 +00:00
expect (
2022-11-29 20:27:15 +00:00
mainnetWallet
? . validateAddress ( " pw1qj6t0kvsmx8qd95pdh4rwxaz5qp5qtfz0xq2rja " ) ,
true ) ;
expect (
mainnetWallet
? . validateAddress ( " bc1qc5ymmsay89r6gr4fy2kklvrkuvzyln4shdvjhf " ) ,
false ) ;
2022-11-30 13:06:31 +00:00
expect ( secureStore . interactions , 0 ) ;
2022-11-29 17:25:39 +00:00
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-11-29 20:27:15 +00:00
test ( " valid mainnet particl legacy/p2pkh address " , ( ) {
2022-11-29 17:25:39 +00:00
expect (
2022-11-29 20:27:15 +00:00
mainnetWallet ? . validateAddress ( " PputQYxNxMiYh3sg7vSh25wg3XxHiPHag7 " ) ,
true ) ;
2022-11-30 13:06:31 +00:00
expect ( secureStore . interactions , 0 ) ;
2022-11-29 20:27:15 +00:00
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
test ( " invalid mainnet particl legacy/p2pkh address " , ( ) {
expect (
mainnetWallet ? . validateAddress ( " PputQYxNxMiYh3sg7vSh25wg3XxHiP0000 " ) ,
false ) ;
expect (
mainnetWallet ? . validateAddress ( " 16YB85zQHjro7fqjR2hMcwdQWCX8jNVtr5 " ) ,
false ) ;
2022-11-30 13:06:31 +00:00
expect ( secureStore . interactions , 0 ) ;
2022-11-29 20:27:15 +00:00
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
test ( " invalid mainnet particl p2wpkh address " , ( ) {
expect (
mainnetWallet
2022-11-30 13:06:31 +00:00
? . validateAddress ( " pw1qce3dhmmle4e0833mssj7ptta3ehydjf0tsa3ju " ) ,
2022-11-29 20:27:15 +00:00
false ) ;
2022-11-30 13:06:31 +00:00
expect ( secureStore . interactions , 0 ) ;
2022-11-29 17:25:39 +00:00
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( tracker ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-12-11 11:48:24 +00:00
test ( " invalid bech32 address type " , ( ) {
expect (
( ) = > mainnetWallet ? . addressType (
address: " tb1qzzlm6mnc8k54mx6akehl8p9ray8r439va5ndyq " ) ,
throwsArgumentError ) ;
expect ( secureStore . interactions , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( tracker ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-11-29 20:27:15 +00:00
2022-11-29 17:25:39 +00:00
test ( " address has no matching script " , ( ) {
expect (
( ) = > mainnetWallet ? . addressType (
address: " mpMk94ETazqonHutyC1v6ajshgtP8oiFKU " ) ,
throwsArgumentError ) ;
expect ( secureStore . interactions , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( tracker ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
} ) ;
2022-12-11 11:48:24 +00:00
group ( " testNetworkConnection " , ( ) {
MockElectrumX ? client ;
MockCachedElectrumX ? cachedClient ;
MockPriceAPI ? priceAPI ;
late FakeSecureStorage secureStore ;
MockTransactionNotificationTracker ? tracker ;
ParticlWallet ? part ;
setUp ( ( ) {
client = MockElectrumX ( ) ;
cachedClient = MockCachedElectrumX ( ) ;
priceAPI = MockPriceAPI ( ) ;
secureStore = FakeSecureStorage ( ) ;
tracker = MockTransactionNotificationTracker ( ) ;
part = ParticlWallet (
walletId: " testNetworkConnection " ,
walletName: " testNetworkConnection " ,
coin: Coin . particl ,
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 part ? . testNetworkConnection ( ) ;
expect ( result , false ) ;
expect ( secureStore . interactions , 0 ) ;
verify ( client ? . ping ( ) ) . called ( 1 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
test ( " attempted connection fails due to exception " , ( ) async {
when ( client ? . ping ( ) ) . thenThrow ( Exception ) ;
final bool ? result = await part ? . testNetworkConnection ( ) ;
expect ( result , false ) ;
expect ( secureStore . interactions , 0 ) ;
verify ( client ? . ping ( ) ) . called ( 1 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
test ( " attempted connection test success " , ( ) async {
when ( client ? . ping ( ) ) . thenAnswer ( ( _ ) async = > true ) ;
final bool ? result = await part ? . testNetworkConnection ( ) ;
expect ( result , true ) ;
expect ( secureStore . interactions , 0 ) ;
verify ( client ? . ping ( ) ) . called ( 1 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
group ( " basic getters, setters, and functions " , ( ) {
final testWalletId = " ParticltestWalletID " ;
final testWalletName = " ParticlWallet " ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
MockElectrumX ? client ;
MockCachedElectrumX ? cachedClient ;
MockPriceAPI ? priceAPI ;
late FakeSecureStorage secureStore ;
MockTransactionNotificationTracker ? tracker ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
ParticlWallet ? part ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
setUp ( ( ) async {
client = MockElectrumX ( ) ;
cachedClient = MockCachedElectrumX ( ) ;
priceAPI = MockPriceAPI ( ) ;
secureStore = FakeSecureStorage ( ) ;
tracker = MockTransactionNotificationTracker ( ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
part = ParticlWallet (
walletId: testWalletId ,
walletName: testWalletName ,
coin: Coin . particl ,
client: client ! ,
cachedClient: cachedClient ! ,
tracker: tracker ! ,
priceAPI: priceAPI ,
secureStore: secureStore ,
) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
test ( " get networkType main " , ( ) async {
expect ( Coin . particl , Coin . particl ) ;
expect ( secureStore . interactions , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
test ( " get networkType test " , ( ) async {
part = ParticlWallet (
walletId: testWalletId ,
walletName: testWalletName ,
coin: Coin . particl ,
client: client ! ,
cachedClient: cachedClient ! ,
tracker: tracker ! ,
priceAPI: priceAPI ,
secureStore: secureStore ,
) ;
expect ( Coin . particl , Coin . particl ) ;
expect ( secureStore . interactions , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
test ( " get cryptoCurrency " , ( ) async {
expect ( Coin . particl , Coin . particl ) ;
expect ( secureStore . interactions , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
test ( " get coinName " , ( ) async {
expect ( Coin . particl , Coin . particl ) ;
expect ( secureStore . interactions , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
test ( " get coinTicker " , ( ) async {
expect ( Coin . particl , Coin . particl ) ;
expect ( secureStore . interactions , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
test ( " get and set walletName " , ( ) async {
expect ( Coin . particl , Coin . particl ) ;
part ? . walletName = " new name " ;
expect ( part ? . walletName , " new name " ) ;
expect ( secureStore . interactions , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
// test("estimateTxFee", () async {
// expect(part?.estimateTxFee(vSize: 356, feeRatePerKB: 1), 356);
// expect(part?.estimateTxFee(vSize: 356, feeRatePerKB: 900), 356);
// expect(part?.estimateTxFee(vSize: 356, feeRatePerKB: 999), 356);
// expect(part?.estimateTxFee(vSize: 356, feeRatePerKB: 1000), 356);
// expect(part?.estimateTxFee(vSize: 356, feeRatePerKB: 1001), 712);
// expect(part?.estimateTxFee(vSize: 356, feeRatePerKB: 1699), 712);
// expect(part?.estimateTxFee(vSize: 356, feeRatePerKB: 2000), 712);
// expect(part?.estimateTxFee(vSize: 356, feeRatePerKB: 12345), 4628);
// expect(secureStore.interactions, 0);
// verifyNoMoreInteractions(client);
// verifyNoMoreInteractions(cachedClient);
// verifyNoMoreInteractions(priceAPI);
// });
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
// 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_MAINNET,
// "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 part?.fees;
// expect(fees, isA<FeeObject>());
// 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(priceAPI);
// });
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
// 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_MAINNET,
// "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 part?.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(priceAPI);
// });
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
// 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 nmc?.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);
// });
} ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
group ( " Particl service class functions that depend on shared storage " , ( ) {
const testWalletId = " ParticltestWalletID " ;
const testWalletName = " ParticlWallet " ;
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
bool hiveAdaptersRegistered = false ;
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
MockElectrumX ? client ;
MockCachedElectrumX ? cachedClient ;
MockPriceAPI ? priceAPI ;
late FakeSecureStorage secureStore ;
MockTransactionNotificationTracker ? tracker ;
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
ParticlWallet ? part ;
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
setUp ( ( ) async {
await setUpTestHive ( ) ;
if ( ! hiveAdaptersRegistered ) {
hiveAdaptersRegistered = true ;
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
// Registering Transaction Model Adapters
Hive . registerAdapter ( TransactionDataAdapter ( ) ) ;
Hive . registerAdapter ( TransactionChunkAdapter ( ) ) ;
Hive . registerAdapter ( TransactionAdapter ( ) ) ;
Hive . registerAdapter ( InputAdapter ( ) ) ;
Hive . registerAdapter ( OutputAdapter ( ) ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
// Registering Utxo Model Adapters
Hive . registerAdapter ( UtxoDataAdapter ( ) ) ;
Hive . registerAdapter ( UtxoObjectAdapter ( ) ) ;
Hive . registerAdapter ( StatusAdapter ( ) ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
final wallets = await Hive . openBox ( ' wallets ' ) ;
await wallets . put ( ' currentWalletName ' , testWalletName ) ;
}
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
client = MockElectrumX ( ) ;
cachedClient = MockCachedElectrumX ( ) ;
priceAPI = MockPriceAPI ( ) ;
secureStore = FakeSecureStorage ( ) ;
tracker = MockTransactionNotificationTracker ( ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
part = ParticlWallet (
walletId: testWalletId ,
walletName: testWalletName ,
coin: Coin . particl ,
client: client ! ,
cachedClient: cachedClient ! ,
tracker: tracker ! ,
priceAPI: priceAPI ,
secureStore: secureStore ,
) ;
} ) ;
2022-12-11 11:48:24 +00:00
//TODO - THis function definition has changed, possibly remove
2022-11-30 13:06:31 +00:00
// test("initializeWallet no network", () async {
// when(client?.ping()).thenAnswer((_) async => false);
// expect(await part?.initializeNew(), false);
// expect(secureStore.interactions, 0);
// verify(client?.ping()).called(1);
// verifyNoMoreInteractions(client);
// verifyNoMoreInteractions(cachedClient);
// verifyNoMoreInteractions(priceAPI);
// });
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
// test("initializeWallet no network exception", () async {
// when(client?.ping()).thenThrow(Exception("Network connection failed"));
// final wallets = await Hive.openBox(testWalletId);
// expect(await nmc?.initializeExisting(), false);
// expect(secureStore.interactions, 0);
// verify(client?.ping()).called(1);
// verifyNoMoreInteractions(client);
// verifyNoMoreInteractions(cachedClient);
// verifyNoMoreInteractions(priceAPI);
// });
2022-11-29 18:57:50 +00:00
2022-12-11 11:48:24 +00:00
test ( " initializeWallet mainnet 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 " : [ ]
} ) ;
await Hive . openBox ( testWalletId ) ;
await expectLater (
( ) = > part ? . initializeExisting ( ) , throwsA ( isA < Exception > ( ) ) )
. then ( ( _ ) {
expect ( secureStore . interactions , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-12-11 11:48:24 +00:00
test ( " initializeWallet throws mnemonic overwrite exception " , ( ) 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 " : [ ]
} ) ;
await secureStore . write (
key: " ${ testWalletId } _mnemonic " , value: " some mnemonic " ) ;
await Hive . openBox ( testWalletId ) ;
await expectLater (
( ) = > part ? . initializeExisting ( ) , throwsA ( isA < Exception > ( ) ) )
. then ( ( _ ) {
expect ( secureStore . interactions , 1 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
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 part ? . 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 part ? . 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 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 = > emptyHistoryBatchResponse ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs1 ) )
. thenAnswer ( ( _ ) async = > emptyHistoryBatchResponse ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs2 ) )
. thenAnswer ( ( _ ) async = > emptyHistoryBatchResponse ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs3 ) )
. thenAnswer ( ( _ ) async = > emptyHistoryBatchResponse ) ;
// await DB.instance.init();
final wallet = await Hive . openBox ( testWalletId ) ;
bool hasThrown = false ;
try {
await part ? . 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 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs2 ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs3 ) ) . called ( 1 ) ;
expect ( secureStore . interactions , 14 ) ;
expect ( secureStore . writes , 5 ) ;
expect ( secureStore . reads , 9 ) ;
expect ( secureStore . deletes , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
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 ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs2 ) )
. thenAnswer ( ( _ ) async = > emptyHistoryBatchResponse ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs3 ) )
. thenAnswer ( ( _ ) async = > emptyHistoryBatchResponse ) ;
2022-11-29 18:57:50 +00:00
2022-12-11 11:48:24 +00:00
await Hive . openBox ( testWalletId ) ;
await part ? . recoverFromMnemonic (
mnemonic: TEST_MNEMONIC ,
maxUnusedAddressGap: 2 ,
maxNumberOfIndexesToCheck: 1000 ,
height: 4000 ) ;
expect ( await part ? . mnemonic , TEST_MNEMONIC . split ( " " ) ) ;
verify ( client ? . getServerFeatures ( ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs0 ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs1 ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs2 ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs3 ) ) . called ( 1 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-12-09 16:41:54 +00:00
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 ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs2 ) )
. thenAnswer ( ( _ ) async = > historyBatchResponse ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs3 ) )
. thenAnswer ( ( _ ) async = > historyBatchResponse ) ;
List < dynamic > dynamicArgValues = [ ] ;
when ( client ? . getBatchHistory ( args: anyNamed ( " args " ) ) )
. thenAnswer ( ( realInvocation ) async {
if ( realInvocation . namedArguments . values . first . length = = 1 ) {
dynamicArgValues . add ( realInvocation . namedArguments . values . first ) ;
}
return historyBatchResponse ;
} ) ;
await Hive . openBox < dynamic > ( testWalletId ) ;
bool hasThrown = false ;
try {
await part ? . recoverFromMnemonic (
mnemonic: TEST_MNEMONIC ,
maxUnusedAddressGap: 2 ,
maxNumberOfIndexesToCheck: 1000 ,
height: 4000 ) ;
} catch ( _ ) {
hasThrown = true ;
}
expect ( hasThrown , false ) ;
verify ( client ? . getServerFeatures ( ) ) . called ( 1 ) ;
2022-12-11 11:48:24 +00:00
verify ( client ? . getBatchHistory ( args: historyBatchArgs0 ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs1 ) ) . called ( 1 ) ;
2022-12-09 16:41:54 +00:00
verify ( client ? . getBatchHistory ( args: historyBatchArgs2 ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs3 ) ) . called ( 1 ) ;
for ( final arg in dynamicArgValues ) {
final map = Map < String , List < dynamic > > . from ( arg as Map ) ;
verify ( client ? . getBatchHistory ( args: map ) ) . called ( 1 ) ;
expect ( activeScriptHashes . contains ( map . values . first . first as String ) ,
true ) ;
}
2022-12-09 16:53:35 +00:00
expect ( secureStore . interactions , 10 ) ;
expect ( secureStore . writes , 5 ) ;
expect ( secureStore . reads , 5 ) ;
2022-12-09 16:41:54 +00:00
expect ( secureStore . deletes , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
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 ( client ? . getBatchHistory ( args: historyBatchArgs2 ) )
. thenAnswer ( ( _ ) async = > historyBatchResponse ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs3 ) )
. thenAnswer ( ( _ ) async = > historyBatchResponse ) ;
when ( cachedClient ? . clearSharedTransactionCache ( coin: Coin . particl ) )
. thenAnswer ( ( realInvocation ) async { } ) ;
when ( client ? . getBatchHistory ( args: {
" 0 " : [
" 8ba03c2c46ed4980fa1e4c84cbceeb2d5e1371a7ccbaf5f3d69c5114161a2247 "
]
} ) ) . thenAnswer ( ( realInvocation ) async = > { " 0 " : [ ] } ) ;
when ( client ? . getBatchHistory ( args: {
" 0 " : [
" 3fedd8a2d5fc355727afe353413dc1a0ef861ba768744d5b8193c33cbc829339 "
]
} ) ) . thenAnswer ( ( realInvocation ) async = > { " 0 " : [ ] } ) ;
when ( client ? . getBatchHistory ( args: {
" 0 " : [
" b6fce6c41154ccf70676c5c91acd9b6899ef0195e34b4c05c4920daa827c19a3 "
]
} ) ) . thenAnswer ( ( realInvocation ) async = > { " 0 " : [ ] } ) ;
when ( client ? . getBatchHistory ( args: {
" 0 " : [
" 0e8b6756b404db5a381fd71ad79cb595a6c36c938cf9913c5a0494b667c2151a "
]
} ) ) . thenAnswer ( ( realInvocation ) async = > { " 0 " : [ ] } ) ;
when ( client ? . getBatchHistory ( args: {
" 0 " : [
" 9b56ab30c7bef0e1eaa10a632c8e2dcdd11b2158d7a917c03d62936afd0015fc "
]
} ) ) . thenAnswer ( ( realInvocation ) async = > { " 0 " : [ ] } ) ;
when ( client ? . getBatchHistory ( args: {
" 0 " : [
" c4b1d9cd4edb7c13eae863b1e4f8fd5acff29f1fe153c4f859906cbea26a3f2f "
]
} ) ) . thenAnswer ( ( realInvocation ) async = > { " 0 " : [ ] } ) ;
final wallet = await Hive . openBox < dynamic > ( testWalletId ) ;
// restore so we have something to rescan
await part ? . recoverFromMnemonic (
mnemonic: TEST_MNEMONIC ,
maxUnusedAddressGap: 2 ,
maxNumberOfIndexesToCheck: 1000 ,
height: 4000 ) ;
// fetch valid wallet data
final preReceivingAddressesP2PKH =
await wallet . get ( ' receivingAddressesP2PKH ' ) ;
final preReceivingAddressesP2WPKH =
await wallet . get ( ' receivingAddressesP2WPKH ' ) ;
final preChangeAddressesP2PKH = await wallet . get ( ' changeAddressesP2PKH ' ) ;
final preChangeAddressesP2WPKH =
await wallet . get ( ' changeAddressesP2WPKH ' ) ;
final preReceivingIndexP2PKH = await wallet . get ( ' receivingIndexP2PKH ' ) ;
final preReceivingIndexP2WPKH = await wallet . get ( ' receivingIndexP2WPKH ' ) ;
final preChangeIndexP2PKH = await wallet . get ( ' changeIndexP2PKH ' ) ;
final preChangeIndexP2WPKH = await wallet . get ( ' changeIndexP2WPKH ' ) ;
final preUtxoData = await wallet . get ( ' latest_utxo_model ' ) ;
final preReceiveDerivationsStringP2PKH = await secureStore . read (
key: " ${ testWalletId } _receiveDerivationsP2PKH " ) ;
final preChangeDerivationsStringP2PKH =
await secureStore . read ( key: " ${ testWalletId } _changeDerivationsP2PKH " ) ;
final preReceiveDerivationsStringP2WPKH = await secureStore . read (
key: " ${ testWalletId } _receiveDerivationsP2WPKH " ) ;
final preChangeDerivationsStringP2WPKH = await secureStore . read (
key: " ${ testWalletId } _changeDerivationsP2WPKH " ) ;
// destroy the data that the rescan will fix
await wallet . put (
' receivingAddressesP2PKH ' , [ " some address " , " some other address " ] ) ;
await wallet . put (
' receivingAddressesP2WPKH ' , [ " some address " , " some other address " ] ) ;
await wallet
. put ( ' changeAddressesP2PKH ' , [ " some address " , " some other address " ] ) ;
await wallet
. put ( ' changeAddressesP2WPKH ' , [ " some address " , " some other address " ] ) ;
await wallet . put ( ' receivingIndexP2PKH ' , 123 ) ;
await wallet . put ( ' receivingIndexP2WPKH ' , 123 ) ;
await wallet . put ( ' changeIndexP2PKH ' , 123 ) ;
await wallet . put ( ' changeIndexP2WPKH ' , 123 ) ;
await secureStore . write (
key: " ${ testWalletId } _receiveDerivationsP2PKH " , value: " {} " ) ;
await secureStore . write (
key: " ${ testWalletId } _changeDerivationsP2PKH " , value: " {} " ) ;
await secureStore . write (
key: " ${ testWalletId } _receiveDerivationsP2WPKH " , value: " {} " ) ;
await secureStore . write (
key: " ${ testWalletId } _changeDerivationsP2WPKH " , value: " {} " ) ;
2022-11-30 13:06:31 +00:00
2022-11-30 14:05:56 +00:00
bool hasThrown = false ;
try {
await part ? . fullRescan ( 2 , 1000 ) ;
} catch ( _ ) {
hasThrown = true ;
}
expect ( hasThrown , false ) ;
2022-11-30 13:06:31 +00:00
2022-11-30 14:05:56 +00:00
// fetch wallet data again
final receivingAddressesP2PKH =
await wallet . get ( ' receivingAddressesP2PKH ' ) ;
2022-12-11 11:48:24 +00:00
final receivingAddressesP2WPKH =
await wallet . get ( ' receivingAddressesP2WPKH ' ) ;
2022-11-30 14:05:56 +00:00
final changeAddressesP2PKH = await wallet . get ( ' changeAddressesP2PKH ' ) ;
2022-12-11 11:48:24 +00:00
final changeAddressesP2WPKH = await wallet . get ( ' changeAddressesP2WPKH ' ) ;
2022-11-30 14:05:56 +00:00
final receivingIndexP2PKH = await wallet . get ( ' receivingIndexP2PKH ' ) ;
2022-12-11 11:48:24 +00:00
final receivingIndexP2WPKH = await wallet . get ( ' receivingIndexP2WPKH ' ) ;
2022-11-30 14:05:56 +00:00
final changeIndexP2PKH = await wallet . get ( ' changeIndexP2PKH ' ) ;
2022-12-11 11:48:24 +00:00
final changeIndexP2WPKH = await wallet . get ( ' changeIndexP2WPKH ' ) ;
2022-11-30 14:05:56 +00:00
final utxoData = await wallet . get ( ' latest_utxo_model ' ) ;
final receiveDerivationsStringP2PKH = await secureStore . read (
key: " ${ testWalletId } _receiveDerivationsP2PKH " ) ;
final changeDerivationsStringP2PKH =
await secureStore . read ( key: " ${ testWalletId } _changeDerivationsP2PKH " ) ;
2022-12-11 11:48:24 +00:00
final receiveDerivationsStringP2WPKH = await secureStore . read (
key: " ${ testWalletId } _receiveDerivationsP2WPKH " ) ;
final changeDerivationsStringP2WPKH = await secureStore . read (
key: " ${ testWalletId } _changeDerivationsP2WPKH " ) ;
2022-11-30 14:05:56 +00:00
expect ( preReceivingAddressesP2PKH , receivingAddressesP2PKH ) ;
2022-12-11 11:48:24 +00:00
expect ( preReceivingAddressesP2WPKH , receivingAddressesP2WPKH ) ;
2022-11-30 14:05:56 +00:00
expect ( preChangeAddressesP2PKH , changeAddressesP2PKH ) ;
2022-12-11 11:48:24 +00:00
expect ( preChangeAddressesP2WPKH , changeAddressesP2WPKH ) ;
2022-11-30 14:05:56 +00:00
expect ( preReceivingIndexP2PKH , receivingIndexP2PKH ) ;
2022-12-11 11:48:24 +00:00
expect ( preReceivingIndexP2WPKH , receivingIndexP2WPKH ) ;
2022-11-30 14:05:56 +00:00
expect ( preChangeIndexP2PKH , changeIndexP2PKH ) ;
2022-12-11 11:48:24 +00:00
expect ( preChangeIndexP2WPKH , changeIndexP2WPKH ) ;
2022-11-30 14:05:56 +00:00
expect ( preUtxoData , utxoData ) ;
expect ( preReceiveDerivationsStringP2PKH , receiveDerivationsStringP2PKH ) ;
expect ( preChangeDerivationsStringP2PKH , changeDerivationsStringP2PKH ) ;
2022-12-11 11:48:24 +00:00
expect ( preReceiveDerivationsStringP2WPKH , receiveDerivationsStringP2WPKH ) ;
expect ( preChangeDerivationsStringP2WPKH , changeDerivationsStringP2WPKH ) ;
2022-11-30 13:06:31 +00:00
2022-11-30 14:05:56 +00:00
verify ( client ? . getServerFeatures ( ) ) . called ( 1 ) ;
2022-12-11 11:48:24 +00:00
verify ( client ? . getBatchHistory ( args: historyBatchArgs0 ) ) . called ( 2 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs1 ) ) . called ( 2 ) ;
2022-12-09 16:53:35 +00:00
verify ( client ? . getBatchHistory ( args: historyBatchArgs2 ) ) . called ( 2 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs3 ) ) . called ( 2 ) ;
2022-12-11 11:48:24 +00:00
2022-11-30 14:05:56 +00:00
verify ( client ? . getBatchHistory ( args: {
" 0 " : [
" 3fedd8a2d5fc355727afe353413dc1a0ef861ba768744d5b8193c33cbc829339 "
]
} ) ) . called ( 2 ) ;
verify ( client ? . getBatchHistory ( args: {
" 0 " : [
" b6fce6c41154ccf70676c5c91acd9b6899ef0195e34b4c05c4920daa827c19a3 "
]
} ) ) . called ( 2 ) ;
verify ( client ? . getBatchHistory ( args: {
" 0 " : [
" 0e8b6756b404db5a381fd71ad79cb595a6c36c938cf9913c5a0494b667c2151a "
]
} ) ) . called ( 2 ) ;
verify ( client ? . getBatchHistory ( args: {
" 0 " : [
" c4b1d9cd4edb7c13eae863b1e4f8fd5acff29f1fe153c4f859906cbea26a3f2f "
]
} ) ) . called ( 2 ) ;
verify ( cachedClient ? . clearSharedTransactionCache ( coin: Coin . particl ) )
. called ( 1 ) ;
2022-12-11 11:48:24 +00:00
expect ( secureStore . writes , 17 ) ;
2022-12-09 16:53:35 +00:00
expect ( secureStore . reads , 22 ) ;
expect ( secureStore . deletes , 4 ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 14:05:56 +00:00
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
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 ( client ? . getBatchHistory ( args: historyBatchArgs2 ) )
. thenAnswer ( ( _ ) async = > historyBatchResponse ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs3 ) )
. thenAnswer ( ( _ ) async = > historyBatchResponse ) ;
when ( client ? . getBatchHistory ( args: {
" 0 " : [
" 8ba03c2c46ed4980fa1e4c84cbceeb2d5e1371a7ccbaf5f3d69c5114161a2247 "
]
} ) ) . thenAnswer ( ( realInvocation ) async = > { " 0 " : [ ] } ) ;
when ( client ? . getBatchHistory ( args: {
" 0 " : [
" 3fedd8a2d5fc355727afe353413dc1a0ef861ba768744d5b8193c33cbc829339 "
]
} ) ) . thenAnswer ( ( realInvocation ) async = > { " 0 " : [ ] } ) ;
when ( client ? . getBatchHistory ( args: {
" 0 " : [
" b6fce6c41154ccf70676c5c91acd9b6899ef0195e34b4c05c4920daa827c19a3 "
]
} ) ) . thenAnswer ( ( realInvocation ) async = > { " 0 " : [ ] } ) ;
when ( client ? . getBatchHistory ( args: {
" 0 " : [
" 0e8b6756b404db5a381fd71ad79cb595a6c36c938cf9913c5a0494b667c2151a "
]
} ) ) . thenAnswer ( ( realInvocation ) async = > { " 0 " : [ ] } ) ;
when ( client ? . getBatchHistory ( args: {
" 0 " : [
" 9b56ab30c7bef0e1eaa10a632c8e2dcdd11b2158d7a917c03d62936afd0015fc "
]
} ) ) . thenAnswer ( ( realInvocation ) async = > { " 0 " : [ ] } ) ;
when ( client ? . getBatchHistory ( args: {
" 0 " : [
" c4b1d9cd4edb7c13eae863b1e4f8fd5acff29f1fe153c4f859906cbea26a3f2f "
]
} ) ) . thenAnswer ( ( realInvocation ) async = > { " 0 " : [ ] } ) ;
when ( cachedClient ? . clearSharedTransactionCache ( coin: Coin . particl ) )
. thenAnswer ( ( realInvocation ) async { } ) ;
final wallet = await Hive . openBox < dynamic > ( testWalletId ) ;
// restore so we have something to rescan
await part ? . recoverFromMnemonic (
mnemonic: TEST_MNEMONIC ,
maxUnusedAddressGap: 2 ,
maxNumberOfIndexesToCheck: 1000 ,
height: 4000 ) ;
// fetch wallet data
final preReceivingAddressesP2PKH =
await wallet . get ( ' receivingAddressesP2PKH ' ) ;
final preReceivingAddressesP2SH =
await wallet . get ( ' receivingAddressesP2SH ' ) ;
final preReceivingAddressesP2WPKH =
await wallet . get ( ' receivingAddressesP2WPKH ' ) ;
final preChangeAddressesP2PKH = await wallet . get ( ' changeAddressesP2PKH ' ) ;
final preChangeAddressesP2SH = await wallet . get ( ' changeAddressesP2SH ' ) ;
final preChangeAddressesP2WPKH =
await wallet . get ( ' changeAddressesP2WPKH ' ) ;
final preReceivingIndexP2PKH = await wallet . get ( ' receivingIndexP2PKH ' ) ;
final preReceivingIndexP2SH = await wallet . get ( ' receivingIndexP2SH ' ) ;
final preReceivingIndexP2WPKH = await wallet . get ( ' receivingIndexP2WPKH ' ) ;
final preChangeIndexP2PKH = await wallet . get ( ' changeIndexP2PKH ' ) ;
final preChangeIndexP2SH = await wallet . get ( ' changeIndexP2SH ' ) ;
final preChangeIndexP2WPKH = await wallet . get ( ' changeIndexP2WPKH ' ) ;
final preUtxoData = await wallet . get ( ' latest_utxo_model ' ) ;
final preReceiveDerivationsStringP2PKH = await secureStore . read (
key: " ${ testWalletId } _receiveDerivationsP2PKH " ) ;
final preChangeDerivationsStringP2PKH =
await secureStore . read ( key: " ${ testWalletId } _changeDerivationsP2PKH " ) ;
final preReceiveDerivationsStringP2SH =
await secureStore . read ( key: " ${ testWalletId } _receiveDerivationsP2SH " ) ;
final preChangeDerivationsStringP2SH =
await secureStore . read ( key: " ${ testWalletId } _changeDerivationsP2SH " ) ;
final preReceiveDerivationsStringP2WPKH = await secureStore . read (
key: " ${ testWalletId } _receiveDerivationsP2WPKH " ) ;
final preChangeDerivationsStringP2WPKH = await secureStore . read (
key: " ${ testWalletId } _changeDerivationsP2WPKH " ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs0 ) )
. thenThrow ( Exception ( " fake exception " ) ) ;
2022-12-09 16:53:35 +00:00
when ( client ? . getBatchHistory ( args: historyBatchArgs1 ) )
. thenThrow ( Exception ( " fake exception " ) ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs2 ) )
. thenThrow ( Exception ( " fake exception " ) ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs3 ) )
. thenThrow ( Exception ( " fake exception " ) ) ;
2022-11-30 14:05:56 +00:00
bool hasThrown = false ;
try {
await part ? . fullRescan ( 2 , 1000 ) ;
} catch ( _ ) {
hasThrown = true ;
}
expect ( hasThrown , true ) ;
// fetch wallet data again
final receivingAddressesP2PKH =
await wallet . get ( ' receivingAddressesP2PKH ' ) ;
final receivingAddressesP2SH = await wallet . get ( ' receivingAddressesP2SH ' ) ;
2022-12-11 11:48:24 +00:00
final receivingAddressesP2WPKH =
await wallet . get ( ' receivingAddressesP2WPKH ' ) ;
2022-11-30 14:05:56 +00:00
final changeAddressesP2PKH = await wallet . get ( ' changeAddressesP2PKH ' ) ;
2022-12-11 11:48:24 +00:00
final changeAddressesP2SH = await wallet . get ( ' changeAddressesP2SH ' ) ;
final changeAddressesP2WPKH = await wallet . get ( ' changeAddressesP2WPKH ' ) ;
2022-11-30 14:05:56 +00:00
final receivingIndexP2PKH = await wallet . get ( ' receivingIndexP2PKH ' ) ;
2022-12-11 11:48:24 +00:00
final receivingIndexP2SH = await wallet . get ( ' receivingIndexP2SH ' ) ;
final receivingIndexP2WPKH = await wallet . get ( ' receivingIndexP2WPKH ' ) ;
2022-11-30 14:05:56 +00:00
final changeIndexP2PKH = await wallet . get ( ' changeIndexP2PKH ' ) ;
2022-12-11 11:48:24 +00:00
final changeIndexP2SH = await wallet . get ( ' changeIndexP2SH ' ) ;
final changeIndexP2WPKH = await wallet . get ( ' changeIndexP2WPKH ' ) ;
2022-11-30 14:05:56 +00:00
final utxoData = await wallet . get ( ' latest_utxo_model ' ) ;
final receiveDerivationsStringP2PKH = await secureStore . read (
key: " ${ testWalletId } _receiveDerivationsP2PKH " ) ;
final changeDerivationsStringP2PKH =
await secureStore . read ( key: " ${ testWalletId } _changeDerivationsP2PKH " ) ;
2022-12-11 11:48:24 +00:00
final receiveDerivationsStringP2SH =
await secureStore . read ( key: " ${ testWalletId } _receiveDerivationsP2SH " ) ;
final changeDerivationsStringP2SH =
await secureStore . read ( key: " ${ testWalletId } _changeDerivationsP2SH " ) ;
final receiveDerivationsStringP2WPKH = await secureStore . read (
key: " ${ testWalletId } _receiveDerivationsP2WPKH " ) ;
final changeDerivationsStringP2WPKH = await secureStore . read (
key: " ${ testWalletId } _changeDerivationsP2WPKH " ) ;
2022-11-30 14:05:56 +00:00
expect ( preReceivingAddressesP2PKH , receivingAddressesP2PKH ) ;
expect ( preReceivingAddressesP2SH , receivingAddressesP2SH ) ;
2022-12-11 11:48:24 +00:00
expect ( preReceivingAddressesP2WPKH , receivingAddressesP2WPKH ) ;
2022-11-30 14:05:56 +00:00
expect ( preChangeAddressesP2PKH , changeAddressesP2PKH ) ;
2022-12-11 11:48:24 +00:00
expect ( preChangeAddressesP2SH , changeAddressesP2SH ) ;
expect ( preChangeAddressesP2WPKH , changeAddressesP2WPKH ) ;
2022-11-30 14:05:56 +00:00
expect ( preReceivingIndexP2PKH , receivingIndexP2PKH ) ;
2022-12-11 11:48:24 +00:00
expect ( preReceivingIndexP2SH , receivingIndexP2SH ) ;
expect ( preReceivingIndexP2WPKH , receivingIndexP2WPKH ) ;
2022-11-30 14:05:56 +00:00
expect ( preChangeIndexP2PKH , changeIndexP2PKH ) ;
2022-12-11 11:48:24 +00:00
expect ( preChangeIndexP2SH , changeIndexP2SH ) ;
expect ( preChangeIndexP2WPKH , changeIndexP2WPKH ) ;
2022-11-30 14:05:56 +00:00
expect ( preUtxoData , utxoData ) ;
expect ( preReceiveDerivationsStringP2PKH , receiveDerivationsStringP2PKH ) ;
expect ( preChangeDerivationsStringP2PKH , changeDerivationsStringP2PKH ) ;
2022-12-11 11:48:24 +00:00
expect ( preReceiveDerivationsStringP2SH , receiveDerivationsStringP2SH ) ;
expect ( preChangeDerivationsStringP2SH , changeDerivationsStringP2SH ) ;
expect ( preReceiveDerivationsStringP2WPKH , receiveDerivationsStringP2WPKH ) ;
expect ( preChangeDerivationsStringP2WPKH , changeDerivationsStringP2WPKH ) ;
2022-11-30 14:05:56 +00:00
verify ( client ? . getServerFeatures ( ) ) . called ( 1 ) ;
2022-12-11 11:48:24 +00:00
verify ( client ? . getBatchHistory ( args: historyBatchArgs0 ) ) . called ( 2 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs1 ) ) . called ( 2 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs2 ) ) . called ( 2 ) ;
2022-11-30 14:05:56 +00:00
verify ( client ? . getBatchHistory ( args: historyBatchArgs3 ) ) . called ( 2 ) ;
verify ( client ? . getBatchHistory ( args: {
" 0 " : [
" 3fedd8a2d5fc355727afe353413dc1a0ef861ba768744d5b8193c33cbc829339 "
]
2022-12-09 16:53:35 +00:00
} ) ) . called ( 1 ) ;
2022-11-30 14:05:56 +00:00
verify ( client ? . getBatchHistory ( args: {
" 0 " : [
" b6fce6c41154ccf70676c5c91acd9b6899ef0195e34b4c05c4920daa827c19a3 "
]
2022-12-09 16:53:35 +00:00
} ) ) . called ( 1 ) ;
2022-11-30 14:05:56 +00:00
verify ( client ? . getBatchHistory ( args: {
" 0 " : [
" 0e8b6756b404db5a381fd71ad79cb595a6c36c938cf9913c5a0494b667c2151a "
]
} ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: {
" 0 " : [
" c4b1d9cd4edb7c13eae863b1e4f8fd5acff29f1fe153c4f859906cbea26a3f2f "
]
2022-12-09 16:53:35 +00:00
} ) ) . called ( 1 ) ;
2022-11-30 14:05:56 +00:00
verify ( cachedClient ? . clearSharedTransactionCache ( coin: Coin . particl ) )
. called ( 1 ) ;
2022-12-09 16:53:35 +00:00
expect ( secureStore . writes , 13 ) ;
2022-12-11 11:48:24 +00:00
expect ( secureStore . reads , 26 ) ;
2022-12-09 16:53:35 +00:00
expect ( secureStore . deletes , 8 ) ;
2022-11-30 14:05:56 +00:00
2022-12-11 11:48:24 +00:00
verifyNoMoreInteractions ( client ) ;
2022-11-30 14:05:56 +00:00
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-12-11 11:48:24 +00:00
test ( " prepareSend 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 ( client ? . getBatchHistory ( args: historyBatchArgs2 ) )
. thenAnswer ( ( _ ) async = > historyBatchResponse ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs3 ) )
. thenAnswer ( ( _ ) async = > historyBatchResponse ) ;
2022-11-29 18:57:50 +00:00
2022-12-11 11:48:24 +00:00
List < dynamic > dynamicArgValues = [ ] ;
2022-11-29 18:57:50 +00:00
2022-12-11 11:48:24 +00:00
when ( client ? . getBatchHistory ( args: anyNamed ( " args " ) ) )
. thenAnswer ( ( realInvocation ) async {
if ( realInvocation . namedArguments . values . first . length = = 1 ) {
dynamicArgValues . add ( realInvocation . namedArguments . values . first ) ;
}
2022-11-29 18:57:50 +00:00
2022-12-11 11:48:24 +00:00
return historyBatchResponse ;
} ) ;
await Hive . openBox < dynamic > ( testWalletId ) ;
when ( cachedClient ? . getTransaction (
txHash:
" 85130125ec9e37a48670fb5eb0a2780b94ea958cd700a1237ff75775d8a0edb0 " ,
coin: Coin . particl ) )
. thenAnswer ( ( _ ) async = > tx2Raw ) ;
when ( cachedClient ? . getTransaction (
txHash:
" bb25567e1ffb2fd6ec9aa3925a7a8dd3055a29521f7811b2b2bc01ce7d8a216e " ,
coin: Coin . particl ) )
. thenAnswer ( ( _ ) async = > tx3Raw ) ;
when ( cachedClient ? . getTransaction (
txHash:
" bb25567e1ffb2fd6ec9aa3925a7a8dd3055a29521f7811b2b2bc01ce7d8a216e " ,
coin: Coin . particl ,
) ) . thenAnswer ( ( _ ) async = > tx4Raw ) ;
// recover to fill data
await part ? . 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 " ,
" 16FuTPaeRSPVxxCnwQmdyx2PQWxX6HWzhQ " ) ) ;
final rcv84 = await secureStore . read (
key: testWalletId + " _receiveDerivationsP2WPKH " ) ;
await secureStore . write (
key: testWalletId + " _receiveDerivationsP2WPKH " ,
value: rcv84 ? . replaceFirst (
" pw1qvr6ehcm44vvqe96mxy9zw9aa5sa5yezvr2r94s " ,
" pw1q66xtkhqzcue808nlg8tp48uq7fshmaddljtkpy " ) ) ;
part ? . outputsList = utxoList ;
bool didThrow = false ;
try {
await part ? . prepareSend (
address: " pw1q66xtkhqzcue808nlg8tp48uq7fshmaddljtkpy " ,
satoshiAmount: 15000 ) ;
} catch ( _ ) {
didThrow = true ;
}
expect ( didThrow , true ) ;
verify ( client ? . getServerFeatures ( ) ) . called ( 1 ) ;
/// verify transaction no matching calls
// verify(cachedClient?.getTransaction(
// txHash:
// "2087ce09bc316877c9f10971526a2bffa3078d52ea31752639305cdcd8230703",
// coin: Coin.particl,
// callOutSideMainIsolate: false))
// .called(1);
// verify(cachedClient?.getTransaction(
// txHash:
// "ed32c967a0e86d51669ac21c2bb9bc9c50f0f55fbacdd8db21d0a986fba93bd7",
// coin: Coin.particl,
// callOutSideMainIsolate: false))
// .called(1);
// verify(cachedClient?.getTransaction(
// txHash:
// "3f0032f89ac44b281b50314cff3874c969c922839dddab77ced54e86a21c3fd4",
// coin: Coin.particl,
// callOutSideMainIsolate: false))
// .called(1);
verify ( client ? . getBatchHistory ( args: historyBatchArgs0 ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs1 ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs2 ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs3 ) ) . called ( 1 ) ;
for ( final arg in dynamicArgValues ) {
final map = Map < String , List < dynamic > > . from ( arg as Map ) ;
verify ( client ? . getBatchHistory ( args: map ) ) . called ( 1 ) ;
expect ( activeScriptHashes . contains ( map . values . first . first as String ) ,
true ) ;
}
expect ( secureStore . interactions , 14 ) ;
expect ( secureStore . writes , 7 ) ;
expect ( secureStore . reads , 7 ) ;
expect ( secureStore . deletes , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
test ( " confirmSend no hex " , ( ) async {
bool didThrow = false ;
try {
await part ? . confirmSend ( txData: { " some " : " strange map " } ) ;
} catch ( _ ) {
didThrow = true ;
}
expect ( didThrow , true ) ;
expect ( secureStore . interactions , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
test ( " confirmSend hex is not string " , ( ) async {
bool didThrow = false ;
try {
await part ? . confirmSend ( txData: { " hex " : true } ) ;
} catch ( _ ) {
didThrow = true ;
}
expect ( didThrow , true ) ;
expect ( secureStore . interactions , 0 ) ;
verifyNoMoreInteractions ( client ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
test ( " confirmSend hex is string but missing other data " , ( ) async {
bool didThrow = false ;
try {
await part ? . confirmSend ( txData: { " hex " : " a string " } ) ;
} 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 ( priceAPI ) ;
} ) ;
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
// test("confirmSend fails due to vSize being greater than fee", () async {
// bool didThrow = false;
// try {
// await nmc
// ?.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(priceAPI);
// });
2022-11-29 18:57:50 +00:00
2022-11-30 13:06:31 +00:00
// 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 nmc
// ?.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);
// });
//
// // this test will create a non mocked electrumx client that will try to connect
// // to the provided ipAddress below. This will throw a bunch of errors
// // which what we want here as actually calling electrumx calls here is unwanted.
// // test("listen to NodesChangedEvent", () async {
2022-12-09 15:30:41 +00:00
// // nmc = ParticlWallet(
2022-11-30 13:06:31 +00:00
// // walletId: testWalletId,
// // walletName: testWalletName,
// // networkType: BasicNetworkType.test,
// // client: client,
// // cachedClient: cachedClient,
// // priceAPI: priceAPI,
// // secureStore: secureStore,
// // );
// //
// // // 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("activeNodeID_Bitcoin", "default");
// //
// // final a = nmc.cachedElectrumXClient;
// //
// // // return when refresh is called on node changed trigger
// // nmc.longMutex = true;
// //
// // GlobalEventBus.instance
// // .fire(NodesChangedEvent(NodesChangedEventType.updatedCurrentNode));
// //
// // // make sure event has processed before continuing
// // await Future.delayed(Duration(seconds: 5));
// //
// // final b = nmc.cachedElectrumXClient;
// //
// // expect(identical(a, b), false);
// //
// // await nmc.exit();
// //
// // expect(secureStore.interactions, 0);
// // verifyNoMoreInteractions(client);
// // verifyNoMoreInteractions(cachedClient);
// // verifyNoMoreInteractions(priceAPI);
// // });
2022-11-30 14:05:56 +00:00
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 ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs2 ) )
. thenAnswer ( ( _ ) async = > historyBatchResponse ) ;
when ( client ? . getBatchHistory ( args: historyBatchArgs3 ) )
. thenAnswer ( ( _ ) async = > historyBatchResponse ) ;
List < dynamic > dynamicArgValues = [ ] ;
when ( client ? . getBatchHistory ( args: anyNamed ( " args " ) ) )
. thenAnswer ( ( realInvocation ) async {
if ( realInvocation . namedArguments . values . first . length = = 1 ) {
dynamicArgValues . add ( realInvocation . namedArguments . values . first ) ;
}
return historyBatchResponse ;
} ) ;
await Hive . openBox < dynamic > ( testWalletId ) ;
// recover to fill data
await part ? . recoverFromMnemonic (
mnemonic: TEST_MNEMONIC ,
maxUnusedAddressGap: 2 ,
maxNumberOfIndexesToCheck: 1000 ,
height: 4000 ) ;
part ? . refreshMutex = true ;
await part ? . refresh ( ) ;
verify ( client ? . getServerFeatures ( ) ) . called ( 1 ) ;
2022-12-11 11:48:24 +00:00
verify ( client ? . getBatchHistory ( args: historyBatchArgs0 ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs1 ) ) . called ( 1 ) ;
2022-11-30 14:05:56 +00:00
verify ( client ? . getBatchHistory ( args: historyBatchArgs2 ) ) . called ( 1 ) ;
verify ( client ? . getBatchHistory ( args: historyBatchArgs3 ) ) . called ( 1 ) ;
for ( final arg in dynamicArgValues ) {
final map = Map < String , List < dynamic > > . from ( arg as Map ) ;
verify ( client ? . getBatchHistory ( args: map ) ) . called ( 1 ) ;
expect ( activeScriptHashes . contains ( map . values . first . first as String ) ,
true ) ;
}
2022-12-09 16:56:18 +00:00
expect ( secureStore . interactions , 10 ) ;
expect ( secureStore . writes , 5 ) ;
expect ( secureStore . reads , 5 ) ;
2022-11-30 14:05:56 +00:00
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 ? . getHistory ( scripthash: anyNamed ( " scripthash " ) ) )
. thenAnswer ( ( _ ) async = > [ ] ) ;
when ( client ? . estimateFee ( blocks: anyNamed ( " blocks " ) ) )
. thenAnswer ( ( _ ) async = > Decimal . one ) ;
when ( priceAPI ? . getPricesAnd24hChange ( baseCurrency: " USD " ) )
. thenAnswer ( ( _ ) async = > { Coin . particl: Tuple2 ( Decimal . one , 0.3 ) } ) ;
final List < dynamic > dynamicArgValues = [ ] ;
when ( client ? . getBatchHistory ( args: anyNamed ( " args " ) ) )
. thenAnswer ( ( realInvocation ) async {
dynamicArgValues . add ( realInvocation . namedArguments . values . first ) ;
return historyBatchResponse ;
} ) ;
await Hive . openBox < dynamic > ( testWalletId ) ;
// recover to fill data
await part ? . 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 part ? . refresh ( ) ;
verify ( client ? . getServerFeatures ( ) ) . called ( 1 ) ;
2022-12-09 16:58:25 +00:00
verify ( client ? . getHistory ( scripthash: anyNamed ( " scripthash " ) ) ) . called ( 3 ) ;
2022-11-30 14:05:56 +00:00
verify ( client ? . estimateFee ( blocks: anyNamed ( " blocks " ) ) ) . called ( 3 ) ;
verify ( client ? . getBlockHeadTip ( ) ) . called ( 1 ) ;
verify ( priceAPI ? . getPricesAnd24hChange ( baseCurrency: " USD " ) ) . called ( 2 ) ;
for ( final arg in dynamicArgValues ) {
final map = Map < String , List < dynamic > > . from ( arg as Map ) ;
verify ( client ? . getBatchHistory ( args: map ) ) . called ( 1 ) ;
}
2022-12-09 16:58:25 +00:00
expect ( secureStore . interactions , 10 ) ;
expect ( secureStore . writes , 5 ) ;
expect ( secureStore . reads , 5 ) ;
2022-11-30 14:05:56 +00:00
expect ( secureStore . deletes , 0 ) ;
verifyNoMoreInteractions ( cachedClient ) ;
verifyNoMoreInteractions ( priceAPI ) ;
} ) ;
tearDown ( ( ) async {
await tearDownTestHive ( ) ;
} ) ;
2022-11-30 13:06:31 +00:00
} ) ;
2022-11-29 17:25:39 +00:00
}