diff --git a/.env.example b/.env.example index 05f4a13a..d4cb82dd 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -EXPLORER_ADDRESS = 'witnet.network' +EXPLORER_ADDRESS = 'witscan.xyz' EXPLORER_DEV_ADDRESS = '0.0.0.0' # [ Integration Test Settings ] diff --git a/lib/bloc/crypto/crypto_bloc.dart b/lib/bloc/crypto/crypto_bloc.dart index 48591c06..6fb587d5 100644 --- a/lib/bloc/crypto/crypto_bloc.dart +++ b/lib/bloc/crypto/crypto_bloc.dart @@ -299,7 +299,7 @@ class CryptoBloc extends Bloc { await _vttGetThroughBlockExplorer.get(_hash); if (valueTransferInfo != null) { account.vtts.add(valueTransferInfo); - Hash txnHash = Hash.fromString(valueTransferInfo.txnHash); + Hash txnHash = Hash.fromString(valueTransferInfo.hash); if (account.utxosByTransactionId.containsKey(txnHash)) { balance += BalanceInfo.fromUtxoList( account.utxosByTransactionId[txnHash]!, @@ -325,19 +325,20 @@ class CryptoBloc extends Bloc { try { /// retrieve any Block Hashes final addressBlocks = await apiExplorer.address( - value: account.address, tab: 'blocks') as AddressBlocks; + value: account.address, + tab: 'blocks') as PaginatedRequest; /// retrieve each block - for (int i = 0; i < addressBlocks.blocks.length; i++) { - BlockInfo blockInfo = addressBlocks.blocks.elementAt(i); - String _hash = blockInfo.blockID; + for (int i = 0; i < addressBlocks.data.blocks.length; i++) { + BlockInfo blockInfo = addressBlocks.data.blocks.elementAt(i); + String _hash = blockInfo.hash; var result = await apiExplorer.hash(_hash); /// create a MintEntry from the BlockInfo and MintInfo BlockDetails blockDetails = result as BlockDetails; MintEntry mintEntry = MintEntry.fromBlockMintInfo( blockInfo, - blockDetails.mintInfo, + blockDetails, ); account.mintHashes.add(mintEntry.blockHash); account.mints.add(mintEntry); @@ -354,9 +355,9 @@ class CryptoBloc extends Bloc { try { final addressValueTransfers = await apiExplorer.address( value: account.address, - tab: 'value_transfers') as AddressValueTransfers; + tab: 'value_transfers') as PaginatedRequest; account.vttHashes = List.from( - addressValueTransfers.transactionHashes.map((e) => e)); + addressValueTransfers.data.addressValueTransfers.map((e) => e.hash)); final List _utxos = await apiExplorer.utxos(address: account.address); account.updateUtxos(_utxos); diff --git a/lib/bloc/explorer/api_explorer.dart b/lib/bloc/explorer/api_explorer.dart index 841e2d04..b0d29803 100644 --- a/lib/bloc/explorer/api_explorer.dart +++ b/lib/bloc/explorer/api_explorer.dart @@ -37,7 +37,7 @@ class ApiExplorer { Future hash(String value, [bool simple = true]) async { try { await delay(); - return await client.hash(value, simple); + return await client.hash(value: value, simple: simple, findAll: true); } on ExplorerException { rethrow; } @@ -52,15 +52,6 @@ class ApiExplorer { } } - Future network() async { - try { - await delay(); - return await client.network(); - } on ExplorerException { - rethrow; - } - } - Future getStatus() async { try { await delay(); @@ -71,37 +62,12 @@ class ApiExplorer { } } - Future pending() async { - try { - await delay(); - return await client.mempool(); - } on ExplorerException { - rethrow; - } - } - - Future richList({int start = 0, int stop = 1000}) async { - try { - await delay(); - return await client.richList(start: start, stop: stop); - } on ExplorerException { - rethrow; - } - } - - Future address({required String value, required String tab}) async { - try { - await delay(); - return await client.address(value: value, tab: tab); - } on ExplorerException { - rethrow; - } - } - - Future blockchain({int block = -100}) async { + Future> address( + {required String value, required String tab}) async { try { await delay(); - return await client.blockchain(block: block); + return await client.address(value: value, tab: tab, findAll: true) + as PaginatedRequest; } on ExplorerException { rethrow; } @@ -164,7 +130,7 @@ class ApiExplorer { AddressValueTransfers vtts = await getValueTransferHashes(account); List vttsToUpdate = []; - vttsToUpdate.addAll(vtts.transactionHashes); + vttsToUpdate.addAll(vtts.addressValueTransfers.map((e) => e.hash)); List vttsInDb = []; @@ -223,7 +189,7 @@ class ApiExplorer { /// get the list of value transfer hashes from the explorer for a given address. Future getValueTransferHashes(Account account) async { AddressValueTransfers vtts = - await address(value: account.address, tab: 'value_transfers'); + (await address(value: account.address, tab: 'value_transfers')).data; return vtts; } @@ -234,14 +200,14 @@ class ApiExplorer { } Future getMint(BlockInfo blockInfo) async { - String _hash = blockInfo.blockID; + String _hash = blockInfo.hash; var result = await Locator.instance.get().hash(_hash); /// create a MintEntry from the BlockInfo and MintInfo BlockDetails blockDetails = result as BlockDetails; MintEntry mintEntry = MintEntry.fromBlockMintInfo( blockInfo, - blockDetails.mintInfo, + blockDetails, ); return mintEntry; } diff --git a/lib/bloc/explorer/explorer_bloc.dart b/lib/bloc/explorer/explorer_bloc.dart index 80d4c92e..dec9166e 100644 --- a/lib/bloc/explorer/explorer_bloc.dart +++ b/lib/bloc/explorer/explorer_bloc.dart @@ -88,7 +88,7 @@ class ExplorerBloc extends Bloc { .get() .address(value: event.address, tab: event.tab); emit(ExplorerState.dataLoaded( - data: resp.jsonMap(), query: ExplorerQuery.address)); + data: resp.data.jsonMap(), query: ExplorerQuery.address)); } catch (err) { emit(ExplorerState.error()); rethrow; @@ -207,7 +207,8 @@ class ExplorerBloc extends Bloc { emit(ExplorerState.synced(database.walletStorage)); } - Future _getStatsByAddress(String address, String tab) async { + Future> _getStatsByAddress( + String address, String tab) async { try { return await Locator.instance .get() @@ -243,8 +244,8 @@ class ExplorerBloc extends Bloc { try { final result = await _getStatsByAddress(address, MasterAccountStats.blocks.name); - if (result.runtimeType != AddressBlocks && result['error'] != null) { - print('Error getting address blocks: ${result['error']}'); + if (result.runtimeType != AddressBlocks && result.data['error'] != null) { + print('Error getting address blocks: ${result.data['error']}'); return null; } return result as AddressBlocks?; @@ -259,12 +260,12 @@ class ExplorerBloc extends Bloc { try { final result = await _getStatsByAddress( address, MasterAccountStats.data_requests_solved.name); - if (result.runtimeType != AddressDataRequestsSolved && - result['error'] != null) { - print('Error getting data requests solved: ${result['error']}'); + if (result.data.runtimeType != AddressDataRequestsSolved) { + print( + 'Error getting data requests solved for address: ${result.data.address}'); return null; } - return result as AddressDataRequestsSolved?; + return result.data as AddressDataRequestsSolved?; } catch (err) { print('Error getting data requests solved: $err'); rethrow; @@ -292,7 +293,7 @@ class ExplorerBloc extends Bloc { totalBlocksMined: blocks.length, totalFeesPayed: feesPayed ?? 0, totalRewards: totalRewards ?? 0, - totalDrSolved: dataRequestsSolved?.numDataRequestsSolved ?? 0); + totalDrSolved: dataRequestsSolved?.dataRequestsSolved.length ?? 0); } Future _updateDBStatsFromExplorer( @@ -327,30 +328,27 @@ class ExplorerBloc extends Bloc { Future _syncAccountVtts(Account account) async { try { - AddressValueTransfers vtts = await explorer.address( - value: account.address, tab: 'value_transfers'); + AddressValueTransfers vtts = (await explorer.address( + value: account.address, tab: 'value_transfers')) + .data; WalletStorage walletStorage = database.walletStorage; - - for (int i = 0; i < vtts.transactionHashes.length; i++) { - String transactionId = vtts.transactionHashes[i]; - ValueTransferInfo? vtt = walletStorage.getVtt(transactionId); - + for (int i = 0; i < vtts.addressValueTransfers.length; i++) { + AddressValueTransferInfo newVtt = vtts.addressValueTransfers[i]; + ValueTransferInfo? vtt = walletStorage.getVtt(newVtt.hash); if (vtt != null) { - /// this vtt.status check for "confirmed" is in the local database - if (vtt.status != "confirmed") { - ValueTransferInfo _vtt = await explorer.getVtt(transactionId); + if (vtt.status != TxStatusLabel.confirmed) { + ValueTransferInfo _vtt = await explorer.getVtt(newVtt.hash); walletStorage.setVtt(database.walletStorage.currentWallet.id, _vtt); database.addOrUpdateVttInDB(_vtt); } } else { - ValueTransferInfo _vtt = await explorer.getVtt(transactionId); + ValueTransferInfo _vtt = await explorer.getVtt(newVtt.hash); walletStorage.setVtt(database.walletStorage.currentWallet.id, _vtt); database.addOrUpdateVttInDB(_vtt); } } - account.vttHashes.clear(); - account.vttHashes.addAll(vtts.transactionHashes); + account.vttHashes.addAll(vtts.addressValueTransfers.map((e) => e.hash)); return account; } catch (e) { print('Error updating vtts from explorer: $e'); @@ -361,12 +359,14 @@ class ExplorerBloc extends Bloc { Future _syncAccountMints(Account account) async { try { /// retrieve all Block Hashes - final addressBlocks = await explorer.address( - value: account.address, tab: 'blocks') as AddressBlocks; + final addressBlocks = (await explorer.address( + value: account.address, + tab: 'blocks') as PaginatedRequest) + .data; /// check if the list of transaction is already in the database for (int i = 0; i < addressBlocks.blocks.length; i++) { - String blockHash = addressBlocks.blocks[i].blockID; + String blockHash = addressBlocks.blocks[i].hash; MintEntry? mintEntry = database.walletStorage.getMint(blockHash); BlockInfo blockInfo = addressBlocks.blocks.elementAt(i); @@ -384,7 +384,7 @@ class ExplorerBloc extends Bloc { account.mintHashes.clear(); account.mintHashes - .addAll(addressBlocks.blocks.map((block) => block.blockID)); + .addAll(addressBlocks.blocks.map((block) => block.hash)); return account; } catch (e) { @@ -442,7 +442,6 @@ class ExplorerBloc extends Bloc { /// get a list of any pending transactions List unconfirmedVtts = wallet.unconfirmedTransactions(); - if (wallet.walletType == WalletType.hd) { /// maintain gap limit for BIP39 await wallet.ensureGapLimit(); @@ -471,7 +470,6 @@ class ExplorerBloc extends Bloc { print('Error getting UTXOs from the explorer $err'); rethrow; } - await syncWalletStorage(utxos: _utxos, wallet: wallet); _updateWalletList(storage: storage, wallet: wallet); } @@ -493,7 +491,7 @@ class ExplorerBloc extends Bloc { for (int i = 0; i < unconfirmedVtts.length; i++) { ValueTransferInfo _vtt = unconfirmedVtts[i]; try { - ValueTransferInfo vtt = await explorer.getVtt(_vtt.txnHash); + ValueTransferInfo vtt = await explorer.getVtt(_vtt.hash); if (_vtt.status != vtt.status) { await database.updateVtt(wallet.id, vtt); } @@ -502,17 +500,16 @@ class ExplorerBloc extends Bloc { /// and the vtt has an unknown hash /// check the inputs for accounts in the wallet and remove the vtt - for (int i = 0; i < _vtt.inputs.length; i++) { - Account? account = wallet.accountByAddress(_vtt.inputs[i].address); + for (int i = 0; i < _vtt.inputAddresses.length; i++) { + Account? account = wallet.accountByAddress(_vtt.inputAddresses[i]); if (account != null) { await account.deleteVtt(_vtt); } } /// check the outputs for accounts in the wallet and remove the vtt - for (int i = 0; i < _vtt.outputs.length; i++) { - Account? account = - wallet.accountByAddress(_vtt.outputs[i].pkh.address); + for (int i = 0; i < _vtt.outputAddresses.length; i++) { + Account? account = wallet.accountByAddress(_vtt.outputAddresses[i]); if (account != null) { await account.deleteVtt(_vtt); } @@ -526,6 +523,7 @@ class ExplorerBloc extends Bloc { await database.updateCurrentWallet( currentWalletId: wallet.id, isHdWallet: wallet.walletType == WalletType.hd); + print('FINISH SYNC'); return storage; } } diff --git a/lib/bloc/transactions/value_transfer/vtt_create/vtt_create_bloc.dart b/lib/bloc/transactions/value_transfer/vtt_create/vtt_create_bloc.dart index c87f8925..44f5360e 100644 --- a/lib/bloc/transactions/value_transfer/vtt_create/vtt_create_bloc.dart +++ b/lib/bloc/transactions/value_transfer/vtt_create/vtt_create_bloc.dart @@ -483,7 +483,7 @@ class VTTCreateBloc extends Bloc { if (account.utxos.contains(currentUtxo)) { _inputs.add(InputUtxo( address: account.address, - input: currentUtxo.toInput(), + inputUtxo: currentUtxo.toInput().outputPointer.toString(), value: currentUtxo.value)); } }); @@ -493,7 +493,7 @@ class VTTCreateBloc extends Bloc { if (account.utxos.contains(currentUtxo)) { _inputs.add(InputUtxo( address: account.address, - input: currentUtxo.toInput(), + inputUtxo: currentUtxo.toInput().outputPointer.toString(), value: currentUtxo.value)); } }); @@ -502,7 +502,7 @@ class VTTCreateBloc extends Bloc { currentWallet.masterAccount != null) { _inputs.add(InputUtxo( address: currentWallet.masterAccount!.address, - input: currentUtxo.toInput(), + inputUtxo: currentUtxo.toInput().outputPointer.toString(), value: currentUtxo.value)); } } @@ -540,17 +540,29 @@ class VTTCreateBloc extends Bloc { if (transactionAccepted) { /// add pending transaction List _inputUtxoList = _buildInputUtxoList(); + //FIX: update schema ValueTransferInfo vti = ValueTransferInfo( - blockHash: '', + block: '0', + confirmed: false, + reverted: false, + inputsMerged: [], + timelocks: outputs.map((e) => e.timeLock.toInt()).toList(), fee: feeNanoWit, - inputs: _inputUtxoList, + inputAddresses: _inputUtxoList.map((e) => e.address).toList(), + outputAddresses: outputs.map((e) => e.pkh.address).toList(), + inputUtxos: _inputUtxoList, outputs: outputs, + outputValues: outputs.map((e) => e.value.toInt()).toList(), priority: 1, - status: 'pending', - txnEpoch: -1, - txnHash: event.transaction.transactionID, - txnTime: DateTime.now().millisecondsSinceEpoch, - type: 'ValueTransfer', + status: TxStatusLabel.pending, + value: outputs[0].value.toInt(), + epoch: -1, + utxos: [], + utxosMerged: [], + trueOutputAddresses: [], + changeOutputAddresses: [], + hash: event.transaction.transactionID, + timestamp: DateTime.now().millisecondsSinceEpoch, weight: event.transaction.weight); /// add pending tx to database diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a3faccaa..6759ba0c 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -281,5 +281,11 @@ "updateError": "There was an issue with the update. Please try again.", "errorTryAgain": "Error. Try Again.", "insufficientFunds": "Insufficient funds", - "insufficientUtxosAvailable": "Wait untill the pending transactions are confirmed or try creating a transaction with a smaller amount." + "insufficientUtxosAvailable": "Wait untill the pending transactions are confirmed or try creating a transaction with a smaller amount.", + "dataRequestTxn": "Data Request", + "valueTransferTxn": "Value Transfer", + "mintTxn": "Mint", + "confirmed": "Confirmed", + "pending": "Pending", + "reverted": "Reverted" } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 11205eb4..a988414d 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -275,5 +275,11 @@ "updateError": "Hubo un problema con la actualización. Por favor, inténtalo de nuevo.", "errorTryAgain": "Error. Inténtalo de nuevo.", "insufficientFunds": "Fondos insuficientes", - "insufficientUtxosAvailable": "Espera a la confirmación de las transacciones pendientes o crea una transacción con una cantidad más pequeña." + "insufficientUtxosAvailable": "Espera a la confirmación de las transacciones pendientes o crea una transacción con una cantidad más pequeña.", + "dataRequestTxn": "Data Request", + "valueTransferTxn": "Value Transfer", + "mintTxn": "Mint", + "confirmed": "Confirmada", + "pending": "Pendiente", + "reverted": "Revertida" } \ No newline at end of file diff --git a/lib/screens/dashboard/bloc/dashboard_bloc.dart b/lib/screens/dashboard/bloc/dashboard_bloc.dart index d790c285..0f1dffbd 100644 --- a/lib/screens/dashboard/bloc/dashboard_bloc.dart +++ b/lib/screens/dashboard/bloc/dashboard_bloc.dart @@ -17,7 +17,7 @@ class DashboardBloc extends Bloc { DashboardState( currentWalletId: defaultWallet.id, currentAddress: defaultAccount.address, - currentVttId: defaulVtt.txnHash, + currentVttId: defaulVtt.hash, status: DashboardStatus.Ready), ) { on(_dashboardLoadEvent); @@ -29,7 +29,7 @@ class DashboardBloc extends Bloc { get initialState => DashboardState( currentWalletId: defaultWallet.id, currentAddress: defaultAccount.address, - currentVttId: defaulVtt.txnHash, + currentVttId: defaulVtt.hash, status: DashboardStatus.Ready); Future _dashboardLoadEvent( @@ -39,7 +39,7 @@ class DashboardBloc extends Bloc { emit(DashboardState( currentWalletId: event.currentWalletId ?? defaultWallet.id, currentAddress: event.currentAddress ?? defaultAccount.address, - currentVttId: event.currentVttId ?? defaulVtt.txnHash, + currentVttId: event.currentVttId ?? defaulVtt.hash, status: DashboardStatus.Ready)); } @@ -49,7 +49,7 @@ class DashboardBloc extends Bloc { emit(DashboardState( currentWalletId: event.currentWalletId ?? defaultWallet.id, currentAddress: event.currentAddress ?? defaultAccount.address, - currentVttId: event.currentVttId ?? defaulVtt.txnHash, + currentVttId: event.currentVttId ?? defaulVtt.hash, status: DashboardStatus.Ready)); } @@ -63,7 +63,7 @@ class DashboardBloc extends Bloc { emit(DashboardState( currentWalletId: event.currentWallet?.id ?? defaultWallet.id, currentAddress: event.currentAddress ?? defaultAccount.address, - currentVttId: event.currentVttId ?? defaulVtt.txnHash, + currentVttId: event.currentVttId ?? defaulVtt.hash, status: DashboardStatus.Ready)); } @@ -72,7 +72,7 @@ class DashboardBloc extends Bloc { emit(DashboardState( currentWalletId: event.currentWalletId ?? defaultWallet.id, currentAddress: event.currentAddress ?? defaultAccount.address, - currentVttId: event.currentVttId ?? defaulVtt.txnHash, + currentVttId: event.currentVttId ?? defaulVtt.hash, status: DashboardStatus.Ready)); } diff --git a/lib/screens/dashboard/view/transactions_view.dart b/lib/screens/dashboard/view/transactions_view.dart index c2e47811..de1d292c 100644 --- a/lib/screens/dashboard/view/transactions_view.dart +++ b/lib/screens/dashboard/view/transactions_view.dart @@ -108,7 +108,7 @@ class TransactionsViewState extends State currentWallet: widget.currentWallet, ), buildPagination(extendedTheme), - SizedBox(height: Platform.isIOS ? 16 : 0), + SizedBox(height: Platform.isIOS || Platform.isMacOS ? 16 : 0), ]), ); } diff --git a/lib/shared/api_database.dart b/lib/shared/api_database.dart index b49024bd..03f74817 100644 --- a/lib/shared/api_database.dart +++ b/lib/shared/api_database.dart @@ -371,7 +371,7 @@ class ApiDatabase { } Future addOrUpdateVttInDB(ValueTransferInfo vtt) async { - if (await getVtt(vtt.txnHash) == null) { + if (await getVtt(vtt.hash) == null) { await addVtt(vtt); } else { await updateVtt(walletStorage.currentWallet.id, vtt); diff --git a/lib/util/filter_utxos.dart b/lib/util/filter_utxos.dart index 674f4b49..2f9e88a7 100644 --- a/lib/util/filter_utxos.dart +++ b/lib/util/filter_utxos.dart @@ -9,8 +9,9 @@ List filterUsedUtxos( List outputPointers = []; for (int i = 0; i < pendingVtts.length; i++) { - pendingVtts[i].inputs.forEach((InputUtxo input) { - outputPointers.add(input.input.outputPointer); + pendingVtts[i].inputAddresses.forEach((String inputAddress) { + //FIX: get output pointer from new value trasnfer schema + // outputPointers.add(input.input.outputPointer); }); } diff --git a/lib/util/get_utxos_match_inputs.dart b/lib/util/get_utxos_match_inputs.dart index 36ea7b0f..3d871223 100644 --- a/lib/util/get_utxos_match_inputs.dart +++ b/lib/util/get_utxos_match_inputs.dart @@ -1,19 +1,18 @@ import 'package:witnet/data_structures.dart'; import 'package:witnet/explorer.dart'; -import 'package:witnet/schema.dart'; List getUtxosMatchInputs( {required List utxoList, required List inputs}) { List matchingUtxos = []; - List outputPointers = []; - + //TODO: check this works with new api + List outputPointers = []; inputs.forEach((InputUtxo input) { - outputPointers.add(input.input.outputPointer); + outputPointers.add(input.inputUtxo); }); for (int i = 0; i < utxoList.length; i++) { Utxo utxo = utxoList[i]; - if (outputPointers.contains(utxo.outputPointer)) { + if (outputPointers.contains(utxo.outputPointer.toString())) { matchingUtxos.add(utxo); } } diff --git a/lib/util/storage/cache/file_manager_interface.dart b/lib/util/storage/cache/file_manager_interface.dart index f577cc9b..d8153420 100644 --- a/lib/util/storage/cache/file_manager_interface.dart +++ b/lib/util/storage/cache/file_manager_interface.dart @@ -43,7 +43,7 @@ class TransactionCache { } void addVtt(ValueTransferInfo vti) { - transactions[vti.txnHash] = vti; + transactions[vti.hash] = vti; } Future> getValue(String key) async { diff --git a/lib/util/storage/cache/transaction_cache.dart b/lib/util/storage/cache/transaction_cache.dart index f577cc9b..d8153420 100644 --- a/lib/util/storage/cache/transaction_cache.dart +++ b/lib/util/storage/cache/transaction_cache.dart @@ -43,7 +43,7 @@ class TransactionCache { } void addVtt(ValueTransferInfo vti) { - transactions[vti.txnHash] = vti; + transactions[vti.hash] = vti; } Future> getValue(String key) async { diff --git a/lib/util/storage/database/account.dart b/lib/util/storage/database/account.dart index e8117c1d..be675bd1 100644 --- a/lib/util/storage/database/account.dart +++ b/lib/util/storage/database/account.dart @@ -162,18 +162,18 @@ class Account extends _Account { Future addVtt(ValueTransferInfo vtt) async { ApiDatabase database = Locator.instance(); - vtt.inputs.forEach((input) { + vtt.inputUtxos.forEach((input) { if (input.address == address) { - if (!vttHashes.contains(vtt.txnHash)) { - vttHashes.add(vtt.txnHash); + if (!vttHashes.contains(vtt.hash)) { + vttHashes.add(vtt.hash); vtts.add(vtt); } } }); vtt.outputs.forEach((output) { if (output.pkh.address == address) { - if (!vttHashes.contains(vtt.txnHash)) { - vttHashes.add(vtt.txnHash); + if (!vttHashes.contains(vtt.hash)) { + vttHashes.add(vtt.hash); vtts.add(vtt); } } @@ -184,8 +184,8 @@ class Account extends _Account { Future deleteVtt(ValueTransferInfo vtt) async { ApiDatabase database = Locator.instance(); try { - vttHashes.removeWhere((hash) => hash == vtt.txnHash); - vtts.removeWhere((_vtt) => _vtt.txnHash == vtt.txnHash); + vttHashes.removeWhere((hash) => hash == vtt.hash); + vtts.removeWhere((_vtt) => _vtt.hash == vtt.hash); await database.updateAccount(this); } catch (e) { return false; diff --git a/lib/util/storage/database/database_isolate.dart b/lib/util/storage/database/database_isolate.dart index 1738ccc1..8239f4f3 100644 --- a/lib/util/storage/database/database_isolate.dart +++ b/lib/util/storage/database/database_isolate.dart @@ -145,8 +145,7 @@ Future _addRecord( value = await dbService.add(Wallet.fromJson(params['value'])); break; case 'vtt': - value = - await dbService.add(ValueTransferInfo.fromDbJson(params['value'])); + value = await dbService.add(ValueTransferInfo.fromJson(params['value'])); break; case 'account': value = await dbService.add(Account.fromJson(params['value'])); @@ -176,7 +175,7 @@ Future _deleteRecord( break; case 'vtt': value = - await dbService.delete(ValueTransferInfo.fromDbJson(params['value'])); + await dbService.delete(ValueTransferInfo.fromJson(params['value'])); break; case 'account': value = await dbService.delete(Account.fromJson(params['value'])); @@ -212,7 +211,7 @@ Future _updateRecord( break; case 'vtt': value = - await dbService.update(ValueTransferInfo.fromDbJson(params['value'])); + await dbService.update(ValueTransferInfo.fromJson(params['value'])); break; case 'account': value = await dbService.update(Account.fromJson(params['value'])); diff --git a/lib/util/storage/database/database_service.dart b/lib/util/storage/database/database_service.dart index 3c001fa0..d0ff1630 100644 --- a/lib/util/storage/database/database_service.dart +++ b/lib/util/storage/database/database_service.dart @@ -6,6 +6,7 @@ import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; import 'package:sembast/sembast_io.dart'; import 'package:sembast/sembast.dart'; import 'package:witnet/explorer.dart'; +import 'dart:convert'; import 'package:my_wit_wallet/constants.dart'; import 'package:my_wit_wallet/util/storage/database/account.dart'; import 'package:my_wit_wallet/util/storage/database/account_repository.dart'; @@ -90,11 +91,11 @@ class DatabaseService { } else { mode = DatabaseMode.create; } - _dbService._database = await dbFactory.openDatabase( - _dbService._dbConfig!.path, - version: 2, - mode: mode, - ); + _dbService._database = await dbFactory + .openDatabase(_dbService._dbConfig!.path, version: 3, mode: mode, + onVersionChanged: (db, oldVersion, newVersion) async { + await migrateDB(db); + }); } Future add(dynamic item) async { @@ -145,13 +146,13 @@ class DatabaseService { await walletRepository.deleteWallet(item.id, _database); break; case ValueTransferInfo: - await vttRepository.deleteTransaction(item.txnHash, _database); + await vttRepository.deleteTransaction(item.hash, _database); break; case Account: await accountRepository.deleteAccount(item.address, _database); break; case MintEntry: - await mintRepository.deleteTransaction(item.txnHash, _database); + await mintRepository.deleteTransaction(item.hash, _database); break; case AccountStats: await statsRepository.deleteStats(item.address, _database); @@ -238,6 +239,22 @@ class DatabaseService { } } + Future migrateDB(db) async { + /// Get all Transactions + final List transactions = + await vttRepository.getAllTransactions(db); + + for (int i = 0; i < transactions.length; i++) { + ValueTransferInfo _vtt = transactions[i]; + // Force transactions to be re-synced + final convertedTx = ValueTransferInfo.fromDBJson({ + ...json.decode(_vtt.toRawJson()), + 'status': 'TxStatusLabel.unknown' + }); + await vttRepository.updateTransaction(convertedTx, db); + } + } + Future loadWallets() async { /// Get all Wallets @@ -305,7 +322,7 @@ class DatabaseService { accountMap[account.address] = account; }); transactions.forEach((vtt) { - vttMap[vtt.txnHash] = vtt; + vttMap[vtt.hash] = vtt; }); mints.forEach((mint) { mintMap[mint.blockHash] = mint; diff --git a/lib/util/storage/database/get_account_vtts_map.dart b/lib/util/storage/database/get_account_vtts_map.dart index 0f1aae3a..8d722539 100644 --- a/lib/util/storage/database/get_account_vtts_map.dart +++ b/lib/util/storage/database/get_account_vtts_map.dart @@ -1,26 +1,25 @@ import 'package:witnet/explorer.dart'; -import 'package:witnet/schema.dart'; Map> getAccountVttsMap( List vttList) { Map> accountVttMap = {}; - // Creates map to get vtts by account address for (int i = 0; i < vttList.length; i++) { - List inputs = vttList[i].inputs; - List outputs = vttList[i].outputs; - inputs.forEach((input) { - if (accountVttMap[input.address] != null) { - accountVttMap[input.address]!.add(vttList[i]); + List inputs = vttList[i].inputUtxos.map((e) => e.address).toList(); + List outputs = + vttList[i].outputs.map((e) => e.pkh.address).toList(); + inputs.forEach((inputAddress) { + if (accountVttMap[inputAddress] != null) { + accountVttMap[inputAddress]!.add(vttList[i]); } else { - accountVttMap[input.address] = [vttList[i]]; + accountVttMap[inputAddress] = [vttList[i]]; } }); - outputs.forEach((output) { - if (accountVttMap[output.pkh.address] != null) { - accountVttMap[output.pkh.address]!.add(vttList[i]); + outputs.forEach((outputAddress) { + if (accountVttMap[outputAddress] != null) { + accountVttMap[outputAddress]!.add(vttList[i]); } else { - accountVttMap[output.pkh.address] = [vttList[i]]; + accountVttMap[outputAddress] = [vttList[i]]; } }); } diff --git a/lib/util/storage/database/transaction_adapter.dart b/lib/util/storage/database/transaction_adapter.dart index d9ec6d7c..ffa3478c 100644 --- a/lib/util/storage/database/transaction_adapter.dart +++ b/lib/util/storage/database/transaction_adapter.dart @@ -1,8 +1,6 @@ import 'package:witnet/explorer.dart'; import 'package:witnet/schema.dart'; -enum TransactionType { mint, value_transfer } - class MintData { final List outputs; final int timestamp; @@ -27,21 +25,28 @@ class MintData { class VttData { final List inputs; + final List inputAddresses; final List outputs; + final List outputAddresses; final int weight; final int priority; + final bool confirmed; + final bool reverted; VttData( {required this.inputs, + required this.inputAddresses, required this.outputs, + required this.outputAddresses, required this.weight, + required this.confirmed, + required this.reverted, required this.priority}); } class GeneralTransaction extends HashInfo { MintData? mint; VttData? vtt; - final TransactionType txnType; final int fee; final int? epoch; @@ -52,7 +57,6 @@ class GeneralTransaction extends HashInfo { required hash, required status, required time, - required this.txnType, required type, this.mint, this.vtt}) @@ -72,7 +76,6 @@ class GeneralTransaction extends HashInfo { status: mintEntry.status, time: mintEntry.timestamp, type: mintEntry.type, - txnType: TransactionType.mint, mint: MintData( commitCount: mintEntry.commitCount, outputs: mintEntry.outputs, @@ -87,32 +90,49 @@ class GeneralTransaction extends HashInfo { ValueTransferInfo valueTransferInfo) => GeneralTransaction( blockHash: valueTransferInfo.blockHash, - epoch: valueTransferInfo.txnEpoch, + epoch: valueTransferInfo.epoch, fee: valueTransferInfo.fee, - hash: valueTransferInfo.txnHash, + hash: valueTransferInfo.hash, status: valueTransferInfo.status, - time: valueTransferInfo.txnTime, + time: valueTransferInfo.timestamp, type: valueTransferInfo.type, - txnType: TransactionType.value_transfer, mint: null, vtt: VttData( - inputs: valueTransferInfo.inputs, + inputs: valueTransferInfo.inputUtxos, + inputAddresses: valueTransferInfo.inputAddresses, + confirmed: valueTransferInfo.confirmed, + reverted: valueTransferInfo.reverted, outputs: valueTransferInfo.outputs, + outputAddresses: valueTransferInfo.outputAddresses, weight: valueTransferInfo.weight, priority: valueTransferInfo.priority)); ValueTransferInfo toValueTransferInfo() => ValueTransferInfo( - blockHash: blockHash, - fee: fee, - inputs: vtt?.inputs ?? [], - outputs: vtt?.outputs ?? [], - priority: vtt?.priority ?? 0, - status: status, - txnEpoch: epoch, - txnHash: txnHash, - txnTime: txnTime, - type: type, - weight: vtt?.weight ?? 0); + block: blockHash, + fee: fee, + inputUtxos: vtt?.inputs ?? [], + outputs: vtt?.outputs ?? [], + priority: vtt?.priority ?? 0, + status: status, + epoch: epoch ?? 0, + hash: txnHash, + timestamp: txnTime, + weight: vtt?.weight ?? 0, + confirmed: vtt?.confirmed ?? false, + reverted: vtt?.reverted ?? false, + inputAddresses: vtt?.inputAddresses ?? [], + outputAddresses: vtt?.outputAddresses ?? [], + value: 0, + inputsMerged: [], + outputValues: [], + timelocks: [], + utxos: [], + utxosMerged: [], + trueOutputAddresses: [], + changeOutputAddresses: [], + trueValue: 0, + changeValue: 0, + ); } class MintEntry { @@ -131,6 +151,8 @@ class MintEntry { required this.tallyCount, required this.status, required this.type, + required this.confirmed, + required this.reverted, }); final String blockHash; final List outputs; @@ -143,8 +165,10 @@ class MintEntry { final int commitCount; final int revealCount; final int tallyCount; - final String status; - final String type; + final TxStatusLabel status; + final TransactionType type; + final bool confirmed; + final bool reverted; bool containsAddress(String address) { bool response = false; @@ -167,31 +191,38 @@ class MintEntry { "commit_count": commitCount, "reveal_count": revealCount, "tally_count": tallyCount, - "status": status, - "type": type, + 'confirmed': confirmed, + 'reverted': reverted, + "status": status.toString(), + "type": type.toString(), }; - factory MintEntry.fromJson(Map json) => MintEntry( - blockHash: json["block_hash"], - outputs: List.from( - json["outputs"].map((x) => ValueTransferOutput.fromJson(x))), - timestamp: json["timestamp"], - epoch: json["epoch"], - reward: json["reward"], - fees: json["fees"], - valueTransferCount: json["vtt_count"], - dataRequestCount: json["drt_count"], - commitCount: json["commit_count"], - revealCount: json["reveal_count"], - tallyCount: json["tally_count"], - status: json["status"], - type: json["type"], - ); + factory MintEntry.fromJson(Map json) { + return MintEntry( + blockHash: json["block_hash"], + outputs: List.from( + json["outputs"].map((x) => ValueTransferOutput.fromJson(x))), + timestamp: json["timestamp"], + epoch: json["epoch"], + reward: json["reward"], + fees: json["fees"], + valueTransferCount: json["vtt_count"], + dataRequestCount: json["drt_count"], + commitCount: json["commit_count"], + revealCount: json["reveal_count"], + tallyCount: json["tally_count"], + confirmed: json['confirmed'] ?? false, + reverted: json['reverted'] ?? false, + status: TransactionStatus.fromJson(json).status, + type: TransactionType.mint, + ); + } - factory MintEntry.fromBlockMintInfo(BlockInfo blockInfo, MintInfo mintInfo) => + factory MintEntry.fromBlockMintInfo( + BlockInfo blockInfo, BlockDetails blockDetails) => MintEntry( - blockHash: mintInfo.blockHash, - outputs: mintInfo.outputs, + blockHash: blockDetails.mintInfo.blockHash, + outputs: blockDetails.mintInfo.outputs, timestamp: blockInfo.timestamp, epoch: blockInfo.epoch, reward: blockInfo.reward, @@ -201,7 +232,12 @@ class MintEntry { commitCount: blockInfo.commitCount, revealCount: blockInfo.revealCount, tallyCount: blockInfo.tallyCount, - status: mintInfo.status, - type: mintInfo.type, + status: TransactionStatus.fromJson({ + 'confirmed': blockDetails.confirmed, + 'reverted': blockDetails.reverted + }).status, + type: TransactionType.mint, + confirmed: blockDetails.confirmed, + reverted: blockDetails.reverted, ); } diff --git a/lib/util/storage/database/transaction_repository.dart b/lib/util/storage/database/transaction_repository.dart index a8472dbe..77093041 100644 --- a/lib/util/storage/database/transaction_repository.dart +++ b/lib/util/storage/database/transaction_repository.dart @@ -42,11 +42,12 @@ class VttRepository extends _TransactionRepository { final snapshots = await _store.find(databaseClient); try { List transactions = snapshots - .map((snapshot) => ValueTransferInfo.fromDbJson( + .map((snapshot) => ValueTransferInfo.fromJson( snapshot.value as Map)) .toList(growable: false); return transactions; } catch (e) { + print('Error getting all transactions $e'); return []; } } @@ -57,7 +58,7 @@ class VttRepository extends _TransactionRepository { try { assert(transaction.runtimeType == ValueTransferInfo); await _store - .record(transaction.txnHash) + .record(transaction.hash) .add(databaseClient, transaction.jsonMap()); return true; } catch (e) { @@ -71,11 +72,11 @@ class VttRepository extends _TransactionRepository { try { assert(transaction.runtimeType == ValueTransferInfo); await _store - .record(transaction.txnHash) + .record(transaction.hash) .update(databaseClient, transaction.jsonMap()); return true; } catch (e) { - print(e); + print('Error updating transaction $e'); return false; } } @@ -87,7 +88,7 @@ class VttRepository extends _TransactionRepository { await _store.record(txHash).get(databaseClient); ValueTransferInfo valueTransferInfo = - ValueTransferInfo.fromDbJson(valueTransferInfoDbJson); + ValueTransferInfo.fromJson(valueTransferInfoDbJson); return valueTransferInfo; } catch (e) { @@ -184,6 +185,7 @@ class MintRepository extends _TransactionRepository { .toList(growable: false); return transactions; } catch (e) { + print('Error getting mint transactions $e'); return []; } } diff --git a/lib/util/storage/database/wallet.dart b/lib/util/storage/database/wallet.dart index 045ee310..69a58d52 100644 --- a/lib/util/storage/database/wallet.dart +++ b/lib/util/storage/database/wallet.dart @@ -47,8 +47,16 @@ class Wallet { required this.externalAccounts, required this.internalAccounts, this.lastSynced = -1, - this.id = "00000000", - }); + }) { + this.id = '00000000'; + this.externalAccounts.forEach((key, Account account) { + account.balance; + }); + + this.internalAccounts.forEach((key, Account account) { + account.balance; + }); + } final WalletType walletType; late String id; @@ -92,16 +100,16 @@ class Wallet { Future deleteVtt(Wallet wallet, ValueTransferInfo vtt) async { /// check the inputs for accounts in the wallet and remove the vtt - for (int i = 0; i < vtt.inputs.length; i++) { - Account? account = wallet.accountByAddress(vtt.inputs[i].address); + for (int i = 0; i < vtt.inputAddresses.length; i++) { + Account? account = wallet.accountByAddress(vtt.inputAddresses[i]); if (account != null) { await account.deleteVtt(vtt); } } /// check the outputs for accounts in the wallet and remove the vtt - for (int i = 0; i < vtt.outputs.length; i++) { - Account? account = wallet.accountByAddress(vtt.outputs[i].pkh.address); + for (int i = 0; i < vtt.outputAddresses.length; i++) { + Account? account = wallet.accountByAddress(vtt.outputAddresses[i]); if (account != null) { await account.deleteVtt(vtt); } @@ -164,7 +172,7 @@ class Wallet { List unconfirmedTransactions() { List unconfirmedVtts = []; allTransactions().forEach((vtt) { - if (vtt.status != "confirmed") { + if (vtt.status != TxStatusLabel.confirmed) { unconfirmedVtts.add(vtt); } }); @@ -185,21 +193,20 @@ class Wallet { Map _vttMap = {}; externalAccounts.forEach((key, account) { account.vtts.forEach((vtt) { - if (vtt.status != 'unknown hash') _vttMap[vtt.txnHash] = vtt; + if (vtt.status != TxStatusLabel.reverted) _vttMap[vtt.hash] = vtt; }); }); internalAccounts.forEach((key, account) { account.vtts.forEach((vtt) { - if (vtt.status != 'unknown hash') _vttMap[vtt.txnHash] = vtt; + if (vtt.status != TxStatusLabel.reverted) _vttMap[vtt.hash] = vtt; }); }); if (walletType == WalletType.single) { masterAccount!.vtts.forEach((vtt) { - if (vtt.status != 'unknown hash') _vttMap[vtt.txnHash] = vtt; + if (vtt.status != TxStatusLabel.reverted) _vttMap[vtt.hash] = vtt; }); } - return _vttMap.values.toList() ..sort((t1, t2) => t2.txnTime.compareTo(t1.txnTime)); } @@ -512,7 +519,6 @@ class Wallet { masterAccount: null, masterAccountStats: null, ); - _wallet.id = _id; return _wallet; } diff --git a/lib/util/storage/database/wallet_storage.dart b/lib/util/storage/database/wallet_storage.dart index 71fd0738..34537cf6 100644 --- a/lib/util/storage/database/wallet_storage.dart +++ b/lib/util/storage/database/wallet_storage.dart @@ -21,18 +21,31 @@ final defaultWallet = Wallet( final defaultAccount = Account(address: '', walletName: '', path: ''); final defaulVtt = ValueTransferInfo( - blockHash: - '0000000000000000000000000000000000000000000000000000000000000000', - fee: 0, - inputs: [], - outputs: [], - priority: 0, - status: 'pending', - txnEpoch: 0, - txnHash: '0000000000000000000000000000000000000000000000000000000000000000', - txnTime: 0, - type: 'valueTransfer', - weight: 0); + confirmed: false, + reverted: false, + block: '0', + epoch: 0, + timestamp: 0, + value: 0, + hash: '0000000000000000000000000000000000000000000000000000000000000000', + fee: 0, + priority: 0, + weight: 0, + inputAddresses: [], + outputAddresses: [], + inputUtxos: [], + inputsMerged: [], + outputValues: [], + timelocks: [], + utxos: [], + utxosMerged: [], + trueOutputAddresses: [], + changeOutputAddresses: [], + status: TxStatusLabel.pending, + trueValue: 0, + changeValue: 0, + outputs: [], +); /// DbWallet formats the wallet for the database class WalletStorage { diff --git a/lib/widgets/transaction_details.dart b/lib/widgets/transaction_details.dart index 26f1259b..57880ce9 100644 --- a/lib/widgets/transaction_details.dart +++ b/lib/widgets/transaction_details.dart @@ -49,20 +49,45 @@ class TransactionDetails extends StatelessWidget { : null; } + String transactionType(TransactionType status) { + switch (status) { + case TransactionType.value_transfer: + return localization.valueTransferTxn; + case TransactionType.mint: + return localization.mintTxn; + case TransactionType.data_request: + return localization.dataRequestTxn; + } + } + + String transactionStatus(TxStatusLabel status) { + switch (status) { + case TxStatusLabel.confirmed: + return localization.confirmed; + case TxStatusLabel.pending: + return localization.pending; + case TxStatusLabel.reverted: + return localization.reverted; + case TxStatusLabel.unknown: + return 'Loading...'; + } + } + Widget _buildOutput( ThemeData theme, ValueTransferOutput output, bool isLastOutput) { final extendedTheme = theme.extension()!; Widget timelock = SizedBox(height: 0); - if (output.timeLock != 0) { - timelock = Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Text(output.timeLock.toInt().formatDate(), - style: theme.textTheme.bodySmall) - ])); - } + // FIXME: new API does not make accesible the timelock field + // if (output.timeLock != 0) { + // timelock = Expanded( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.end, + // mainAxisAlignment: MainAxisAlignment.end, + // children: [ + // Text(output.timeLock.toInt().formatDate(), + // style: theme.textTheme.bodySmall) + // ])); + // } return Container( padding: EdgeInsets.only(top: 16, bottom: 16), decoration: BoxDecoration( @@ -124,8 +149,8 @@ class TransactionDetails extends StatelessWidget { )); } - bool _isPendingTransaction(String status) { - return status.toLowerCase() == "pending"; + bool _isPendingTransaction(TxStatusLabel status) { + return status == TxStatusLabel.pending; } Widget buildSpeedUpBtn() { @@ -137,12 +162,12 @@ class TransactionDetails extends StatelessWidget { Widget build(BuildContext context) { final theme = Theme.of(context); String label = ''; - if (transaction.txnType == TransactionType.value_transfer) { + if (transaction.type == TransactionType.value_transfer) { label = getTransactionLabel(externalAddresses, internalAddresses, transaction.vtt!.inputs, singleAddressAccount, context); } List outputs = - transaction.txnType == TransactionType.value_transfer + transaction.type == TransactionType.value_transfer ? transaction.vtt!.outputs : transaction.mint!.outputs; return ClosableView(closeSetting: goToList, children: [ @@ -153,7 +178,7 @@ class TransactionDetails extends StatelessWidget { SizedBox(height: 24), InfoElement( label: localization.status, - text: transaction.status.capitalize(), + text: transactionStatus(transaction.status), color: theme.textTheme.labelMedium?.color), InfoElement( label: localization.transactionId, @@ -166,10 +191,9 @@ class TransactionDetails extends StatelessWidget { ? '_' : transaction.epoch.toString()), InfoElement( - label: localization.type, - text: transaction.type.split('_').join(' ').toTitleCase()), + label: localization.type, text: transactionType(transaction.type)), InfoElement( - label: transaction.txnType == TransactionType.value_transfer + label: transaction.type == TransactionType.value_transfer ? localization.feesPayed : localization.feesCollected, text: @@ -179,7 +203,7 @@ class TransactionDetails extends StatelessWidget { text: _isPendingTransaction(transaction.status) ? '_' : transaction.txnTime.formatDate()), - transaction.txnType == TransactionType.value_transfer + transaction.type == TransactionType.value_transfer ? Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( localization.inputs, @@ -217,7 +241,7 @@ class TransactionDetails extends StatelessWidget { ), ]), SizedBox(height: 8), - transaction.status == 'pending' && label == localization.to + transaction.status == TxStatusLabel.pending && label == localization.to ? buildSpeedUpBtn() : Container(), ]); diff --git a/lib/widgets/transaction_item.dart b/lib/widgets/transaction_item.dart index 635b8119..a89cc1af 100644 --- a/lib/widgets/transaction_item.dart +++ b/lib/widgets/transaction_item.dart @@ -14,6 +14,7 @@ import 'package:my_wit_wallet/util/transactions_list/get_transaction_label.dart' import 'package:my_wit_wallet/theme/colors.dart'; import 'package:my_wit_wallet/theme/extended_theme.dart'; import 'package:my_wit_wallet/util/extensions/int_extensions.dart'; +import 'package:witnet/explorer.dart'; typedef void GeneralTransactionCallback(GeneralTransaction? value); @@ -65,7 +66,7 @@ class TransactionsItemState extends State { int receiveValue(GeneralTransaction vti) { int nanoWitvalue = 0; - if (vti.txnType == TransactionType.value_transfer) { + if (vti.type == TransactionType.value_transfer) { vti.vtt!.outputs.forEach((element) { if ((externalAddresses.contains(element.pkh.address) || internalAddresses.contains(element.pkh.address))) { @@ -91,12 +92,16 @@ class TransactionsItemState extends State { } int sendValue(GeneralTransaction vti) { - if (vti.txnType == TransactionType.value_transfer) { - bool isInternalTx = - externalAddresses.contains(vti.vtt!.outputs[0].pkh.address) || - internalAddresses.contains(vti.vtt!.outputs[0].pkh.address) || - singleAddressAccount?.address == vti.vtt!.outputs[0].pkh.address; - return isInternalTx ? vti.fee : vti.vtt!.outputs[0].value.toInt(); + if (vti.type == TransactionType.value_transfer) { + if (vti.vtt!.outputs.length > 0) { + bool isInternalTx = externalAddresses + .contains(vti.vtt!.outputs[0].pkh.address) || + internalAddresses.contains(vti.vtt!.outputs[0].pkh.address) || + singleAddressAccount?.address == vti.vtt!.outputs[0].pkh.address; + return isInternalTx ? vti.fee : vti.vtt!.outputs[0].value.toInt(); + } else { + return 0; + } } else { return 0; } @@ -129,15 +134,15 @@ class TransactionsItemState extends State { } Widget buildTransactionStatus(ThemeData theme) { - String transactionStatus = widget.transaction.status; - String localizedtxnStatus = localization.txnStatus(transactionStatus); + TxStatusLabel transactionStatus = widget.transaction.status; + String localizedtxnStatus = localization.txnStatus(transactionStatus.name); String txnTime = widget.transaction.txnTime.formatDuration(context); List pendingStatus = []; String transacionStatusCopy = txnTime; - if (transactionStatus != "confirmed") { + if (transactionStatus != TxStatusLabel.confirmed) { transacionStatusCopy = "$localizedtxnStatus $txnTime"; - if (transactionStatus == "pending") { + if (transactionStatus == TxStatusLabel.pending) { pendingStatus = [ Icon(FontAwesomeIcons.clock, size: 10, color: theme.textTheme.bodySmall!.color), @@ -165,9 +170,9 @@ class TransactionsItemState extends State { final extendedTheme = theme.extension()!; String label; String address; - TransactionType txnType = widget.transaction.txnType; + TransactionType type = widget.transaction.type; - if (txnType == TransactionType.value_transfer) { + if (type == TransactionType.value_transfer) { label = getTransactionLabel(externalAddresses, internalAddresses, widget.transaction.vtt!.inputs, singleAddressAccount, context); address = getTransactionAddress(label, widget.transaction.vtt!.inputs, diff --git a/lib/widgets/transactions_list.dart b/lib/widgets/transactions_list.dart index 0ba74016..6e38ce23 100644 --- a/lib/widgets/transactions_list.dart +++ b/lib/widgets/transactions_list.dart @@ -75,6 +75,7 @@ class TransactionsListState extends State { speedUpTx: speedUpTx, filteredUtxos: false, currentWallet: currentWallet, + //FIXME: add timelock output: ValueTransferOutput.fromJson({ 'pkh': speedUpTx.vtt!.outputs.first.pkh.address, 'value': speedUpTx.vtt!.outputs.first.value.toInt(), diff --git a/pubspec.yaml b/pubspec.yaml index 9f396eac..89de1f11 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,7 +39,8 @@ dependencies: flutter_launcher_icons: ^0.13.1 sliding_up_panel: ^2.0.0+1 decimal: 2.3.3 - witnet: 0.2.9 + witnet: + path: ../witnet.dart path_provider: ^2.0.8 permission_handler: ^11.0.1 open_file: ^3.2.1