Skip to content

Commit

Permalink
feat: integrate explorer api v1.5
Browse files Browse the repository at this point in the history
  • Loading branch information
gabaldon committed Jan 8, 2024
1 parent 1b42933 commit 9bcd0a9
Show file tree
Hide file tree
Showing 26 changed files with 347 additions and 255 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
EXPLORER_ADDRESS = 'witnet.network'
EXPLORER_ADDRESS = 'witscan.xyz'
EXPLORER_DEV_ADDRESS = '0.0.0.0'

# [ Integration Test Settings ]
Expand Down
17 changes: 9 additions & 8 deletions lib/bloc/crypto/crypto_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ class CryptoBloc extends Bloc<CryptoEvent, CryptoState> {
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]!,
Expand All @@ -325,19 +325,20 @@ class CryptoBloc extends Bloc<CryptoEvent, CryptoState> {
try {
/// retrieve any Block Hashes
final addressBlocks = await apiExplorer.address(
value: account.address, tab: 'blocks') as AddressBlocks;
value: account.address,
tab: 'blocks') as PaginatedRequest<AddressBlocks>;

/// 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);
Expand All @@ -354,9 +355,9 @@ class CryptoBloc extends Bloc<CryptoEvent, CryptoState> {
try {
final addressValueTransfers = await apiExplorer.address(
value: account.address,
tab: 'value_transfers') as AddressValueTransfers;
tab: 'value_transfers') as PaginatedRequest<AddressValueTransfers>;
account.vttHashes = List<String>.from(
addressValueTransfers.transactionHashes.map((e) => e));
addressValueTransfers.data.addressValueTransfers.map((e) => e.hash));
final List<Utxo> _utxos =
await apiExplorer.utxos(address: account.address);
account.updateUtxos(_utxos);
Expand Down
52 changes: 9 additions & 43 deletions lib/bloc/explorer/api_explorer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ApiExplorer {
Future<dynamic> 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;
}
Expand All @@ -52,15 +52,6 @@ class ApiExplorer {
}
}

Future<Network> network() async {
try {
await delay();
return await client.network();
} on ExplorerException {
rethrow;
}
}

