stack_wallet/test/services/coins/firo/firo_wallet_test.dart
2022-08-26 23:15:10 +08:00

3543 lines
130 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:decimal/decimal.dart';
import 'package:flutter/services.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/models/models.dart';
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
import 'package:stackwallet/services/price.dart';
import 'package:stackwallet/services/transaction_notification_tracker.dart';
import 'package:stackwallet/utilities/address_utils.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/format.dart';
import 'firo_wallet_test.mocks.dart';
import 'firo_wallet_test_parameters.dart';
import 'sample_data/get_anonymity_set_sample_data.dart';
import 'sample_data/get_used_serials_sample_data.dart';
import 'sample_data/get_utxos_sample_data.dart';
import 'sample_data/gethistory_samples.dart';
import 'sample_data/transaction_data_samples.dart';
@GenerateMocks(
[ElectrumX, CachedElectrumX, PriceAPI, TransactionNotificationTracker])
void main() {
group("isolate functions", () {
test("isolateDerive", () async {
final result =
await isolateDerive(IsolateDeriveParams.mnemonic, 0, 2, firoNetwork);
expect(result, isA<Map<String, dynamic>>());
expect(result.toString(), IsolateDeriveParams.expected);
});
test("isolateRestore success", () async {
final cachedClient = MockCachedElectrumX();
final txData = TransactionData.fromJson(dateTimeChunksJson);
final Map setData = {};
setData[1] = GetAnonymitySetSampleData.data;
final usedSerials = GetUsedSerialsSampleData.serials["serials"] as List;
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash8,
coin: Coin.firo,
)).thenAnswer((_) async {
return SampleGetTransactionData.txData8;
});
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash9,
coin: Coin.firo,
)).thenAnswer((_) async {
return SampleGetTransactionData.txData9;
});
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash7,
coin: Coin.firo,
)).thenAnswer((_) async {
return SampleGetTransactionData.txData7;
});
final result = await isolateRestore(
TEST_MNEMONIC,
txData,
"USD",
Coin.firo,
1,
setData,
usedSerials,
firoNetwork,
Decimal.ten,
"en_US",
);
expect(result, isA<Map<String, dynamic>>());
expect(result["mintIndex"], 8);
expect(result["jindex"], [2, 4, 6]);
expect(
result["_lelantus_coins"], isA<List<Map<dynamic, LelantusCoin>>>());
expect(result["newTxMap"], isA<Map<String, Transaction>>());
});
test("isolateRestore throws", () async {
final txData = TransactionData();
final Map setData = {};
final usedSerials = [];
expect(
() => isolateRestore(
TEST_MNEMONIC,
txData,
"USD",
Coin.firo,
1,
setData,
usedSerials,
firoNetwork,
Decimal.ten,
"en_US",
),
throwsA(isA<Error>()));
});
test("isolateCreateJoinSplitTransaction not enough funds", () async {
final result = await isolateCreateJoinSplitTransaction(
100,
"aNmsUtzPzQ3SKWNjEH48GacMQJXWN5Rotm",
false,
TEST_MNEMONIC,
2,
Decimal.ten,
[],
459185,
Coin.firo,
firoNetwork,
[GetAnonymitySetSampleData.data],
"en_US",
);
expect(result, 1);
});
// test("isolateCreateJoinSplitTransaction success", () async {
// final result = await isolateCreateJoinSplitTransaction(
// 9000,
// "aNmsUtzPzQ3SKWNjEH48GacMQJXWN5Rotm",
// true,
// TEST_MNEMONIC,
// 2,
// Decimal.ten,
// SampleLelantus.lelantusEntries,
// 459185,
// Coin.firo,
// firoNetwork,
// [GetAnonymitySetSampleData.data],
// "en_US",
// );
//
// expect(result, isA<Map<String, dynamic>>());
// });
test("isolateEstimateJoinSplitFee", () async {
final result = await isolateEstimateJoinSplitFee(
1000,
false,
SampleLelantus.lelantusEntries,
Coin.firo,
);
expect(result, isA<LelantusFeeData>());
});
test("call getIsolate with missing args", () async {
final receivePort = await getIsolate({
"function": "estimateJoinSplit",
"subtractFeeFromAmount": true,
});
expect(await receivePort.first, "Error");
});
test("call getIsolate with bad args", () async {
final receivePort = await getIsolate({
"function": "estimateJoinSplit",
"spendAmount": "spendAmount",
"subtractFeeFromAmount": true,
"lelantusEntries": MockCachedElectrumX(),
});
expect(await receivePort.first, "Error");
});
});
group("Other standalone functions in firo_wallet.dart", () {
test("Firo main net parameters", () {
expect(firoNetwork.messagePrefix, '\x18Zcoin Signed Message:\n');
expect(firoNetwork.bech32, 'bc');
expect(firoNetwork.bip32.private, 0x0488ade4);
expect(firoNetwork.bip32.public, 0x0488b21e);
expect(firoNetwork.pubKeyHash, 0x52);
expect(firoNetwork.scriptHash, 0x07);
expect(firoNetwork.wif, 0xd2);
});
test("Firo test net parameters", () {
expect(firoTestNetwork.messagePrefix, '\x18Zcoin Signed Message:\n');
expect(firoTestNetwork.bech32, 'bc');
expect(firoTestNetwork.bip32.private, 0x04358394);
expect(firoTestNetwork.bip32.public, 0x043587cf);
expect(firoTestNetwork.pubKeyHash, 0x41);
expect(firoTestNetwork.scriptHash, 0xb2);
expect(firoTestNetwork.wif, 0xb9);
});
test("getBip32Node", () {
final node = getBip32Node(0, 3, Bip32TestParams.mnemonic, firoNetwork);
expect(node.index, 3);
expect(node.chainCode.toList(), Bip32TestParams.chainCodeList);
expect(node.depth, 5);
expect(node.toBase58(), Bip32TestParams.base58);
expect(node.publicKey.toList(), Bip32TestParams.publicKeyList);
expect(node.privateKey!.toList(), Bip32TestParams.privateKeyList);
expect(node.parentFingerprint, Bip32TestParams.parentFingerprint);
expect(node.fingerprint.toList(), Bip32TestParams.fingerprintList);
});
// group("getJMintTransactions", () {
// test(
// "getJMintTransactions throws Error due to some invalid transactions passed to this function",
// () {
// final cachedClient = MockCachedElectrumX();
// final priceAPI = MockPriceAPI();
//
// // mock price calls
// // when(priceAPI.getPricesAnd24hChange(baseCurrency: "USD"))
// // .thenAnswer((_) async => Decimal.fromInt(10));
//
// // mock transaction calls
// when(cachedClient.getTransaction(
// txHash: SampleGetTransactionData.txHash0,
// coin: Coin.firo,))
// .thenAnswer((_) async => SampleGetTransactionData.txData0);
// when(cachedClient.getTransaction(
// txHash: SampleGetTransactionData.txHash1,
// coin: Coin.firo,
// ))
// .thenAnswer((_) async => SampleGetTransactionData.txData1);
// when(cachedClient.getTransaction(
// txHash: SampleGetTransactionData.txHash2,
// coin: Coin.firo,
// ))
// .thenAnswer((_) async => SampleGetTransactionData.txData2);
// when(cachedClient.getTransaction(
// txHash: SampleGetTransactionData.txHash3,
// coin: Coin.firo,
// ))
// .thenAnswer((_) async => SampleGetTransactionData.txData3);
// when(cachedClient.getTransaction(
// txHash: SampleGetTransactionData.txHash4,
// coin: Coin.firo,
// ))
// .thenAnswer((_) async => SampleGetTransactionData.txData4);
// when(cachedClient.getTransaction(
// txHash: SampleGetTransactionData.txHash5,
// coin: Coin.firo,
// ))
// .thenAnswer((_) async => SampleGetTransactionData.txData5);
//
// final transactions = [
// SampleGetTransactionData.txHash0,
// SampleGetTransactionData.txHash1,
// SampleGetTransactionData.txHash2,
// SampleGetTransactionData.txHash3,
// SampleGetTransactionData.txHash4,
// SampleGetTransactionData.txHash5,
// ];
//
// expect(
// () async => await getJMintTransactions(
// cachedClient,
// transactions,
// "USD",
// "Firo",
// false,
// Decimal.ten,
// "en_US",
// ),
// throwsA(isA<Error>()));
// });
//
// test("getJMintTransactions success", () async {
// final cachedClient = MockCachedElectrumX();
// final priceAPI = MockPriceAPI();
//
// // mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
//
// // mock transaction calls
// when(cachedClient.getTransaction(
// txHash: SampleGetTransactionData.txHash0,
// coin: Coin.firo,
// ))
// .thenAnswer((_) async => SampleGetTransactionData.txData0);
//
// when(cachedClient.getTransaction(
// txHash: SampleGetTransactionData.txHash2,
// coin: Coin.firo,
// ))
// .thenAnswer((_) async => SampleGetTransactionData.txData2);
//
// when(cachedClient.getTransaction(
// txHash: SampleGetTransactionData.txHash4,
// coin: Coin.firo,
// ))
// .thenAnswer((_) async => SampleGetTransactionData.txData4);
//
// when(cachedClient.getTransaction(
// txHash: SampleGetTransactionData.txHash6,
// coin: Coin.firo,
// ))
// .thenAnswer((_) async => SampleGetTransactionData.txData6);
//
// final transactions = [
// SampleGetTransactionData.txHash0,
// SampleGetTransactionData.txHash2,
// SampleGetTransactionData.txHash4,
// SampleGetTransactionData.txHash6,
// ];
//
// final result = await getJMintTransactions(
// cachedClient,
// transactions,
// "USD",
// "Firo",
// false,
// Decimal.ten,
// "en_US",
// );
//
// expect(result, isA<List<Transaction>>());
// expect(result.length, 4);
// });
// });
//
// test("getAnonymitySet", () async {
// final cachedClient = MockCachedElectrumX();
// when(cachedClient.getAnonymitySet(
// groupId: "1", coin: Coin.firo, ))
// .thenAnswer((_) async => {
// "blockHash":
// "c8e0ee6b8f7c1c85973e2b09321dc8644483f19dd7677ab0f33f7ffb1c6a0ec1",
// "setHash":
// "3d67502ae9e9d21d452dbbad1d961c6fcf594a3e44e9ca7b874f991a4c0e2f2d",
// "serializedCoins": [
// "388b82fdc27fd4a64c3290578d00b210bf9aa0bd9e4b08be1913bf95877bead00100",
// "a554e4b700c161adefbe7933c6e2784cc029a590d75c7ad35407323e7579e8680100",
// "162ec5f41380f590462514615fae016ff674e3e07513039d16f90161d88d83220000",
// "... ~50000 more strings ...",
// "6482f50f21b38246f3f9f074cbf61b00ad175b63a946467a85bd22fe1a89825b0100",
// "7a9e57560d4abc384a48bf850a12df94e83d33496bb456aad26e7317921845330000",
// "a7a8ddf79fdaf6846c0c19eb00ba7a95713a1a62df91761cb74b122606385fb80000"
// ]
// });
//
// final result =
// await getAnonymitySet(cachedClient, "", "1", false, "Firo");
//
// expect(result, isA<Map<String, dynamic>>());
// expect(result["blockHash"],
// "c8e0ee6b8f7c1c85973e2b09321dc8644483f19dd7677ab0f33f7ffb1c6a0ec1");
// expect(result["setHash"],
// "3d67502ae9e9d21d452dbbad1d961c6fcf594a3e44e9ca7b874f991a4c0e2f2d");
// expect(result["serializedCoins"], isA<List<String>>());
// });
test("getBlockHead", () async {
final client = MockElectrumX();
when(client.getBlockHeadTip()).thenAnswer(
(_) async => {"height": 4359032, "hex": "... some block hex ..."});
int result = await getBlockHead(client);
expect(result, 4359032);
});
});
group("validate firo addresses", () {
test("check valid firo main net address", () async {
final firo = FiroWallet(
walletName: 'unit test',
walletId: 'some id',
coin: Coin.firo,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expect(firo.validateAddress("a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg"), true);
});
test("check invalid firo main net address", () async {
final firo = FiroWallet(
walletName: 'unit test',
walletId: 'some id',
coin: Coin.firo,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expect(firo.validateAddress("sDda3fsd4af"), false);
});
test("check valid firo test net address against main net", () async {
final firo = FiroWallet(
walletName: 'unit test',
walletId: 'some id',
coin: Coin.firo,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expect(firo.validateAddress("THqfkegzJjpF4PQFAWPhJWMWagwHecfqva"), false);
});
test("check valid firo test net address", () async {
final firo = FiroWallet(
walletName: 'unit test',
walletId: 'some id',
coin: Coin.firoTestNet,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expect(firo.validateAddress("THqfkegzJjpF4PQFAWPhJWMWagwHecfqva"), true);
});
test("check invalid firo test net address", () async {
final firo = FiroWallet(
walletName: 'unit test',
walletId: 'some id',
coin: Coin.firoTestNet,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expect(firo.validateAddress("sDda3fsd4af"), false);
});
test("check valid firo address against test net", () async {
final firo = FiroWallet(
walletName: 'unit test',
walletId: 'some id',
coin: Coin.firoTestNet,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expect(firo.validateAddress("a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg"), false);
});
});
group("testNetworkConnection", () {
test("attempted connection fails due to server error", () async {
final client = MockElectrumX();
when(client.ping()).thenAnswer((_) async => false);
final firo = FiroWallet(
walletName: 'unit test',
walletId: 'some id',
coin: Coin.firo,
client: client,
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
final bool result = await firo.testNetworkConnection();
expect(result, false);
});
test("attempted connection fails due to exception", () async {
final client = MockElectrumX();
when(client.ping()).thenThrow(Exception);
final firo = FiroWallet(
walletName: 'unit test',
walletId: 'some id',
coin: Coin.firo,
client: client,
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
final bool result = await firo.testNetworkConnection();
expect(result, false);
});
test("attempted connection test success", () async {
final client = MockElectrumX();
when(client.ping()).thenAnswer((_) async => true);
final firo = FiroWallet(
walletName: 'unit test',
walletId: 'some id',
coin: Coin.firoTestNet,
client: client,
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
final bool result = await firo.testNetworkConnection();
expect(result, true);
});
});
group("FiroWallet service class functions that depend on shared storage", () {
const testWalletId = "testWalletID";
const testWalletName = "Test Wallet";
bool hiveAdaptersRegistered = false;
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());
// Registering Lelantus Model Adapters
Hive.registerAdapter(LelantusCoinAdapter());
}
final wallets = await Hive.openBox('wallets');
await wallets.put('currentWalletName', testWalletName);
});
// test("initializeWallet no network", () async {
// final client = MockElectrumX();
// final cachedClient = MockCachedElectrumX();
// final secureStore = FakeSecureStorage();
// final priceAPI = MockPriceAPI();
//
// when(client.getServerFeatures()).thenAnswer((_) async => false);
//
// final firo = FiroWallet(
// walletName: testWalletName,
// walletId: testWalletId + "initializeWallet no net",
// client: client,coin: Coin.firo,
// cachedClient: cachedClient,
// secureStore: secureStore,
// priceAPI: priceAPI,
// tracker: MockTransactionNotificationTracker(),
// );
//
// expect(await firo.initializeNew(), false);
// });
// test("initializeWallet no network exception", () async {
// final client = MockElectrumX();
// final cachedClient = MockCachedElectrumX();
// final secureStore = FakeSecureStorage();
// final priceAPI = MockPriceAPI();
//
// when(client.ping()).thenThrow(Exception("Network connection failed"));
//
// final firo = FiroWallet(
// walletName: testWalletName,
// walletId: "${testWalletId}initializeWallet no net exception",
// client: client,
// coin: Coin.firo,
// cachedClient: cachedClient,
// secureStore: secureStore,
// priceAPI: priceAPI,
// tracker: MockTransactionNotificationTracker(),
// );
//
// expect(await firo.initializeWallet(), false);
// });
//
// test("initializeWallet throws bad network on testnet", () async {
// final client = MockElectrumX();
// final cachedClient = MockCachedElectrumX();
// final secureStore = FakeSecureStorage();
// final priceAPI = MockPriceAPI();
//
// 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": []
// });
//
// final firo = FiroWallet(
// walletName: testWalletName,
// walletId: testWalletId + "initializeWallet bad net testnet",
// coin: Coin.firoTestNet,
// client: client,
// cachedClient: cachedClient,
// secureStore: secureStore,
// priceAPI: priceAPI,
// tracker: MockTransactionNotificationTracker(),
// );
//
// expect(() => firo.initializeWallet(), throwsA(isA<Exception>()));
// });
//
// test("initializeWallet throws bad network on mainnet", () async {
// final client = MockElectrumX();
// final cachedClient = MockCachedElectrumX();
// final secureStore = FakeSecureStorage();
// final priceAPI = MockPriceAPI();
//
// 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": []
// });
//
// final firo = FiroWallet(
// walletName: testWalletName,
// walletId: testWalletId + "initializeWallet bad net mainnet",
// client: client,
// cachedClient: cachedClient,
// secureStore: secureStore,
// priceAPI: priceAPI,
// tracker: MockTransactionNotificationTracker(),
// );
//
// expect(() => firo.initializeWallet(), throwsA(isA<Exception>()));
// });
//
// test("initializeWallet new test net wallet", () async {
// TestWidgetsFlutterBinding.ensureInitialized();
// const MethodChannel('uk.spiralarm.flutter/devicelocale')
// .setMockMethodCallHandler((methodCall) async => 'en_US');
//
// final client = MockElectrumX();
// final cachedClient = MockCachedElectrumX();
// final secureStore = FakeSecureStorage();
// final priceAPI = MockPriceAPI();
// when(priceAPI.getPrice(ticker: "tFIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(-1));
//
// 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": []
// });
//
// final List<Map<String, dynamic>> emptyList = [];
//
// when(client.getUTXOs(scripthash: anyNamed("scripthash")))
// .thenAnswer((_) async => emptyList);
// when(client.getHistory(scripthash: anyNamed("scripthash")))
// .thenAnswer((_) async => emptyList);
//
// final firo = FiroWallet(
// walletName: testWalletName,
// walletId: testWalletId + "initializeWallet testnet",
// coin: Coin.firoTestNet,
// client: client,
// cachedClient: cachedClient,
// secureStore: secureStore,
// priceAPI: priceAPI,
// tracker: MockTransactionNotificationTracker(),
// );
//
// await firo.initializeWallet();
//
// final wallet =
// await Hive.openBox(testWalletId + "initializeWallet testnet");
//
// expect(await wallet.get("addressBookEntries"), {});
//
// expect(await wallet.get("blocked_tx_hashes"), ["0xdefault"]);
//
// final result = await wallet.get("changeAddresses");
// expect(result, isA<List<String>>());
// expect(result.length, 1);
//
// expect(await wallet.get("changeIndex"), 0);
//
// expect(await wallet.get("id"), testWalletId + "initializeWallet testnet");
//
// expect(await wallet.get("jindex"), []);
//
// expect(await wallet.get("mintIndex"), 0);
//
//
// final currentReceivingAddress = await firo.currentReceivingAddress;
// expect(currentReceivingAddress, isA<String>());
//
// expect(await wallet.get("receivingIndex"), 0);
// });
//
// test("initializeWallet an already existing test net wallet", () async {
// TestWidgetsFlutterBinding.ensureInitialized();
// const MethodChannel('uk.spiralarm.flutter/devicelocale')
// .setMockMethodCallHandler((methodCall) async => 'en_US');
//
// final client = MockElectrumX();
// final cachedClient = MockCachedElectrumX();
// final secureStore = FakeSecureStorage();
// final priceAPI = MockPriceAPI();
// // when(priceAPI.getPrice(ticker: "tFIRO", baseCurrency: "USD"))
// // .thenAnswer((_) async => Decimal.fromInt(-1));
//
// 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": []
// });
//
// final List<Map<String, dynamic>> emptyList = [];
//
// when(client.getUTXOs(scripthash: anyNamed("scripthash")))
// .thenAnswer((_) async => emptyList);
// when(client.getHistory(scripthash: anyNamed("scripthash")))
// .thenAnswer((_) async => emptyList);
//
// final firo = FiroWallet(
// walletName: testWalletName,
// walletId: testWalletId + "initializeWallet existing",
// coin: Coin.firoTestNet,
// client: client,
// cachedClient: cachedClient,
// secureStore: secureStore,
// priceAPI: priceAPI,
// tracker: MockTransactionNotificationTracker(),
// );
//
// // 1st call to create wallet
// await firo.initializeWallet();
//
// final wallet =
// await Hive.openBox(testWalletId + "initializeWallet existing");
//
// expect(await wallet.get("addressBookEntries"), {});
//
// expect(await wallet.get("blocked_tx_hashes"), ["0xdefault"]);
//
// final result = await wallet.get("changeAddresses");
// expect(result, isA<List<String>>());
// expect(result.length, 1);
//
// expect(await wallet.get("changeIndex"), 0);
//
// expect(
// await wallet.get("id"), testWalletId + "initializeWallet existing");
//
// expect(await wallet.get("jindex"), []);
//
// expect(await wallet.get("mintIndex"), 0);
//
// expect(firo.fiatCurrency, "USD");
//
// final currentReceivingAddress = await firo.currentReceivingAddress;
// expect(currentReceivingAddress, isA<String>());
//
// expect(await wallet.get("receivingIndex"), 0);
//
// // second call to test initialization of existing wallet;
// await firo.initializeWallet();
//
// final wallet2 =
// await Hive.openBox(testWalletId + "initializeWallet existing");
//
// expect(await wallet2.get("addressBookEntries"), {});
//
// expect(await wallet2.get("blocked_tx_hashes"), ["0xdefault"]);
//
// final result2 = await wallet2.get("changeAddresses");
// expect(result2, isA<List<String>>());
// expect(result2.length, 1);
//
// expect(await wallet2.get("changeIndex"), 0);
//
// expect(
// await wallet2.get("id"), testWalletId + "initializeWallet existing");
//
// expect(await wallet2.get("jindex"), []);
//
// expect(await wallet2.get("mintIndex"), 0);
//
// expect(firo.fiatCurrency, "USD");
//
// final cra = await wallet2.get("receivingAddresses");
// expect(cra, isA<List<String>>());
// expect(cra.length, 1);
//
// expect(await wallet2.get("receivingIndex"), 0);
// });
//
// test("initializeWallet new main net wallet", () async {
// TestWidgetsFlutterBinding.ensureInitialized();
// const MethodChannel('uk.spiralarm.flutter/devicelocale')
// .setMockMethodCallHandler((methodCall) async => 'en_US');
//
// final client = MockElectrumX();
// final cachedClient = MockCachedElectrumX();
// final secureStore = FakeSecureStorage();
// final priceAPI = MockPriceAPI();
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) 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": []
// });
//
// final List<Map<String, dynamic>> emptyList = [];
//
// when(client.getUTXOs(scripthash: anyNamed("scripthash")))
// .thenAnswer((_) async => emptyList);
// when(client.getHistory(scripthash: anyNamed("scripthash")))
// .thenAnswer((_) async => emptyList);
//
// final firo = FiroWallet(
// walletName: testWalletName,
// walletId: testWalletId + "initializeWallet",
// coin: Coin.firo,
// client: client,
// cachedClient: cachedClient,
// secureStore: secureStore,
// priceAPI: priceAPI,
// tracker: MockTransactionNotificationTracker(),
// );
//
// expect(await firo.initializeWallet(), true);
//
// final wallet = await Hive.openBox(testWalletId + "initializeWallet");
//
// var result = await wallet.get("addressBookEntries");
// expect(result, {});
//
// result = await wallet.get("blocked_tx_hashes");
// expect(result, ["0xdefault"]);
//
// result = await wallet.get("changeAddresses");
// expect(result, isA<List<String>>());
// expect(result.length, 1);
//
// result = await wallet.get("changeIndex");
// expect(result, 0);
//
// result = await wallet.get("id");
// expect(result, testWalletId + "initializeWallet");
//
// result = await wallet.get("jindex");
// expect(result, []);
//
// result = await wallet.get("mintIndex");
// expect(result, 0);
//
// result = await wallet.get("preferredFiatCurrency");
// expect(result, null);
//
// result = await wallet.get("receivingAddresses");
// expect(result, isA<List<String>>());
// expect(result.length, 1);
//
// result = await wallet.get("receivingIndex");
// expect(result, 0);
// });
test("getAllTxsToWatch", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
final tracker = MockTransactionNotificationTracker();
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}getAllTxsToWatch",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: tracker,
);
await firo.getAllTxsToWatch(txData, lTxData);
verify(tracker.wasNotifiedPending(
"51576e2230c2911a508aabb85bb50045f04b8dc958790ce2372986c3ebbe7d3e"))
.called(1);
verify(tracker.wasNotifiedPending(
"FF7e74edecd8c14ff5a8ddeb54e9e5e9c7c301c6f76f0ac1ac8119c6cc15e35"))
.called(1);
verify(tracker.wasNotifiedPending(
"f4217364cbe6a81ef7ecaaeba0a6d6b576a9850b3e891fa7b88ed4927c505218"))
.called(1);
// expect(firo.unconfirmedTxs, {
// "51576e2230c2911a508aabb85bb50045f04b8dc958790ce2372986c3ebbe7d3e",
// 'FF7e74edecd8c14ff5a8ddeb54e9e5e9c7c301c6f76f0ac1ac8119c6cc15e35',
// "f4217364cbe6a81ef7ecaaeba0a6d6b576a9850b3e891fa7b88ed4927c505218"
// });
});
group("refreshIfThereIsNewData", () {
test("refreshIfThereIsNewData with no unconfirmed transactions",
() async {
TestWidgetsFlutterBinding.ensureInitialized();
const MethodChannel('uk.spiralarm.flutter/devicelocale')
.setMockMethodCallHandler((methodCall) async => 'en_US');
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
// mock history calls
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash0))
.thenAnswer((_) async => SampleGetHistoryData.data0);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash1))
.thenAnswer((_) async => SampleGetHistoryData.data1);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash2))
.thenAnswer((_) async => SampleGetHistoryData.data2);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash3))
.thenAnswer((_) async => SampleGetHistoryData.data3);
// mock transaction calls
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash0,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData0);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash1,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData1);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash2,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData2);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash3,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData3);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash4,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData4);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash5,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData5);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash6,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData6);
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}refreshIfThereIsNewData",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
// firo.unconfirmedTxs = {};
final wallet =
await Hive.openBox(testWalletId + "refreshIfThereIsNewData");
await wallet.put('receivingAddresses', [
"a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg",
"aPjLWDTPQsoPHUTxKBNRzoebDALj3eTcfh",
"aKmXfS7nEZdqWBGRdAXcyMoEoKhZQDPBoq",
]);
await wallet.put('changeAddresses', [
"a5V5r6We6mNZzWJwGwEeRML3mEYLjvK39w",
]);
final result = await firo.refreshIfThereIsNewData();
expect(result, false);
});
test("refreshIfThereIsNewData with two unconfirmed transactions",
() async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
when(client.getTransaction(txHash: SampleGetTransactionData.txHash6))
.thenAnswer((_) async => SampleGetTransactionData.txData6);
when(client.getTransaction(
txHash:
"f4217364cbe6a81ef7ecaaeba0a6d6b576a9850b3e891fa7b88ed4927c505218"))
.thenAnswer((_) async => SampleGetTransactionData.txData7);
final firo = FiroWallet(
walletName: testWalletName,
walletId: testWalletId + "refreshIfThereIsNewData",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
await firo.getAllTxsToWatch(txData, lTxData);
final result = await firo.refreshIfThereIsNewData();
expect(result, true);
});
});
test("submitHexToNetwork", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
when(client.broadcastTransaction(
rawTx:
"0200000001ddba3ce3a3ab07d342183fa6743d3b620149c1db26efa239323384d82f9e2859010000006a47304402207d4982586eb4b0de17ee88f8eae4aaf7bc68590ae048e67e75932fe84a73f7f3022011392592558fb39d8c132234ad34a2c7f5071d2dab58d8c9220d343078413497012102f123ab9dbd627ab572de7cd77eda6e3781213a2ef4ab5e0d6e87f1c0d944b2caffffffff01e42e000000000000a5c5bc76bae786dc3a7d939757c34e15994d403bdaf418f9c9fa6eb90ac6e8ffc3550100772ad894f285988789669acd69ba695b9485c90141d7833209d05bcdad1b898b0000f5cba1a513dd97d81f89159f2be6eb012e987335fffa052c1fbef99550ba488fb6263232e7a0430c0a3ca8c728a5d8c8f2f985c8b586024a0f488c73130bd5ec9e7c23571f23c2d34da444ecc2fb65a12cee2ad3b8d3fcc337a2c2a45647eb43cff50600"))
.thenAnswer((_) async =>
"b36161c6e619395b3d40a851c45c1fef7a5c541eed911b5524a66c5703a689c9");
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}submitHexToNetwork",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
final txid = await firo.submitHexToNetwork(
"0200000001ddba3ce3a3ab07d342183fa6743d3b620149c1db26efa239323384d82f9e2859010000006a47304402207d4982586eb4b0de17ee88f8eae4aaf7bc68590ae048e67e75932fe84a73f7f3022011392592558fb39d8c132234ad34a2c7f5071d2dab58d8c9220d343078413497012102f123ab9dbd627ab572de7cd77eda6e3781213a2ef4ab5e0d6e87f1c0d944b2caffffffff01e42e000000000000a5c5bc76bae786dc3a7d939757c34e15994d403bdaf418f9c9fa6eb90ac6e8ffc3550100772ad894f285988789669acd69ba695b9485c90141d7833209d05bcdad1b898b0000f5cba1a513dd97d81f89159f2be6eb012e987335fffa052c1fbef99550ba488fb6263232e7a0430c0a3ca8c728a5d8c8f2f985c8b586024a0f488c73130bd5ec9e7c23571f23c2d34da444ecc2fb65a12cee2ad3b8d3fcc337a2c2a45647eb43cff50600");
expect(txid,
"b36161c6e619395b3d40a851c45c1fef7a5c541eed911b5524a66c5703a689c9");
});
test("fillAddresses", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}fillAddresses",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
await firo.fillAddresses(FillAddressesParams.mnemonic);
final rcv = await secureStore.read(
key: "${testWalletId}fillAddresses_receiveDerivations");
final chg = await secureStore.read(
key: "${testWalletId}fillAddresses_changeDerivations");
final receiveDerivations =
Map<String, dynamic>.from(jsonDecode(rcv as String) as Map);
final changeDerivations =
Map<String, dynamic>.from(jsonDecode(chg as String) as Map);
expect(receiveDerivations.toString(),
FillAddressesParams.expectedReceiveDerivationsString);
expect(changeDerivations.toString(),
FillAddressesParams.expectedChangeDerivationsString);
});
// the above test needs to pass in order for this test to pass
test("buildMintTransaction", () async {
TestWidgetsFlutterBinding.ensureInitialized();
const MethodChannel('uk.spiralarm.flutter/devicelocale')
.setMockMethodCallHandler((methodCall) async => 'en_US');
List<UtxoObject> utxos = [
UtxoObject(
txid: BuildMintTxTestParams.utxoInfo["txid"] as String,
vout: BuildMintTxTestParams.utxoInfo["vout"] as int,
value: BuildMintTxTestParams.utxoInfo["value"] as int,
txName: '',
status: Status(
confirmed: false,
blockHash: "",
blockHeight: -1,
blockTime: 42,
confirmations: 0),
isCoinbase: false,
blocked: false,
fiatWorth: '',
)
];
const sats = 9658;
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
await secureStore.write(
key: "${testWalletId}buildMintTransaction_mnemonic",
value: BuildMintTxTestParams.mnemonic);
when(cachedClient.getTransaction(
txHash: BuildMintTxTestParams.utxoInfo["txid"] as String,
coin: Coin.firo,
)).thenAnswer((_) async => BuildMintTxTestParams.cachedClientResponse);
when(client.getBlockHeadTip()).thenAnswer(
(_) async => {"height": 455873, "hex": "this value not used here"});
final priceAPI = MockPriceAPI();
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}buildMintTransaction",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
final wallet = await Hive.openBox("${testWalletId}buildMintTransaction");
await wallet.put("mintIndex", 0);
await secureStore.write(
key: "${testWalletId}buildMintTransaction_receiveDerivations",
value: jsonEncode(BuildMintTxTestParams.receiveDerivations));
await secureStore.write(
key: "${testWalletId}buildMintTransaction_changeDerivations",
value: jsonEncode(BuildMintTxTestParams.changeDerivations));
List<Map<String, dynamic>> mintsWithoutFee =
await firo.createMintsFromAmount(sats);
final result =
await firo.buildMintTransaction(utxos, sats, mintsWithoutFee);
expect(result["txHex"], isA<String>());
});
test("recoverFromMnemonic succeeds", () async {
TestWidgetsFlutterBinding.ensureInitialized();
const MethodChannel('uk.spiralarm.flutter/devicelocale')
.setMockMethodCallHandler((methodCall) async => 'en_US');
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
// mock electrumx client calls
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.getLatestCoinId()).thenAnswer((_) async => 1);
// when(client.getCoinsForRecovery(setId: 1))
// .thenAnswer((_) async => getCoinsForRecoveryResponse);
when(cachedClient.getUsedCoinSerials(
coin: Coin.firo,
)).thenAnswer(
(_) async => GetUsedSerialsSampleData.serials["serials"] as List);
when(cachedClient.getAnonymitySet(
groupId: "1",
coin: Coin.firo,
)).thenAnswer(
(_) async => GetAnonymitySetSampleData.data,
);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash8,
coin: Coin.firo,
)).thenAnswer((_) async {
return SampleGetTransactionData.txData8;
});
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash9,
coin: Coin.firo,
)).thenAnswer((_) async {
return SampleGetTransactionData.txData9;
});
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash7,
coin: Coin.firo,
)).thenAnswer((_) async {
return SampleGetTransactionData.txData7;
});
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}recoverFromMnemonic",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
// pre grab derivations in order to set up mock calls needed later on
await firo.fillAddresses(TEST_MNEMONIC);
final wallet =
await Hive.openBox<dynamic>("${testWalletId}recoverFromMnemonic");
final rcv = await secureStore.read(
key: "${testWalletId}recoverFromMnemonic_receiveDerivations");
final chg = await secureStore.read(
key: "${testWalletId}recoverFromMnemonic_changeDerivations");
final receiveDerivations =
Map<String, dynamic>.from(jsonDecode(rcv as String) as Map);
final changeDerivations =
Map<String, dynamic>.from(jsonDecode(chg as String) as Map);
for (int i = 0; i < receiveDerivations.length; i++) {
final receiveHash = AddressUtils.convertToScriptHash(
receiveDerivations["$i"]!["address"] as String, firoNetwork);
final changeHash = AddressUtils.convertToScriptHash(
changeDerivations["$i"]!["address"] as String, firoNetwork);
List<Map<String, dynamic>> data;
switch (receiveHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: receiveHash))
.thenAnswer((_) async => data);
switch (changeHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: changeHash))
.thenAnswer((_) async => data);
}
await firo.recoverFromMnemonic(
mnemonic: TEST_MNEMONIC,
maxUnusedAddressGap: 20,
height: 0,
maxNumberOfIndexesToCheck: 1000);
final receivingAddresses = await wallet.get('receivingAddresses');
expect(receivingAddresses, ["a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg"]);
final changeAddresses = await wallet.get('changeAddresses');
expect(changeAddresses, ["a5V5r6We6mNZzWJwGwEeRML3mEYLjvK39w"]);
final receivingIndex = await wallet.get('receivingIndex');
expect(receivingIndex, 0);
final changeIndex = await wallet.get('changeIndex');
expect(changeIndex, 0);
final _rcv = await secureStore.read(
key: "${testWalletId}recoverFromMnemonic_receiveDerivations");
final _chg = await secureStore.read(
key: "${testWalletId}recoverFromMnemonic_changeDerivations");
final _receiveDerivations =
Map<String, dynamic>.from(jsonDecode(_rcv as String) as Map);
final _changeDerivations =
Map<String, dynamic>.from(jsonDecode(_chg as String) as Map);
expect(_receiveDerivations.length, 190);
expect(_changeDerivations.length, 190);
final mintIndex = await wallet.get('mintIndex');
expect(mintIndex, 8);
final lelantusCoins = await wallet.get('_lelantus_coins');
expect(lelantusCoins.length, 1);
final lcoin = lelantusCoins[
"36c92daa4005d368e28cea917fdb2c1e7069319a4a79fb2ff45c089100680232"]
as LelantusCoin;
expect(lcoin.index, 1);
expect(lcoin.value, 9658);
expect(lcoin.publicCoin,
"7fd927efbea0a9e4ba299209aaee610c63359857596be0a2da276011a0baa84a0000");
expect(lcoin.txId,
"36c92daa4005d368e28cea917fdb2c1e7069319a4a79fb2ff45c089100680232");
expect(lcoin.anonymitySetId, 1);
expect(lcoin.isUsed, true);
final jIndex = await wallet.get('jindex');
expect(jIndex, []);
final lelantusTxModel = await wallet.get('latest_lelantus_tx_model');
expect(lelantusTxModel.getAllTransactions().length, 0);
}, timeout: const Timeout(Duration(minutes: 3)));
test("fullRescan succeeds", () async {
TestWidgetsFlutterBinding.ensureInitialized();
const MethodChannel('uk.spiralarm.flutter/devicelocale')
.setMockMethodCallHandler((methodCall) async => 'en_US');
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
await secureStore.write(
key: '${testWalletId}fullRescan_mnemonic', value: TEST_MNEMONIC);
// mock electrumx client calls
when(client.getLatestCoinId()).thenAnswer((_) async => 1);
// when(client.getCoinsForRecovery(setId: 1))
// .thenAnswer((_) async => getCoinsForRecoveryResponse);
when(client.getUsedCoinSerials(startNumber: 0))
.thenAnswer((_) async => GetUsedSerialsSampleData.serials);
when(cachedClient.clearSharedTransactionCache(coin: Coin.firo))
.thenAnswer((_) async => {});
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}fullRescan",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
// pre grab derivations in order to set up mock calls needed later on
await firo.fillAddresses(TEST_MNEMONIC);
final wallet = await Hive.openBox(testWalletId + "fullRescan");
final rcv = await secureStore.read(
key: "${testWalletId}fullRescan_receiveDerivations");
final chg = await secureStore.read(
key: "${testWalletId}fullRescan_changeDerivations");
final receiveDerivations =
Map<String, dynamic>.from(jsonDecode(rcv as String) as Map);
final changeDerivations =
Map<String, dynamic>.from(jsonDecode(chg as String) as Map);
for (int i = 0; i < receiveDerivations.length; i++) {
final receiveHash = AddressUtils.convertToScriptHash(
receiveDerivations["$i"]!["address"] as String, firoNetwork);
final changeHash = AddressUtils.convertToScriptHash(
changeDerivations["$i"]!["address"] as String, firoNetwork);
List<Map<String, dynamic>> data;
switch (receiveHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: receiveHash))
.thenAnswer((_) async => data);
switch (changeHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: changeHash))
.thenAnswer((_) async => data);
}
await firo.fullRescan(20, 1000);
final receivingAddresses = await wallet.get('receivingAddresses');
expect(receivingAddresses, ["a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg"]);
final changeAddresses = await wallet.get('changeAddresses');
expect(changeAddresses, ["a5V5r6We6mNZzWJwGwEeRML3mEYLjvK39w"]);
final receivingIndex = await wallet.get('receivingIndex');
expect(receivingIndex, 0);
final changeIndex = await wallet.get('changeIndex');
expect(changeIndex, 0);
final _rcv = await secureStore.read(
key: "${testWalletId}fullRescan_receiveDerivations");
final _chg = await secureStore.read(
key: "${testWalletId}fullRescan_changeDerivations");
final _receiveDerivations =
Map<String, dynamic>.from(jsonDecode(_rcv as String) as Map);
final _changeDerivations =
Map<String, dynamic>.from(jsonDecode(_chg as String) as Map);
expect(_receiveDerivations.length, 150);
expect(_changeDerivations.length, 150);
final mintIndex = await wallet.get('mintIndex');
expect(mintIndex, 2);
final lelantusCoins = await wallet.get('_lelantus_coins');
expect(lelantusCoins.length, 1);
final lcoin = lelantusCoins[
"36c92daa4005d368e28cea917fdb2c1e7069319a4a79fb2ff45c089100680232"]
as LelantusCoin;
expect(lcoin.index, 1);
expect(lcoin.value, 9658);
expect(lcoin.publicCoin,
"7fd927efbea0a9e4ba299209aaee610c63359857596be0a2da276011a0baa84a0000");
expect(lcoin.txId,
"36c92daa4005d368e28cea917fdb2c1e7069319a4a79fb2ff45c089100680232");
expect(lcoin.anonymitySetId, 1);
expect(lcoin.isUsed, true);
final jIndex = await wallet.get('jindex');
expect(jIndex, []);
final lelantusTxModel = await wallet.get('latest_lelantus_tx_model');
expect(lelantusTxModel.getAllTransactions().length, 0);
}, timeout: Timeout(Duration(minutes: 3)));
test("fullRescan fails", () async {
TestWidgetsFlutterBinding.ensureInitialized();
const MethodChannel('uk.spiralarm.flutter/devicelocale')
.setMockMethodCallHandler((methodCall) async => 'en_US');
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
await secureStore.write(
key: '${testWalletId}fullRescan_mnemonic', value: TEST_MNEMONIC);
// mock electrumx client calls
when(client.getLatestCoinId()).thenAnswer((_) async => 1);
// when(client.getCoinsForRecovery(setId: 1))
// .thenAnswer((_) async => getCoinsForRecoveryResponse);
when(client.getUsedCoinSerials(startNumber: 0))
.thenAnswer((_) async => GetUsedSerialsSampleData.serials);
when(cachedClient.clearSharedTransactionCache(coin: Coin.firo))
.thenAnswer((_) async => {});
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}fullRescan",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
// pre grab derivations in order to set up mock calls needed later on
await firo.fillAddresses(TEST_MNEMONIC);
final wallet = await Hive.openBox<dynamic>("${testWalletId}fullRescan");
final rcv = await secureStore.read(
key: "${testWalletId}fullRescan_receiveDerivations");
final chg = await secureStore.read(
key: "${testWalletId}fullRescan_changeDerivations");
final receiveDerivations =
Map<String, dynamic>.from(jsonDecode(rcv as String) as Map);
final changeDerivations =
Map<String, dynamic>.from(jsonDecode(chg as String) as Map);
for (int i = 0; i < receiveDerivations.length; i++) {
final receiveHash = AddressUtils.convertToScriptHash(
receiveDerivations["$i"]!["address"] as String, firoNetwork);
final changeHash = AddressUtils.convertToScriptHash(
changeDerivations["$i"]!["address"] as String, firoNetwork);
List<Map<String, dynamic>> data;
switch (receiveHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: receiveHash))
.thenAnswer((_) async => data);
switch (changeHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: changeHash))
.thenAnswer((_) async => data);
}
when(client.getLatestCoinId()).thenThrow(Exception());
bool didThrow = false;
try {
await firo.fullRescan(20, 1000);
} catch (e) {
didThrow = true;
}
expect(didThrow, true);
final receivingAddresses = await wallet.get('receivingAddresses');
expect(receivingAddresses, null);
final changeAddresses = await wallet.get('changeAddresses');
expect(changeAddresses, null);
final receivingIndex = await wallet.get('receivingIndex');
expect(receivingIndex, null);
final changeIndex = await wallet.get('changeIndex');
expect(changeIndex, null);
final _rcv = await secureStore.read(
key: "${testWalletId}fullRescan_receiveDerivations");
final _chg = await secureStore.read(
key: "${testWalletId}fullRescan_changeDerivations");
final _receiveDerivations =
Map<String, dynamic>.from(jsonDecode(_rcv as String) as Map);
final _changeDerivations =
Map<String, dynamic>.from(jsonDecode(_chg as String) as Map);
expect(_receiveDerivations.length, 40);
expect(_changeDerivations.length, 40);
final mintIndex = await wallet.get('mintIndex');
expect(mintIndex, null);
final lelantusCoins = await wallet.get('_lelantus_coins');
expect(lelantusCoins, null);
final jIndex = await wallet.get('jindex');
expect(jIndex, null);
final lelantusTxModel = await wallet.get('latest_lelantus_tx_model');
expect(lelantusTxModel, null);
}, timeout: const Timeout(Duration(minutes: 3)));
test("recoverFromMnemonic then fullRescan", () async {
TestWidgetsFlutterBinding.ensureInitialized();
const MethodChannel('uk.spiralarm.flutter/devicelocale')
.setMockMethodCallHandler((methodCall) async => 'en_US');
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
// mock electrumx client calls
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.getLatestCoinId()).thenAnswer((_) async => 1);
// when(client.getCoinsForRecovery(setId: 1))
// .thenAnswer((_) async => getCoinsForRecoveryResponse);
when(client.getUsedCoinSerials(startNumber: 0))
.thenAnswer((_) async => GetUsedSerialsSampleData.serials);
when(cachedClient.clearSharedTransactionCache(coin: Coin.firo))
.thenAnswer((_) async => {});
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}recoverFromMnemonic",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
// pre grab derivations in order to set up mock calls needed later on
await firo.fillAddresses(TEST_MNEMONIC);
final wallet =
await Hive.openBox<dynamic>("${testWalletId}recoverFromMnemonic");
final rcv = await secureStore.read(
key: "${testWalletId}recoverFromMnemonic_receiveDerivations");
final chg = await secureStore.read(
key: "${testWalletId}recoverFromMnemonic_changeDerivations");
final receiveDerivations =
Map<String, dynamic>.from(jsonDecode(rcv as String) as Map);
final changeDerivations =
Map<String, dynamic>.from(jsonDecode(chg as String) as Map);
for (int i = 0; i < receiveDerivations.length; i++) {
final receiveHash = AddressUtils.convertToScriptHash(
receiveDerivations["$i"]!["address"] as String, firoNetwork);
final changeHash = AddressUtils.convertToScriptHash(
changeDerivations["$i"]!["address"] as String, firoNetwork);
List<Map<String, dynamic>> data;
switch (receiveHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: receiveHash))
.thenAnswer((_) async => data);
switch (changeHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: changeHash))
.thenAnswer((_) async => data);
}
await firo.recoverFromMnemonic(
mnemonic: TEST_MNEMONIC,
maxUnusedAddressGap: 20,
maxNumberOfIndexesToCheck: 1000,
height: 0);
final receivingAddresses = await wallet.get('receivingAddresses');
expect(receivingAddresses, ["a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg"]);
final changeAddresses = await wallet.get('changeAddresses');
expect(changeAddresses, ["a5V5r6We6mNZzWJwGwEeRML3mEYLjvK39w"]);
final receivingIndex = await wallet.get('receivingIndex');
expect(receivingIndex, 0);
final changeIndex = await wallet.get('changeIndex');
expect(changeIndex, 0);
final _rcv = await secureStore.read(
key: "${testWalletId}recoverFromMnemonic_receiveDerivations");
final _chg = await secureStore.read(
key: "${testWalletId}recoverFromMnemonic_changeDerivations");
final _receiveDerivations =
Map<String, dynamic>.from(jsonDecode(_rcv as String) as Map);
final _changeDerivations =
Map<String, dynamic>.from(jsonDecode(_chg as String) as Map);
expect(_receiveDerivations.length, 190);
expect(_changeDerivations.length, 190);
final mintIndex = await wallet.get('mintIndex');
expect(mintIndex, 2);
final lelantusCoins = await wallet.get('_lelantus_coins');
expect(lelantusCoins.length, 1);
final lcoin = lelantusCoins[
"36c92daa4005d368e28cea917fdb2c1e7069319a4a79fb2ff45c089100680232"]
as LelantusCoin;
expect(lcoin.index, 1);
expect(lcoin.value, 9658);
expect(lcoin.publicCoin,
"7fd927efbea0a9e4ba299209aaee610c63359857596be0a2da276011a0baa84a0000");
expect(lcoin.txId,
"36c92daa4005d368e28cea917fdb2c1e7069319a4a79fb2ff45c089100680232");
expect(lcoin.anonymitySetId, 1);
expect(lcoin.isUsed, true);
final jIndex = await wallet.get('jindex');
expect(jIndex, []);
final lelantusTxModel = await wallet.get('latest_lelantus_tx_model');
expect(lelantusTxModel.getAllTransactions().length, 0);
await firo.fullRescan(20, 1000);
final _receivingAddresses = await wallet.get('receivingAddresses');
expect(_receivingAddresses, ["a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg"]);
final _changeAddresses = await wallet.get('changeAddresses');
expect(_changeAddresses, ["a5V5r6We6mNZzWJwGwEeRML3mEYLjvK39w"]);
final _receivingIndex = await wallet.get('receivingIndex');
expect(_receivingIndex, 0);
final _changeIndex = await wallet.get('changeIndex');
expect(_changeIndex, 0);
final __rcv = await secureStore.read(
key: "${testWalletId}recoverFromMnemonic_receiveDerivations");
final __chg = await secureStore.read(
key: "${testWalletId}recoverFromMnemonic_changeDerivations");
final __receiveDerivations =
Map<String, dynamic>.from(jsonDecode(__rcv as String) as Map);
final __changeDerivations =
Map<String, dynamic>.from(jsonDecode(__chg as String) as Map);
expect(__receiveDerivations.length, 150);
expect(__changeDerivations.length, 150);
final _mintIndex = await wallet.get('mintIndex');
expect(_mintIndex, 2);
final _lelantusCoins = await wallet.get('_lelantus_coins');
expect(_lelantusCoins.length, 1);
final _lcoin = lelantusCoins[
"36c92daa4005d368e28cea917fdb2c1e7069319a4a79fb2ff45c089100680232"]
as LelantusCoin;
expect(_lcoin.index, 1);
expect(_lcoin.value, 9658);
expect(_lcoin.publicCoin,
"7fd927efbea0a9e4ba299209aaee610c63359857596be0a2da276011a0baa84a0000");
expect(_lcoin.txId,
"36c92daa4005d368e28cea917fdb2c1e7069319a4a79fb2ff45c089100680232");
expect(_lcoin.anonymitySetId, 1);
expect(_lcoin.isUsed, true);
final _jIndex = await wallet.get('jindex');
expect(_jIndex, []);
final _lelantusTxModel = await wallet.get('latest_lelantus_tx_model');
expect(_lelantusTxModel.getAllTransactions().length, 0);
}, timeout: const Timeout(Duration(minutes: 6)));
test("recoverFromMnemonic fails testnet", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
// mock electrumx client calls
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": []
});
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}recoverFromMnemonic fails testnet",
coin: Coin.firoTestNet,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
expect(
() async => await firo.recoverFromMnemonic(
mnemonic: TEST_MNEMONIC,
maxUnusedAddressGap: 20,
maxNumberOfIndexesToCheck: 1000,
height: 0),
throwsA(isA<Exception>()));
}, timeout: const Timeout(Duration(minutes: 3)));
test("recoverFromMnemonic fails mainnet", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
// mock electrumx client calls
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": []
});
final firo = FiroWallet(
walletName: testWalletName,
walletId: testWalletId + "recoverFromMnemonic fails mainnet",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
expect(
() async => await firo.recoverFromMnemonic(
mnemonic: TEST_MNEMONIC,
maxUnusedAddressGap: 20,
height: 0,
maxNumberOfIndexesToCheck: 1000),
throwsA(isA<Exception>()));
});
test("incrementAddressIndexForChain receiving", () async {
final firo = FiroWallet(
walletId: "${testWalletId}incrementAddressIndexForChain receiving",
walletName: testWalletName,
coin: Coin.firo,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
final wallet = await Hive.openBox<dynamic>(
"${testWalletId}incrementAddressIndexForChain receiving");
await wallet.put("receivingIndex", 1);
await expectLater(() async => await firo.incrementAddressIndexForChain(0),
returnsNormally);
expect(wallet.get("receivingIndex"), 2);
});
test("incrementAddressIndexForChain change", () async {
final firo = FiroWallet(
walletId: "${testWalletId}incrementAddressIndexForChain change",
walletName: testWalletName,
coin: Coin.firo,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
final wallet = await Hive.openBox(
"${testWalletId}incrementAddressIndexForChain change");
await wallet.put("changeIndex", 1);
await expectLater(() async => await firo.incrementAddressIndexForChain(1),
returnsNormally);
expect(wallet.get("changeIndex"), 2);
});
test("addToAddressesArrayForChain receiving", () async {
final firo = FiroWallet(
walletId: "${testWalletId}addToAddressesArrayForChain receiving",
walletName: testWalletName,
coin: Coin.firo,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
final wallet = await Hive.openBox<dynamic>(
"${testWalletId}addToAddressesArrayForChain receiving");
await expectLater(
() async =>
await firo.addToAddressesArrayForChain("Some Address String", 0),
returnsNormally);
expect(wallet.get("receivingAddresses"), ["Some Address String"]);
});
test("addToAddressesArrayForChain change", () async {
final firo = FiroWallet(
walletId: "${testWalletId}addToAddressesArrayForChain change",
walletName: testWalletName,
coin: Coin.firo,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
final wallet = await Hive.openBox<dynamic>(
"${testWalletId}addToAddressesArrayForChain change");
await wallet.put("changeAddresses", ["some address A"]);
await expectLater(
() async =>
await firo.addToAddressesArrayForChain("Some Address B", 1),
returnsNormally);
expect(
wallet.get("changeAddresses"), ["some address A", "Some Address B"]);
});
test("checkReceivingAddressForTransactions fails", () async {
final firo = FiroWallet(
walletId: "${testWalletId}checkReceivingAddressForTransactions fails",
walletName: testWalletName,
coin: Coin.firo,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
await expectLater(
() async => await firo.checkReceivingAddressForTransactions(),
throwsA(isA<NoSuchMethodError>()));
});
test("checkReceivingAddressForTransactions numtxs >= 1", () async {
final client = MockElectrumX();
final secureStore = FakeSecureStorage();
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash1))
.thenAnswer((_) async => SampleGetHistoryData.data1);
final firo = FiroWallet(
walletId:
"${testWalletId}checkReceivingAddressForTransactions numtxs >= 1",
walletName: testWalletName,
coin: Coin.firo,
client: client,
cachedClient: MockCachedElectrumX(),
secureStore: secureStore,
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
final wallet = await Hive.openBox<dynamic>(
"${testWalletId}checkReceivingAddressForTransactions numtxs >= 1");
await secureStore.write(
key:
"${testWalletId}checkReceivingAddressForTransactions numtxs >= 1_mnemonic",
value: TEST_MNEMONIC);
await wallet
.put("receivingAddresses", ["aPjLWDTPQsoPHUTxKBNRzoebDALj3eTcfh"]);
await wallet.put("receivingIndex", 1);
await firo.checkReceivingAddressForTransactions();
expect(await wallet.get("receivingIndex"), 2);
expect((await wallet.get("receivingAddresses")).length, 2);
});
test("getLatestSetId", () async {
final client = MockElectrumX();
when(client.getLatestCoinId()).thenAnswer((_) async => 1);
final firo = FiroWallet(
walletId: testWalletId + "exit",
walletName: testWalletName,
coin: Coin.firo,
client: client,
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
final setId = await firo.getLatestSetId();
expect(setId, 1);
});
// test("getSetData", () async {
// final client = MockElectrumX();
//
// when(client.getCoinsForRecovery(setId: 1))
// .thenAnswer((_) async => getCoinsForRecoveryResponse);
//
// final firo = FiroWallet(
// walletId: testWalletId + "exit",
// walletName: testWalletName,
// networkType: firoNetworkType,
// client: client,
// cachedClient: MockCachedElectrumX(),
// secureStore: FakeSecureStorage(),
// priceAPI: MockPriceAPI(),
// tracker: MockTransactionNotificationTracker(),
// );
//
// final setData = await firo.getSetData(1);
// expect(setData, getCoinsForRecoveryResponse);
// });
test("getUsedCoinSerials", () async {
final client = MockElectrumX();
when(client.getUsedCoinSerials(startNumber: 0))
.thenAnswer((_) async => GetUsedSerialsSampleData.serials);
final firo = FiroWallet(
walletId: testWalletId + "getUsedCoinSerials",
walletName: testWalletName,
coin: Coin.firo,
client: client,
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
final serials = await firo.getUsedCoinSerials();
expect(serials, GetUsedSerialsSampleData.serials);
});
test("refresh", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
// set mnemonic
await secureStore.write(
key: "${testWalletId}refresh_mnemonic",
value: RefreshTestParams.mnemonic);
// mock electrumx client calls
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.getLatestCoinId()).thenAnswer((_) async => 1);
// when(client.getCoinsForRecovery(setId: 1))
// .thenAnswer((_) async => getCoinsForRecoveryResponse);
when(client.getUsedCoinSerials(startNumber: 0))
.thenAnswer((_) async => GetUsedSerialsSampleData.serials);
when(client.getFeeRate()).thenAnswer((_) async => {"rate": 1000});
// mock history calls
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash0))
.thenAnswer((_) async => SampleGetHistoryData.data0);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash1))
.thenAnswer((_) async => SampleGetHistoryData.data1);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash2))
.thenAnswer((_) async => SampleGetHistoryData.data2);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash3))
.thenAnswer((_) async => SampleGetHistoryData.data3);
// mock transaction calls
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash0,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData0);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash1,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData1);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash2,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData2);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash3,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData3);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash4,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData4);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash5,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData5);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash6,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData6);
// mock utxo calls
when(client.getUTXOs(scripthash: anyNamed("scripthash")))
.thenAnswer((_) async => []);
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}refresh",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
final wallet = await Hive.openBox<dynamic>("${testWalletId}refresh");
await wallet.put(
'receivingAddresses', RefreshTestParams.receivingAddresses);
await wallet.put('changeAddresses', RefreshTestParams.changeAddresses);
// set timer to non null so a periodic timer isn't created
firo.timer = Timer(const Duration(), () {});
await firo.refresh();
// kill timer and listener
await firo.exit();
}, timeout: const Timeout(Duration(minutes: 3)));
test("send succeeds", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
String expectedTxid = "-1";
when(client.getBlockHeadTip()).thenAnswer(
(_) async => {"height": 459185, "hex": "... some block hex ..."});
when(client.broadcastTransaction(rawTx: anyNamed("rawTx")))
.thenAnswer((realInvocation) async {
final rawTx = realInvocation.namedArguments[Symbol("rawTx")] as String;
final rawTxData = Format.stringToUint8List(rawTx);
final hash = sha256
.convert(sha256.convert(rawTxData.toList(growable: false)).bytes);
final reversedBytes =
Uint8List.fromList(hash.bytes.reversed.toList(growable: false));
final txid = Format.uint8listToString(reversedBytes);
expectedTxid = txid;
return txid;
});
//
// when(cachedClient.getAnonymitySet(
// groupId: "1",
// coin: Coin.firo,
// ,
// )).thenAnswer((_) async => GetAnonymitySetSampleData.finalData);
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
// mock transaction calls
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash0,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData0);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash1,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData1);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash2,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData2);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash3,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData3);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash4,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData4);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash5,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData5);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash6,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData6);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash7,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData7);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash8,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData8);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash9,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData9);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash10,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData10);
final firo = FiroWallet(
walletId: "${testWalletId}send",
walletName: testWalletName,
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
// set mnemonic
await secureStore.write(
key: "${testWalletId}send_mnemonic", value: TEST_MNEMONIC);
// set timer to non null so a periodic timer isn't created
firo.timer = Timer(const Duration(), () {});
// build sending wallet
await firo.fillAddresses(TEST_MNEMONIC);
final wallet = await Hive.openBox<dynamic>("${testWalletId}send");
final rcv =
await secureStore.read(key: "${testWalletId}send_receiveDerivations");
final chg =
await secureStore.read(key: "${testWalletId}send_changeDerivations");
final receiveDerivations =
Map<String, dynamic>.from(jsonDecode(rcv as String) as Map);
final changeDerivations =
Map<String, dynamic>.from(jsonDecode(chg as String) as Map);
for (int i = 0; i < receiveDerivations.length; i++) {
final receiveHash = AddressUtils.convertToScriptHash(
receiveDerivations["$i"]!["address"] as String, firoNetwork);
final changeHash = AddressUtils.convertToScriptHash(
changeDerivations["$i"]!["address"] as String, firoNetwork);
List<Map<String, dynamic>> data;
switch (receiveHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: receiveHash))
.thenAnswer((_) async => data);
switch (changeHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: changeHash))
.thenAnswer((_) async => data);
}
await wallet.put('_lelantus_coins', SampleLelantus.lelantusCoins);
await wallet.put('jindex', [2, 4, 6]);
await wallet.put('mintIndex', 8);
await wallet.put('receivingAddresses', [
"a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg",
"aPjLWDTPQsoPHUTxKBNRzoebDALj3eTcfh",
"aKmXfS7nEZdqWBGRdAXcyMoEoKhZQDPBoq"
]);
await wallet
.put('changeAddresses', ["a5V5r6We6mNZzWJwGwEeRML3mEYLjvK39w"]);
final result = await firo.send(
toAddress: "aHZJsucDrhr4Uzzx6XXrKnaTgLxsEAokvV", amount: 100);
expect(result, isA<String>());
expect(result, expectedTxid);
expect(result.length, 64);
}, timeout: const Timeout(Duration(minutes: 3)));
test("send fails due to insufficient balance", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
when(client.getBlockHeadTip()).thenAnswer(
(_) async => {"height": 459185, "hex": "... some block hex ..."});
when(client.broadcastTransaction(rawTx: anyNamed("rawTx")))
.thenAnswer((realInvocation) async {
final rawTx =
realInvocation.namedArguments[const Symbol("rawTx")] as String;
final rawTxData = Format.stringToUint8List(rawTx);
final hash = sha256
.convert(sha256.convert(rawTxData.toList(growable: false)).bytes);
final reversedBytes =
Uint8List.fromList(hash.bytes.reversed.toList(growable: false));
final txid = Format.uint8listToString(reversedBytes);
return txid;
});
// when(cachedClient.getAnonymitySet(
// groupId: "1",
// coin: Coin.firo,
// ,
// )).thenAnswer((_) async => GetAnonymitySetSampleData.finalData);
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
// mock transaction calls
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash0,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData0);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash1,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData1);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash2,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData2);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash3,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData3);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash4,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData4);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash5,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData5);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash6,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData6);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash7,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData7);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash8,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData8);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash9,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData9);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash10,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData10);
final firo = FiroWallet(
walletId: "${testWalletId}send",
coin: Coin.firo,
walletName: testWalletName,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
// set mnemonic
await secureStore.write(
key: "${testWalletId}send_mnemonic", value: TEST_MNEMONIC);
// set timer to non null so a periodic timer isn't created
firo.timer = Timer(const Duration(), () {});
// build sending wallet
await firo.fillAddresses(TEST_MNEMONIC);
final wallet = await Hive.openBox<dynamic>("${testWalletId}send");
final rcv =
await secureStore.read(key: "${testWalletId}send_receiveDerivations");
final chg =
await secureStore.read(key: "${testWalletId}send_changeDerivations");
final receiveDerivations =
Map<String, dynamic>.from(jsonDecode(rcv as String) as Map);
final changeDerivations =
Map<String, dynamic>.from(jsonDecode(chg as String) as Map);
for (int i = 0; i < receiveDerivations.length; i++) {
final receiveHash = AddressUtils.convertToScriptHash(
receiveDerivations["$i"]!["address"] as String, firoNetwork);
final changeHash = AddressUtils.convertToScriptHash(
changeDerivations["$i"]!["address"] as String, firoNetwork);
List<Map<String, dynamic>> data;
switch (receiveHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: receiveHash))
.thenAnswer((_) async => data);
switch (changeHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: changeHash))
.thenAnswer((_) async => data);
}
await wallet.put('_lelantus_coins', {});
await wallet.put('jindex', []);
await wallet.put('mintIndex', 0);
await wallet.put('receivingAddresses', [
"a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg",
"aPjLWDTPQsoPHUTxKBNRzoebDALj3eTcfh",
"aKmXfS7nEZdqWBGRdAXcyMoEoKhZQDPBoq"
]);
await wallet
.put('changeAddresses', ["a5V5r6We6mNZzWJwGwEeRML3mEYLjvK39w"]);
expect(
() async => await firo.send(
toAddress: "aHZJsucDrhr4Uzzx6XXrKnaTgLxsEAokvV", amount: 100),
throwsA(isA<Exception>()));
}, timeout: Timeout(const Duration(minutes: 3)));
test("send fails due to bad transaction created", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
when(client.getBlockHeadTip()).thenAnswer(
(_) async => {"height": 459185, "hex": "... some block hex ..."});
when(client.broadcastTransaction(rawTx: anyNamed("rawTx")))
.thenAnswer((_) async {
return "some bad txid";
});
// when(cachedClient.getAnonymitySet(
// groupId: "1",
// coin: Coin.firo,
// )).thenAnswer((_) async => GetAnonymitySetSampleData.finalData);
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
// mock transaction calls
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash0,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData0);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash1,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData1);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash2,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData2);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash3,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData3);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash4,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData4);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash5,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData5);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash6,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData6);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash7,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData7);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash8,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData8);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash9,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData9);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash10,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData10);
final firo = FiroWallet(
walletId: "${testWalletId}send",
coin: Coin.firo,
walletName: testWalletName,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
// set mnemonic
await secureStore.write(
key: "${testWalletId}send_mnemonic", value: TEST_MNEMONIC);
// set timer to non null so a periodic timer isn't created
firo.timer = Timer(const Duration(), () {});
// build sending wallet
await firo.fillAddresses(TEST_MNEMONIC);
final wallet = await Hive.openBox<dynamic>("${testWalletId}send");
final rcv =
await secureStore.read(key: "${testWalletId}send_receiveDerivations");
final chg =
await secureStore.read(key: "${testWalletId}send_changeDerivations");
final receiveDerivations =
Map<String, dynamic>.from(jsonDecode(rcv as String) as Map);
final changeDerivations =
Map<String, dynamic>.from(jsonDecode(chg as String) as Map);
for (int i = 0; i < receiveDerivations.length; i++) {
final receiveHash = AddressUtils.convertToScriptHash(
receiveDerivations["$i"]!["address"] as String, firoNetwork);
final changeHash = AddressUtils.convertToScriptHash(
changeDerivations["$i"]!["address"] as String, firoNetwork);
List<Map<String, dynamic>> data;
switch (receiveHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: receiveHash))
.thenAnswer((_) async => data);
switch (changeHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: changeHash))
.thenAnswer((_) async => data);
}
await wallet.put('_lelantus_coins', SampleLelantus.lelantusCoins);
await wallet.put('jindex', [2, 4, 6]);
await wallet.put('mintIndex', 8);
await wallet.put('receivingAddresses', [
"a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg",
"aPjLWDTPQsoPHUTxKBNRzoebDALj3eTcfh",
"aKmXfS7nEZdqWBGRdAXcyMoEoKhZQDPBoq"
]);
await wallet
.put('changeAddresses', ["a5V5r6We6mNZzWJwGwEeRML3mEYLjvK39w"]);
expect(
() async => await firo.send(
toAddress: "aHZJsucDrhr4Uzzx6XXrKnaTgLxsEAokvV", amount: 100),
throwsA(isA<Exception>()));
}, timeout: Timeout(const Duration(minutes: 3)));
test("wallet balances", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final priceAPI = MockPriceAPI();
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
// mock history calls
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash0))
.thenAnswer((_) async => SampleGetHistoryData.data0);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash1))
.thenAnswer((_) async => SampleGetHistoryData.data1);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash2))
.thenAnswer((_) async => SampleGetHistoryData.data2);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash3))
.thenAnswer((_) async => SampleGetHistoryData.data3);
// mock transaction calls
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash0,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData0);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash1,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData1);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash2,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData2);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash3,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData3);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash4,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData4);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash5,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData5);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash6,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData6);
final firo = FiroWallet(
walletId: "${testWalletId}wallet balances",
walletName: "pendingBalance wallet name",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: FakeSecureStorage(),
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
final wallet =
await Hive.openBox<dynamic>("${testWalletId}wallet balances");
await wallet.put('_lelantus_coins', SampleLelantus.lelantusCoins);
await wallet.put('jindex', [2, 4, 6]);
await wallet.put('mintIndex', 8);
await wallet.put('receivingAddresses', [
"a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg",
"aPjLWDTPQsoPHUTxKBNRzoebDALj3eTcfh",
"aKmXfS7nEZdqWBGRdAXcyMoEoKhZQDPBoq",
]);
await wallet.put('changeAddresses', [
"a5V5r6We6mNZzWJwGwEeRML3mEYLjvK39w",
]);
expect(await firo.pendingBalance, Decimal.zero);
expect(await firo.availableBalance, Decimal.parse("0.00021594"));
expect(await firo.totalBalance, Decimal.parse("0.00021594"));
});
test("wallet balance minus maxfee - wallet balance is zero", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final priceAPI = MockPriceAPI();
final secureStore = FakeSecureStorage();
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
// mock history calls
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash0))
.thenAnswer((_) async => SampleGetHistoryData.data0);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash1))
.thenAnswer((_) async => SampleGetHistoryData.data1);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash2))
.thenAnswer((_) async => SampleGetHistoryData.data2);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash3))
.thenAnswer((_) async => SampleGetHistoryData.data3);
// mock transaction calls
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash0,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData0);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash1,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData1);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash2,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData2);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash3,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData3);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash4,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData4);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash5,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData5);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash6,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData6);
final firo = FiroWallet(
walletId: "${testWalletId}wallet balance minus maxfee",
walletName: "pendingBalance wallet name",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
await secureStore.write(
key: "${testWalletId}wallet balance minus maxfee_mnemonic",
value: TEST_MNEMONIC);
final wallet = await Hive.openBox<dynamic>(
"${testWalletId}wallet balance minus maxfee");
await wallet.put('receivingAddresses', [
"a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg",
"aPjLWDTPQsoPHUTxKBNRzoebDALj3eTcfh",
"aKmXfS7nEZdqWBGRdAXcyMoEoKhZQDPBoq",
]);
await wallet.put('changeAddresses', [
"a5V5r6We6mNZzWJwGwEeRML3mEYLjvK39w",
]);
expect(await firo.maxFee, 0);
expect(await firo.balanceMinusMaxFee, Decimal.zero);
});
test("wallet balance minus maxfee - wallet balance is not zero", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final priceAPI = MockPriceAPI();
final secureStore = FakeSecureStorage();
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
// mock history calls
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash0))
.thenAnswer((_) async => SampleGetHistoryData.data0);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash1))
.thenAnswer((_) async => SampleGetHistoryData.data1);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash2))
.thenAnswer((_) async => SampleGetHistoryData.data2);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash3))
.thenAnswer((_) async => SampleGetHistoryData.data3);
// mock transaction calls
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash0,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData0);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash1,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData1);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash2,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData2);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash3,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData3);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash4,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData4);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash5,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData5);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash6,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData6);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash7,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData7);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash8,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData8);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash9,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData9);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash10,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData10);
final firo = FiroWallet(
walletId: "${testWalletId}wallet balance minus maxfee",
walletName: "pendingBalance wallet name",
client: client,
coin: Coin.firo,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
await secureStore.write(
key: "${testWalletId}wallet balance minus maxfee_mnemonic",
value: TEST_MNEMONIC);
final wallet = await Hive.openBox<dynamic>(
"${testWalletId}wallet balance minus maxfee");
await wallet.put('_lelantus_coins', SampleLelantus.lelantusCoins);
await wallet.put('jindex', [2, 4, 6]);
await wallet.put('mintIndex', 8);
await wallet.put('receivingAddresses', [
"a8VV7vMzJdTQj1eLEJNskhLEBUxfNWhpAg",
"aPjLWDTPQsoPHUTxKBNRzoebDALj3eTcfh",
"aKmXfS7nEZdqWBGRdAXcyMoEoKhZQDPBoq",
]);
await wallet.put('changeAddresses', [
"a5V5r6We6mNZzWJwGwEeRML3mEYLjvK39w",
]);
expect(await firo.maxFee, 8914);
expect(await firo.balanceMinusMaxFee, Decimal.parse("0.0001268"));
});
test("get transactionData", () async {
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
// set mnemonic
await secureStore.write(
key: "${testWalletId}transactionData_mnemonic",
value: RefreshTestParams.mnemonic);
// mock electrumx client calls
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.getLatestCoinId()).thenAnswer((_) async => 1);
// when(client.getCoinsForRecovery(setId: 1))
// .thenAnswer((_) async => getCoinsForRecoveryResponse);
when(client.getUsedCoinSerials(startNumber: 0))
.thenAnswer((_) async => GetUsedSerialsSampleData.serials);
when(client.getFeeRate()).thenAnswer((_) async => {"rate": 1000});
// mock history calls
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash0))
.thenAnswer((_) async => SampleGetHistoryData.data0);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash1))
.thenAnswer((_) async => SampleGetHistoryData.data1);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash2))
.thenAnswer((_) async => SampleGetHistoryData.data2);
when(client.getHistory(scripthash: SampleGetHistoryData.scripthash3))
.thenAnswer((_) async => SampleGetHistoryData.data3);
// mock transaction calls
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash0,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData0);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash1,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData1);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash2,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData2);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash3,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData3);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash4,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData4);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash5,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData5);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash6,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData6);
// mock utxo calls
when(client.getUTXOs(scripthash: anyNamed("scripthash")))
.thenAnswer((_) async => []);
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}transactionData",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
final wallet = await Hive.openBox(testWalletId + "transactionData");
await wallet.put(
'receivingAddresses', RefreshTestParams.receivingAddresses);
await wallet.put('changeAddresses', RefreshTestParams.changeAddresses);
final txData = await firo.transactionData;
expect(txData, isA<TransactionData>());
// kill timer and listener
await firo.exit();
});
test("autoMint", () async {
TestWidgetsFlutterBinding.ensureInitialized();
const MethodChannel('uk.spiralarm.flutter/devicelocale')
.setMockMethodCallHandler((methodCall) async => 'en_US');
final client = MockElectrumX();
final cachedClient = MockCachedElectrumX();
final secureStore = FakeSecureStorage();
final priceAPI = MockPriceAPI();
// mock electrumx client calls
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.getBlockHeadTip()).thenAnswer(
(_) async => {"height": 465873, "hex": "this value not used here"});
when(client.broadcastTransaction(rawTx: anyNamed("rawTx")))
.thenAnswer((realInvocation) async {
final rawTx =
realInvocation.namedArguments[const Symbol("rawTx")] as String;
final rawTxData = Format.stringToUint8List(rawTx);
final hash = sha256
.convert(sha256.convert(rawTxData.toList(growable: false)).bytes);
final reversedBytes =
Uint8List.fromList(hash.bytes.reversed.toList(growable: false));
final txid = Format.uint8listToString(reversedBytes);
return txid;
});
when(client.getFeeRate()).thenAnswer((_) async => {"rate": 1000});
when(client.getLatestCoinId()).thenAnswer((_) async => 1);
// when(client.getCoinsForRecovery(setId: 1))
// .thenAnswer((_) async => getCoinsForRecoveryResponse);
when(client.getUsedCoinSerials(startNumber: 0))
.thenAnswer((_) async => GetUsedSerialsSampleData.serials);
// mock price calls
// when(priceAPI.getPrice(ticker: "FIRO", baseCurrency: "USD"))
// .thenAnswer((_) async => Decimal.fromInt(10));
// mock transaction calls
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash0,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData0);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash1,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData1);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash2,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData2);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash3,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData3);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash4,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData4);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash5,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData5);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash6,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData6);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash11,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData11);
when(cachedClient.getTransaction(
txHash: SampleGetTransactionData.txHash12,
coin: Coin.firo,
)).thenAnswer((_) async => SampleGetTransactionData.txData12);
final firo = FiroWallet(
walletName: testWalletName,
walletId: "${testWalletId}autoMint",
coin: Coin.firo,
client: client,
cachedClient: cachedClient,
secureStore: secureStore,
priceAPI: priceAPI,
tracker: MockTransactionNotificationTracker(),
);
// pre grab derivations in order to set up mock calls needed later on
await firo.fillAddresses(TEST_MNEMONIC);
final wallet = await Hive.openBox<dynamic>("${testWalletId}autoMint");
await wallet.put(
'receivingAddresses', RefreshTestParams.receivingAddresses);
await wallet.put('changeAddresses', RefreshTestParams.changeAddresses);
final rcv = await secureStore.read(
key: "${testWalletId}autoMint_receiveDerivations");
final chg = await secureStore.read(
key: "${testWalletId}autoMint_changeDerivations");
final receiveDerivations =
Map<String, dynamic>.from(jsonDecode(rcv as String) as Map);
final changeDerivations =
Map<String, dynamic>.from(jsonDecode(chg as String) as Map);
for (int i = 0; i < receiveDerivations.length; i++) {
final receiveHash = AddressUtils.convertToScriptHash(
receiveDerivations["$i"]!["address"] as String, firoNetwork);
final changeHash = AddressUtils.convertToScriptHash(
changeDerivations["$i"]!["address"] as String, firoNetwork);
List<Map<String, dynamic>> data;
switch (receiveHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: receiveHash))
.thenAnswer((_) async => data);
switch (changeHash) {
case SampleGetHistoryData.scripthash0:
data = SampleGetHistoryData.data0;
break;
case SampleGetHistoryData.scripthash1:
data = SampleGetHistoryData.data1;
break;
case SampleGetHistoryData.scripthash2:
data = SampleGetHistoryData.data2;
break;
case SampleGetHistoryData.scripthash3:
data = SampleGetHistoryData.data3;
break;
default:
data = [];
}
when(client.getHistory(scripthash: changeHash))
.thenAnswer((_) async => data);
}
when(client.getUTXOs(scripthash: GetUtxoSampleData.scriptHash0))
.thenAnswer((_) async => GetUtxoSampleData.utxos0);
when(client.getUTXOs(scripthash: GetUtxoSampleData.scriptHash1))
.thenAnswer((_) async => GetUtxoSampleData.utxos1);
await firo.recoverFromMnemonic(
mnemonic: TEST_MNEMONIC,
maxUnusedAddressGap: 20,
height: 0,
maxNumberOfIndexesToCheck: 1000);
firo.timer = Timer(const Duration(minutes: 3), () {});
await firo.refresh();
bool flag = false;
try {
await firo.autoMint();
} catch (_) {
flag = true;
}
expect(flag, false);
await firo.exit();
}, timeout: const Timeout(Duration(minutes: 3)));
test("exit", () async {
final firo = FiroWallet(
walletId: "${testWalletId}exit",
walletName: testWalletName,
coin: Coin.firo,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
firo.timer = Timer(const Duration(seconds: 2), () {});
bool flag = false;
try {
await firo.exit();
} catch (_) {
flag = true;
}
expect(flag, false);
expect(firo.timer, null);
});
tearDown(() async {
await tearDownTestHive();
});
});
group("simple getters", () {
group("fees", () {
test("get fees succeeds", () async {
final client = MockElectrumX();
when(client.getFeeRate()).thenAnswer((_) async => {"rate": 1000});
final firo = FiroWallet(
walletId: "some id",
walletName: "some name",
coin: Coin.firo,
client: client,
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expect((await firo.fees).fast, "0.00001000");
expect((await firo.fees).medium, "0.00001000");
expect((await firo.fees).slow, "0.00001000");
});
test("get fees throws", () {
final client = MockElectrumX();
when(client.getFeeRate()).thenThrow(Exception("Some exception"));
final firo = FiroWallet(
walletId: "some id",
walletName: "some name",
coin: Coin.firo,
client: client,
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expect(firo.fees, throwsA(isA<Exception>()));
});
});
group("coin", () {
test("get main net coinTicker", () {
final firo = FiroWallet(
walletId: "some id",
walletName: "some name",
coin: Coin.firo,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expect(firo.coin, Coin.firo);
});
test("get test net coin", () {
final firo = FiroWallet(
walletId: "some id",
walletName: "some name",
coin: Coin.firoTestNet,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expect(firo.coin, Coin.firoTestNet);
});
});
group("mnemonic", () {
test("fetch and convert properly stored mnemonic to list of words",
() async {
final store = FakeSecureStorage();
store.write(
key: "some id_mnemonic",
value: "some test mnemonic string of words");
final firo = FiroWallet(
walletName: 'unit test',
walletId: 'some id',
coin: Coin.firoTestNet,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: store,
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
final List<String> result = await firo.mnemonic;
expect(result, [
"some",
"test",
"mnemonic",
"string",
"of",
"words",
]);
});
test("attempt fetch and convert non existent mnemonic to list of words",
() async {
final store = FakeSecureStorage();
store.write(
key: "some id_mnemonic",
value: "some test mnemonic string of words");
final firo = FiroWallet(
walletName: 'unit test',
walletId: 'some other id',
coin: Coin.firoTestNet,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: store,
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expectLater(() => firo.mnemonic, throwsA(isA<NoSuchMethodError>()));
});
});
test("walletName", () {
final firo = FiroWallet(
walletId: "some id",
walletName: "some name",
coin: Coin.firo,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expect(firo.walletName, "some name");
firo.walletName = "new name";
expect(firo.walletName, "new name");
});
test("walletId", () {
final firo = FiroWallet(
walletId: "some id",
walletName: "some name",
coin: Coin.firo,
client: MockElectrumX(),
cachedClient: MockCachedElectrumX(),
secureStore: FakeSecureStorage(),
priceAPI: MockPriceAPI(),
tracker: MockTransactionNotificationTracker(),
);
expect(firo.walletId, "some id");
});
});
}