Skip to content

Commit

Permalink
Feature: Adaptive address prefix (#9)
Browse files Browse the repository at this point in the history
This branch introduces support for a default bech32 address prefix (hrp) queried from the network, and thus specific to each network. Until now, default prefix was hardcoded ('kira'), which was removed in this branch. The new model for the default bech32 prefix was already introduced on Adaptive Default Token feature, which has analogous purpose and was initially intended to implement together. But due to work organization purposes, the Adaptive Bech32 Address Prefix is introduced separately.

List of changes:
- deleted wallet_details.dart which contained hardcoded default bech32 prefix
- created getter "bech32Address" in wallet_address.dart, which extracts the hrp data from QueryTokenAliases or QueryValidators
- created "WalletAddress.fromBech32ValidatorsPage()" to enable viewing addresses in ValidatorsPage when not signed in. Also, changed "bech32Hrp" field to optional, because it is needed only to store the bech32 hrp value in case of using this constructor.
- cleaned up wallet_address.dart - removed not used and invalid methods related to hex. They were created based on wrong assumptions 2 years ago.
- modified tab list controllers, so that each of them requires Wallet Address and uses its getter to get default prefix from Network Module. This change solved bug with broken queries (if network changed, but address in request contained old prefix).
- changed "valoperWalletAddress" to String value "valkey", because wallet should only represent signed in user, and valkey prefix should be fetched from network
- changed order of tests in identity_registrar_cubit_test.dart to properly simulate the process after implementing My Account access block - cannot get IR data without getting bech32 prefix from network
  • Loading branch information
nemoforte authored Mar 26, 2024
1 parent 6362f2e commit 797cfb9
Show file tree
Hide file tree
Showing 47 changed files with 377 additions and 394 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import 'package:miro/infra/services/api_kira/query_balance_service.dart';
import 'package:miro/infra/services/cache/favourites_cache_service.dart';
import 'package:miro/shared/models/balances/balance_model.dart';
import 'package:miro/shared/models/list/pagination_details_model.dart';
import 'package:miro/shared/models/wallet/wallet_address.dart';

class BalancesListController implements IListController<BalanceModel> {
final FavouritesCacheService favouriteCacheService = FavouritesCacheService(domainName: 'balances');
final QueryBalanceService queryBalanceService = globalLocator<QueryBalanceService>();
final String address;
final WalletAddress walletAddress;

BalancesListController({
required this.address,
required this.walletAddress,
});

@override
Expand All @@ -27,7 +28,7 @@ class BalancesListController implements IListController<BalanceModel> {
if (favouriteBalances.isNotEmpty) {
// TODO(dominik): implement request Balances by name
PageData<BalanceModel> balancesPageData = await queryBalanceService.getBalanceModelList(
QueryBalanceReq(address: address, offset: 0, limit: 500),
QueryBalanceReq(address: walletAddress.bech32Address, offset: 0, limit: 500),
forceRequestBool: forceRequestBool,
);

Expand All @@ -41,7 +42,7 @@ class BalancesListController implements IListController<BalanceModel> {
@override
Future<PageData<BalanceModel>> getPageData(PaginationDetailsModel paginationDetailsModel, {bool forceRequestBool = false}) async {
PageData<BalanceModel> balancesPageData = await queryBalanceService.getBalanceModelList(
QueryBalanceReq(address: address, limit: paginationDetailsModel.limit, offset: paginationDetailsModel.offset),
QueryBalanceReq(address: walletAddress.bech32Address, limit: paginationDetailsModel.limit, offset: paginationDetailsModel.offset),
forceRequestBool: forceRequestBool,
);
return balancesPageData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import 'package:miro/infra/services/api_kira/query_delegations_service.dart';
import 'package:miro/infra/services/cache/favourites_cache_service.dart';
import 'package:miro/shared/models/delegations/validator_staking_model.dart';
import 'package:miro/shared/models/list/pagination_details_model.dart';
import 'package:miro/shared/models/wallet/wallet_address.dart';

class StakingListController implements IListController<ValidatorStakingModel> {
final FavouritesCacheService _favouritesCacheService = FavouritesCacheService(domainName: 'staking');
final QueryDelegationsService _queryDelegationsService = globalLocator<QueryDelegationsService>();
final String delegatorAddress;
final WalletAddress walletAddress;

StakingListController({
required this.delegatorAddress,
required this.walletAddress,
});

@override
Expand All @@ -30,7 +31,7 @@ class StakingListController implements IListController<ValidatorStakingModel> {
Future<PageData<ValidatorStakingModel>> getPageData(PaginationDetailsModel paginationDetailsModel, {bool forceRequestBool = false}) async {
PageData<ValidatorStakingModel> stakingPageData = await _queryDelegationsService.getValidatorStakingModelList(
QueryDelegationsReq(
delegatorAddress: delegatorAddress,
delegatorAddress: walletAddress.bech32Address,
offset: paginationDetailsModel.offset,
limit: paginationDetailsModel.limit,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,20 @@ import 'package:miro/shared/models/transactions/list/tx_direction_type.dart';
import 'package:miro/shared/models/transactions/list/tx_list_item_model.dart';
import 'package:miro/shared/models/transactions/list/tx_sort_type.dart';
import 'package:miro/shared/models/transactions/list/tx_status_type.dart';
import 'package:miro/shared/models/wallet/wallet_address.dart';

class TransactionsListController implements IListController<TxListItemModel> {
final FavouritesCacheService favouriteCacheService = FavouritesCacheService(domainName: 'transactions');
final QueryTransactionsService queryTransactionsService = globalLocator<QueryTransactionsService>();
final String address;
final WalletAddress walletAddress;

List<TxDirectionType>? directionFilters;
List<TxStatusType>? statusFilters;
DateTime? startDateTime;
DateTime? endDateTime;

TransactionsListController({
required this.address,
required this.walletAddress,
});

@override
Expand All @@ -38,7 +39,7 @@ class TransactionsListController implements IListController<TxListItemModel> {
Future<PageData<TxListItemModel>> getPageData(PaginationDetailsModel paginationDetailsModel, {bool forceRequestBool = false}) async {
PageData<TxListItemModel> transactionsPageData = await queryTransactionsService.getTransactionList(
QueryTransactionsReq(
address: address,
address: walletAddress.bech32Address,
limit: paginationDetailsModel.limit,
offset: paginationDetailsModel.offset,
sort: TxSortType.dateDESC,
Expand All @@ -47,7 +48,7 @@ class TransactionsListController implements IListController<TxListItemModel> {
status: statusFilters,
direction: directionFilters,
),
forceRequestBool: forceRequestBool,
forceRequestBool: forceRequestBool,
);
return transactionsPageData;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import 'package:miro/shared/models/wallet/wallet_address.dart';
class UndelegationListController implements IListController<UndelegationModel> {
final FavouritesCacheService _favouritesCacheService = FavouritesCacheService(domainName: 'undelegations');
final QueryUndelegationsService _queryUndelegationsService = globalLocator<QueryUndelegationsService>();
final WalletAddress undelegatorWalletAddress;
final WalletAddress walletAddress;

UndelegationListController({
required this.undelegatorWalletAddress,
required this.walletAddress,
});

@override
Expand All @@ -31,7 +31,7 @@ class UndelegationListController implements IListController<UndelegationModel> {
Future<PageData<UndelegationModel>> getPageData(PaginationDetailsModel paginationDetailsModel, {bool forceRequestBool = false}) async {
PageData<UndelegationModel> undelegationPageData = await _queryUndelegationsService.getUndelegationModelList(
QueryUndelegationsReq(
undelegatorAddress: undelegatorWalletAddress.bech32Address,
undelegatorAddress: walletAddress.bech32Address,
offset: paginationDetailsModel.offset,
limit: paginationDetailsModel.limit,
),
Expand Down
1 change: 1 addition & 0 deletions lib/shared/models/delegations/validator_staking_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class ValidatorStakingModel extends AListItem {
walletAddress: WalletAddress.fromBech32(delegation.validatorInfo.address),
moniker: delegation.validatorInfo.moniker,
logo: delegation.validatorInfo.logo,
valkey: delegation.validatorInfo.valkey,
),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import 'package:miro/shared/models/wallet/wallet_address.dart';

class StakingMsgDelegateFormModel extends AMsgFormModel {
// Form fields
String? _valkey;
WalletAddress? _delegatorWalletAddress;
WalletAddress? _valoperWalletAddress;
List<TokenAmountModel>? _tokenAmountModels;

// Values required to be saved to allow editing transaction
Expand All @@ -20,18 +20,18 @@ class StakingMsgDelegateFormModel extends AMsgFormModel {
TokenDenominationModel? tokenDenominationModel;

StakingMsgDelegateFormModel({
String? valkey,
WalletAddress? delegatorWalletAddress,
WalletAddress? valoperWalletAddress,
List<TokenAmountModel>? tokenAmountModels,
this.balanceModel,
this.tokenAliasModel,
this.tokenDenominationModel,
}) : _delegatorWalletAddress = delegatorWalletAddress,
_valoperWalletAddress = valoperWalletAddress,
}) : _valkey = valkey,
_delegatorWalletAddress = delegatorWalletAddress,
_tokenAmountModels = tokenAmountModels;

/// Method [buildTxMsgModel] throws [Exception] if at least one of the fields:
/// [_delegatorWalletAddress], [_valoperWalletAddress] or [_tokenAmountModels]
/// [_valkey], [_delegatorWalletAddress] or [_tokenAmountModels]
/// is not filled (equal null) or [_tokenAmountModels] is empty List.
///
@override
Expand All @@ -41,16 +41,16 @@ class StakingMsgDelegateFormModel extends AMsgFormModel {
throw Exception('Cannot build StakingMsgDelegateModel. Form is not valid');
}
return StakingMsgDelegateModel(
valkey: _valkey!,
delegatorWalletAddress: _delegatorWalletAddress!,
valoperWalletAddress: _valoperWalletAddress!,
tokenAmountModels: _tokenAmountModels!,
);
}

@override
bool canBuildTxMsg() {
bool amountZeroBool = tokenAmountModels?.length == 1 && tokenAmountModels?.first.getAmountInDefaultDenomination() == Decimal.zero;
bool fieldsFilledBool = _delegatorWalletAddress != null && _valoperWalletAddress != null && tokenAmountModels != null && amountZeroBool == false;
bool fieldsFilledBool = _delegatorWalletAddress != null && _valkey != null && tokenAmountModels != null && amountZeroBool == false;
return fieldsFilledBool;
}

Expand All @@ -61,10 +61,10 @@ class StakingMsgDelegateFormModel extends AMsgFormModel {
notifyListeners();
}

WalletAddress? get valoperWalletAddress => _valoperWalletAddress;
String? get valkey => _valkey;

set valoperWalletAddress(WalletAddress? validatorWalletAddress) {
_valoperWalletAddress = validatorWalletAddress;
set valoperWalletAddress(String? valkey) {
_valkey = valkey;
notifyListeners();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import 'package:miro/shared/models/wallet/wallet_address.dart';

class StakingMsgUndelegateFormModel extends AMsgFormModel {
// Form fields
String? _valkey;
WalletAddress? _delegatorWalletAddress;
WalletAddress? _valoperWalletAddress;
List<TokenAmountModel>? _tokenAmountModels;

// Values required to be saved to allow editing transaction
Expand All @@ -20,18 +20,18 @@ class StakingMsgUndelegateFormModel extends AMsgFormModel {
TokenDenominationModel? tokenDenominationModel;

StakingMsgUndelegateFormModel({
String? valkey,
WalletAddress? delegatorWalletAddress,
WalletAddress? valoperWalletAddress,
List<TokenAmountModel>? tokenAmountModels,
this.balanceModel,
this.tokenAliasModel,
this.tokenDenominationModel,
}) : _delegatorWalletAddress = delegatorWalletAddress,
_valoperWalletAddress = valoperWalletAddress,
}) : _valkey = valkey,
_delegatorWalletAddress = delegatorWalletAddress,
_tokenAmountModels = tokenAmountModels;

/// Method [buildTxMsgModel] throws [Exception] if at least one of the fields:
/// [_delegatorWalletAddress], [_valoperWalletAddress] or [_tokenAmountModels]
/// [_valkey], [_delegatorWalletAddress] or [_tokenAmountModels]
/// is not filled (equal null) or [_tokenAmountModels] is empty List.
///
@override
Expand All @@ -41,16 +41,16 @@ class StakingMsgUndelegateFormModel extends AMsgFormModel {
throw Exception('Cannot build StakingMsgUndelegateModel. Form is not valid');
}
return StakingMsgUndelegateModel(
valkey: _valkey!,
delegatorWalletAddress: _delegatorWalletAddress!,
valoperWalletAddress: _valoperWalletAddress!,
tokenAmountModels: _tokenAmountModels!,
);
}

@override
bool canBuildTxMsg() {
bool amountZeroBool = tokenAmountModels?.length == 1 && tokenAmountModels?.first.getAmountInDefaultDenomination() == Decimal.zero;
bool fieldsFilledBool = _delegatorWalletAddress != null && _valoperWalletAddress != null && tokenAmountModels != null && amountZeroBool == false;
bool fieldsFilledBool = _delegatorWalletAddress != null && _valkey != null && tokenAmountModels != null && amountZeroBool == false;
return fieldsFilledBool;
}

Expand All @@ -61,10 +61,10 @@ class StakingMsgUndelegateFormModel extends AMsgFormModel {
notifyListeners();
}

WalletAddress? get valoperWalletAddress => _valoperWalletAddress;
String? get valkey => _valkey;

set valoperWalletAddress(WalletAddress? validatorWalletAddress) {
_valoperWalletAddress = validatorWalletAddress;
_valkey = valkey;
notifyListeners();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,27 @@ import 'package:miro/shared/models/transactions/messages/tx_msg_type.dart';
import 'package:miro/shared/models/wallet/wallet_address.dart';

class StakingMsgDelegateModel extends ATxMsgModel {
final String valkey;
final WalletAddress delegatorWalletAddress;
final WalletAddress valoperWalletAddress;
final List<TokenAmountModel> tokenAmountModels;

const StakingMsgDelegateModel({
required this.valkey,
required this.delegatorWalletAddress,
required this.valoperWalletAddress,
required this.tokenAmountModels,
}) : super(txMsgType: TxMsgType.msgDelegate);

StakingMsgDelegateModel.single({
required this.valkey,
required this.delegatorWalletAddress,
required this.valoperWalletAddress,
required TokenAmountModel tokenAmountModel,
}) : tokenAmountModels = <TokenAmountModel>[tokenAmountModel],
super(txMsgType: TxMsgType.msgDelegate);

factory StakingMsgDelegateModel.fromMsgDto(MsgDelegate msgDelegate) {
return StakingMsgDelegateModel(
valkey: msgDelegate.valoperAddress,
delegatorWalletAddress: WalletAddress.fromBech32(msgDelegate.delegatorAddress),
valoperWalletAddress: WalletAddress.fromBech32(msgDelegate.valoperAddress),
tokenAmountModels: msgDelegate.amounts
.map((Coin coin) => TokenAmountModel(
defaultDenominationAmount: Decimal.parse(coin.amount),
Expand All @@ -48,7 +48,7 @@ class StakingMsgDelegateModel extends ATxMsgModel {
ATxMsg toMsgDto() {
return MsgDelegate(
delegatorAddress: delegatorWalletAddress.bech32Address,
valoperAddress: valoperWalletAddress.bech32Address,
valoperAddress: valkey,
amounts: tokenAmountModels.map((TokenAmountModel tokenAmountModel) {
return Coin(
denom: tokenAmountModel.tokenAliasModel.defaultTokenDenominationModel.name,
Expand All @@ -72,7 +72,7 @@ class StakingMsgDelegateModel extends ATxMsgModel {

@override
String? getSubtitle(TxDirectionType txDirectionType) {
return valoperWalletAddress.bech32Address;
return valkey;
}

@override
Expand All @@ -81,5 +81,5 @@ class StakingMsgDelegateModel extends ATxMsgModel {
}

@override
List<Object?> get props => <Object>[delegatorWalletAddress, valoperWalletAddress, tokenAmountModels];
List<Object?> get props => <Object>[delegatorWalletAddress, valkey, tokenAmountModels];
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,27 @@ import 'package:miro/shared/models/transactions/messages/tx_msg_type.dart';
import 'package:miro/shared/models/wallet/wallet_address.dart';

class StakingMsgUndelegateModel extends ATxMsgModel {
final String valkey;
final WalletAddress delegatorWalletAddress;
final WalletAddress valoperWalletAddress;
final List<TokenAmountModel> tokenAmountModels;

const StakingMsgUndelegateModel({
required this.valkey,
required this.delegatorWalletAddress,
required this.valoperWalletAddress,
required this.tokenAmountModels,
}) : super(txMsgType: TxMsgType.msgUndelegate);

StakingMsgUndelegateModel.single({
required this.valkey,
required this.delegatorWalletAddress,
required this.valoperWalletAddress,
required TokenAmountModel tokenAmountModel,
}) : tokenAmountModels = <TokenAmountModel>[tokenAmountModel],
super(txMsgType: TxMsgType.msgUndelegate);

factory StakingMsgUndelegateModel.fromMsgDto(MsgUndelegate msgUndelegate) {
return StakingMsgUndelegateModel(
valkey: msgUndelegate.valoperAddress,
delegatorWalletAddress: WalletAddress.fromBech32(msgUndelegate.delegatorAddress),
valoperWalletAddress: WalletAddress.fromBech32(msgUndelegate.valoperAddress),
tokenAmountModels: msgUndelegate.amounts
.map((Coin coin) => TokenAmountModel(
defaultDenominationAmount: Decimal.parse(coin.amount),
Expand All @@ -48,7 +48,7 @@ class StakingMsgUndelegateModel extends ATxMsgModel {
ATxMsg toMsgDto() {
return MsgUndelegate(
delegatorAddress: delegatorWalletAddress.bech32Address,
valoperAddress: valoperWalletAddress.bech32Address,
valoperAddress: valkey,
amounts: tokenAmountModels.map((TokenAmountModel tokenAmountModel) {
return Coin(
denom: tokenAmountModel.tokenAliasModel.defaultTokenDenominationModel.name,
Expand All @@ -72,7 +72,7 @@ class StakingMsgUndelegateModel extends ATxMsgModel {

@override
String? getSubtitle(TxDirectionType txDirectionType) {
return valoperWalletAddress.bech32Address;
return valkey;
}

@override
Expand All @@ -81,5 +81,5 @@ class StakingMsgUndelegateModel extends ATxMsgModel {
}

@override
List<Object?> get props => <Object>[delegatorWalletAddress, valoperWalletAddress, tokenAmountModels];
List<Object?> get props => <Object>[delegatorWalletAddress, valkey, tokenAmountModels];
}
1 change: 1 addition & 0 deletions lib/shared/models/undelegations/undelegation_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class UndelegationModel extends AListItem {
walletAddress: WalletAddress.fromBech32(undelegation.validatorInfo.address),
moniker: undelegation.validatorInfo.moniker,
logo: undelegation.validatorInfo.logo,
valkey: undelegation.validatorInfo.valkey,
),
tokens: undelegation.tokens
.map((Coin e) => TokenAmountModel(
Expand Down
Loading

0 comments on commit 797cfb9

Please sign in to comment.