Future<Status> getStatus() async {
try {
await delay();
Expand All @@ -71,37 +62,12 @@ class ApiExplorer {
}
}

Future<dynamic> pending() async {
try {
await delay();
return await client.mempool();
} on ExplorerException {
rethrow;
}
}

Future<dynamic> richList({int start = 0, int stop = 1000}) async {
try {
await delay();
return await client.richList(start: start, stop: stop);
} on ExplorerException {
rethrow;
}
}

Future<dynamic> address({required String value, required String tab}) async {
try {
await delay();
return await client.address(value: value, tab: tab);
} on ExplorerException {
rethrow;
}
}

Future<Blockchain> blockchain({int block = -100}) async {
Future<PaginatedRequest<dynamic>> 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<dynamic>;
} on ExplorerException {
rethrow;
}
Expand Down Expand Up @@ -164,7 +130,7 @@ class ApiExplorer {
AddressValueTransfers vtts = await getValueTransferHashes(account);

List<String> vttsToUpdate = [];
vttsToUpdate.addAll(vtts.transactionHashes);
vttsToUpdate.addAll(vtts.addressValueTransfers.map((e) => e.hash));

List<String> vttsInDb = [];

Expand Down Expand Up @@ -223,7 +189,7 @@ class ApiExplorer {
/// get the list of value transfer hashes from the explorer for a given address.
Future<AddressValueTransfers> 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;
}

Expand All @@ -234,14 +200,14 @@ class ApiExplorer {
}

Future<MintEntry> getMint(BlockInfo blockInfo) async {
String _hash = blockInfo.blockID;
String _hash = blockInfo.hash;
var result = await Locator.instance.get<ApiExplorer>().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;
}
Expand Down
66 changes: 32 additions & 34 deletions lib/bloc/explorer/explorer_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {
.get<ApiExplorer>()
.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;
Expand Down Expand Up @@ -207,7 +207,8 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {
emit(ExplorerState.synced(database.walletStorage));
}

Future<dynamic> _getStatsByAddress(String address, String tab) async {
Future<PaginatedRequest<dynamic>> _getStatsByAddress(
String address, String tab) async {
try {
return await Locator.instance
.get<ApiExplorer>()
Expand Down Expand Up @@ -243,8 +244,8 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {
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?;
Expand All @@ -259,12 +260,12 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {
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;
Expand Down Expand Up @@ -292,7 +293,7 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {
totalBlocksMined: blocks.length,
totalFeesPayed: feesPayed ?? 0,
totalRewards: totalRewards ?? 0,
totalDrSolved: dataRequestsSolved?.numDataRequestsSolved ?? 0);
totalDrSolved: dataRequestsSolved?.dataRequestsSolved.length ?? 0);
}

Future<void> _updateDBStatsFromExplorer(
Expand Down Expand Up @@ -327,30 +328,27 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {

Future<Account> _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');
Expand All @@ -361,12 +359,14 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {
Future<Account> _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<AddressBlocks>)
.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);

Expand All @@ -384,7 +384,7 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {

account.mintHashes.clear();
account.mintHashes
.addAll(addressBlocks.blocks.map((block) => block.blockID));
.addAll(addressBlocks.blocks.map((block) => block.hash));

return account;
} catch (e) {
Expand Down Expand Up @@ -442,7 +442,6 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {

/// get a list of any pending transactions
List<ValueTransferInfo> unconfirmedVtts = wallet.unconfirmedTransactions();

if (wallet.walletType == WalletType.hd) {
/// maintain gap limit for BIP39
await wallet.ensureGapLimit();
Expand Down Expand Up @@ -471,7 +470,6 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {
print('Error getting UTXOs from the explorer $err');
rethrow;
}

await syncWalletStorage(utxos: _utxos, wallet: wallet);
_updateWalletList(storage: storage, wallet: wallet);
}
Expand All @@ -493,7 +491,7 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {
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);
}
Expand All @@ -502,17 +500,16 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {
/// 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);
}
Expand All @@ -526,6 +523,7 @@ class ExplorerBloc extends Bloc<ExplorerEvent, ExplorerState> {
await database.updateCurrentWallet(
currentWalletId: wallet.id,
isHdWallet: wallet.walletType == WalletType.hd);
print('FINISH SYNC');
return storage;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ class VTTCreateBloc extends Bloc<VTTCreateEvent, VTTCreateState> {
if (account.utxos.contains(currentUtxo)) {
_inputs.add(InputUtxo(
address: account.address,
input: currentUtxo.toInput(),
inputUtxo: currentUtxo.toInput().outputPointer.toString(),
value: currentUtxo.value));
}
});
Expand All @@ -493,7 +493,7 @@ class VTTCreateBloc extends Bloc<VTTCreateEvent, VTTCreateState> {
if (account.utxos.contains(currentUtxo)) {
_inputs.add(InputUtxo(
address: account.address,
input: currentUtxo.toInput(),
inputUtxo: currentUtxo.toInput().outputPointer.toString(),
value: currentUtxo.value));
}
});
Expand All @@ -502,7 +502,7 @@ class VTTCreateBloc extends Bloc<VTTCreateEvent, VTTCreateState> {
currentWallet.masterAccount != null) {
_inputs.add(InputUtxo(
address: currentWallet.masterAccount!.address,
input: currentUtxo.toInput(),
inputUtxo: currentUtxo.toInput().outputPointer.toString(),
value: currentUtxo.value));
}
}
Expand Down Expand Up @@ -540,17 +540,29 @@ class VTTCreateBloc extends Bloc<VTTCreateEvent, VTTCreateState> {
if (transactionAccepted) {
/// add pending transaction
List<InputUtxo> _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
Expand Down
Loading

0 comments on commit 9bcd0a9

Please sign in to comment.