diff --git a/lib/core/crypto/dart_esr/src/signing_request_manager.dart b/lib/core/crypto/dart_esr/src/signing_request_manager.dart index d24b47d9..8bc4bf78 100644 --- a/lib/core/crypto/dart_esr/src/signing_request_manager.dart +++ b/lib/core/crypto/dart_esr/src/signing_request_manager.dart @@ -804,18 +804,18 @@ extension HyphaSigningRequestManager on SigningRequestManager { /// Convert the ESR standard's "chain_id" to our Network /// Both signify a unique identifier for a chain /// But we support fewer chains than ESR does. - /// Networks maps to remote config which contains the server node URLs we need + /// Network maps to remote config which contains the server node URLs we need /// to use in order to access supported chains. /// Returns: Network /// throws: unsupported network when the chainID can't be parsed. /// - static Networks resolveNetwork(List chainId) { + static Network resolveNetwork(List chainId) { if (chainId[0] == 'chain_alias') { // chain_alias officially only supports EOS mainnet, and Telos mainnet, as 1, and 2. if (chainId[1] == 1) { - return Networks.eos; + return Network.eos; } else if (chainId[1] == 2) { - return Networks.telos; + return Network.telos; } else { throw 'unsupported network alias ${chainId[1]}'; } @@ -823,17 +823,17 @@ extension HyphaSigningRequestManager on SigningRequestManager { final ChainName name = SigningRequestUtils.idToName(chainId[1]); switch (name) { case ChainName.EOS: - return Networks.eos; + return Network.eos; case ChainName.EOS_JUNGLE4: - return Networks.eosTestnet; + return Network.eosTestnet; case ChainName.TELOS: - return Networks.telos; + return Network.telos; case ChainName.TELOS_TESTNET: - return Networks.telosTestnet; + return Network.telosTestnet; default: throw 'unsupported network ${name.name}'; } } - return Networks.eos; + return Network.eos; } } diff --git a/lib/core/crypto/seeds_esr/eos_transaction.dart b/lib/core/crypto/seeds_esr/eos_transaction.dart index 274fadc5..bf2fe4f1 100644 --- a/lib/core/crypto/seeds_esr/eos_transaction.dart +++ b/lib/core/crypto/seeds_esr/eos_transaction.dart @@ -5,7 +5,7 @@ import 'package:hypha_wallet/core/crypto/seeds_esr/eos_action.dart'; import 'package:hypha_wallet/core/network/api/services/remote_config_service.dart'; class EOSTransaction extends Equatable { - final Networks network; + final Network network; final List actions; bool get isValid => actions.isNotEmpty; @@ -16,7 +16,7 @@ class EOSTransaction extends Equatable { @override List get props => [actions]; - factory EOSTransaction.fromESRActionsList(List esrActions, Networks network) { + factory EOSTransaction.fromESRActionsList(List esrActions, Network network) { final List eosActions = esrActions.map((e) => EOSAction.fromESRAction(e)).where((item) => item.isValid).toList(); return EOSTransaction(eosActions, network); @@ -27,7 +27,7 @@ class EOSTransaction extends Equatable { required String actionName, required Map data, List? authorization, - required Networks network, + required Network network, }) => EOSTransaction([ EOSAction() diff --git a/lib/core/crypto/seeds_esr/seeds_esr.dart b/lib/core/crypto/seeds_esr/seeds_esr.dart index 0b66303d..aa2f06a9 100644 --- a/lib/core/crypto/seeds_esr/seeds_esr.dart +++ b/lib/core/crypto/seeds_esr/seeds_esr.dart @@ -22,7 +22,7 @@ class SeedsESR { } Result processResolvedRequest() { - Networks network; + Network network; try { network = _resolveNetwork(); } catch (error) { @@ -40,7 +40,7 @@ class SeedsESR { } /// Map ChainName or actual chain ID to our supported Network list - Networks _resolveNetwork() { + Network _resolveNetwork() { final List chainId = manager.signingRequest.chainId; return HyphaSigningRequestManager.resolveNetwork(chainId); } diff --git a/lib/core/di/bloc_module.dart b/lib/core/di/bloc_module.dart index 82581fd1..110c03fa 100644 --- a/lib/core/di/bloc_module.dart +++ b/lib/core/di/bloc_module.dart @@ -113,5 +113,6 @@ void _registerBlocsModule() { _registerFactory(() => SearchUserBloc( _getIt(), + _getIt(), )); } diff --git a/lib/core/network/api/aws_amplify/amplify_service.dart b/lib/core/network/api/aws_amplify/amplify_service.dart index 6a726136..e52271ed 100644 --- a/lib/core/network/api/aws_amplify/amplify_service.dart +++ b/lib/core/network/api/aws_amplify/amplify_service.dart @@ -10,7 +10,6 @@ import 'package:hypha_wallet/core/network/api/aws_amplify/aws_authenticated_requ import 'package:hypha_wallet/core/network/api/eos_service.dart'; import 'package:hypha_wallet/core/network/api/services/remote_config_service.dart'; import 'package:hypha_wallet/core/network/networking_manager.dart'; -import 'package:hypha_wallet/ui/profile/interactor/profile_data.dart'; String getRandomString(int len) { final random = Random.secure(); @@ -148,7 +147,7 @@ class AmplifyService { // handle CUSTOM_CHALLENGE challenge final loginCode = e.challengeParameters['loginCode']; - await eosService.loginWithCode(accountName: accountName, loginCode: loginCode, network: Networks.telos); + await eosService.loginWithCode(accountName: accountName, loginCode: loginCode, network: Network.telos); print('return challenge $loginCode'); session = await cognitoUser!.sendCustomChallengeAnswer(loginCode); @@ -168,18 +167,6 @@ class AmplifyService { return true; } - Future getProfile() async { - final result = await _request( - path: 'get-profile', - body: { - 'originAppId': remoteConfigService.pppOriginAppId, - }, - ); - final Map data = result['profile']; - final ProfileData profile = ProfileData.fromPPPDataJson(data); - return profile; - } - /// /// register method is used to modify any user attributes such as name, bio, etc /// diff --git a/lib/core/network/api/eos_service.dart b/lib/core/network/api/eos_service.dart index 7361db71..abe6e7b6 100644 --- a/lib/core/network/api/eos_service.dart +++ b/lib/core/network/api/eos_service.dart @@ -15,7 +15,7 @@ class EOSService { EOSService(this.secureStorageService, this.remoteConfigService); - EOSClient getEosClientForNetwork(Networks network, {List privateKeys = const []}) { + EOSClient getEosClientForNetwork(Network network, {List privateKeys = const []}) { return EOSClient( baseUrl: remoteConfigService.pushTransactionNodeUrl(network: network), privateKeys: privateKeys, @@ -26,7 +26,7 @@ class EOSService { Future> loginWithCode({ required String accountName, required String loginCode, - required Networks network, + required Network network, }) async { final contractName = remoteConfigService.loginContract(network: network); final actionName = remoteConfigService.loginAction(network: network); @@ -52,7 +52,7 @@ class EOSService { required String toAccount, required TokenValue tokenValue, String memo = '', - required Networks network, + required Network network, }) async { final contractName = tokenValue.tokenModel.contract; final actionName = 'transfer'; @@ -77,7 +77,7 @@ class EOSService { Future> deleteBlockchainAccount({ required String accountName, - required Networks network, + required Network network, }) async { throw 'TBD - implement this'; // final action = createChangePermissionsAction(accountName, 'owner', ['keys'], ['accounts']); @@ -87,7 +87,7 @@ class EOSService { Future> sendTransaction({ required EOSTransaction eosTransaction, required String accountName, - required Networks network, + required Network network, }) async { final actions = eosTransaction.actions.map((e) => e.toEosAction).toList(); diff --git a/lib/core/network/api/services/dao_service.dart b/lib/core/network/api/services/dao_service.dart index eb012e4b..e015b550 100644 --- a/lib/core/network/api/services/dao_service.dart +++ b/lib/core/network/api/services/dao_service.dart @@ -11,7 +11,7 @@ class DaoService { Future> getDaos({ required String accountName, - required Networks network, + required Network network, }) async { final String query = '{"query":"query profileDhos(\$username: String!, \$first: Int, \$offset: Int) { getMember(details_member_n: \$username) { docId __typename createdDate details_member_n memberofAggregate { count } memberof(first: \$first, offset: \$offset) { ... on Dao { docId details_daoName_n settings { settings_daoTitle_s settings_isHypha_i settings_logo_s settings_daoUrl_s } } } applicantof { ... on Dao { details_daoName_n settings { settings_daoTitle_s settings_daoUrl_s } } } } }","variables":{"username":"$accountName"}}'; diff --git a/lib/core/network/api/services/hypha_member_service.dart b/lib/core/network/api/services/hypha_member_service.dart index 82b6a0e1..e1954e9d 100644 --- a/lib/core/network/api/services/hypha_member_service.dart +++ b/lib/core/network/api/services/hypha_member_service.dart @@ -41,7 +41,7 @@ class HyphaMemberService { /// Find a hypha accounts starting with prefix Future, HyphaError>> findHyphaAccounts({ required String prefix, - required Networks network, + required Network network, }) async { try { final daoContract = remoteConfigService.daoContract(network: network); @@ -61,7 +61,7 @@ class HyphaMemberService { Future> isMember({ required String account, - required Networks network, + required Network network, }) async { try { final daoContract = remoteConfigService.daoContract(network: network); diff --git a/lib/core/network/api/services/invite_service.dart b/lib/core/network/api/services/invite_service.dart index a8abc191..416563d9 100644 --- a/lib/core/network/api/services/invite_service.dart +++ b/lib/core/network/api/services/invite_service.dart @@ -21,7 +21,7 @@ class InviteService { Future> redeemInvite({ required String account, required String secret, - required Networks network, + required Network network, }) async { final contractName = eosService.remoteConfigService.inviteContract(network: network); final actionName = 'redeeminvite'; diff --git a/lib/core/network/api/services/pay_cpu_service.dart b/lib/core/network/api/services/pay_cpu_service.dart index 153b87dc..46516226 100644 --- a/lib/core/network/api/services/pay_cpu_service.dart +++ b/lib/core/network/api/services/pay_cpu_service.dart @@ -16,7 +16,7 @@ class PayForCpuService { /// Usage: preload the payCpuAction for any member who is a Hypha member - see HyphaMemberService EOSAction payCpuAction({ required String account, - required Networks network, + required Network network, }) { final contractName = eosService.remoteConfigService.payCpuContract(network: network); final action = EOSAction() diff --git a/lib/core/network/api/services/remote_config_service.dart b/lib/core/network/api/services/remote_config_service.dart index 3b088875..d590319f 100644 --- a/lib/core/network/api/services/remote_config_service.dart +++ b/lib/core/network/api/services/remote_config_service.dart @@ -3,9 +3,21 @@ import 'dart:convert'; import 'package:firebase_remote_config/firebase_remote_config.dart'; import 'package:flutter/services.dart'; -enum Networks { telos, telosTestnet, eos, eosTestnet } +enum Network { + telos, + telosTestnet, + eos, + eosTestnet; + + static Network fromString(String label) { + return values.firstWhere( + (v) => v.name == label, + orElse: () => Network.telos, + ); + } +} -const Networks _defaultNetwork = Networks.telos; +const Network _defaultNetwork = Network.telos; /// Encapsulates everything to do with remote configuration class RemoteConfigService { @@ -20,12 +32,12 @@ class RemoteConfigService { return json.decode(FirebaseRemoteConfig.instance.getValue(param).asString()); } - Map _pppService({Networks? network}) { + Map _pppService({Network? network}) { network = network ?? _defaultNetwork; return _getMap('profileService')[network.name]; } - Map _getNetworkConfig({Networks? network}) { + Map _getNetworkConfig({Network? network}) { network = network ?? _defaultNetwork; final conf = _getMap('networks'); final networkFromConfig = conf[network.name]; @@ -37,7 +49,7 @@ class RemoteConfigService { // base url - read URL // network: default is Telos mainnet - String baseUrl({Networks? network}) { + String baseUrl({Network? network}) { final networkConfig = _getNetworkConfig(network: network); final endpoint = networkConfig['endpoint']; return endpoint; @@ -45,59 +57,69 @@ class RemoteConfigService { // Node for push transactions - should be a fast server to prevent timeouts // network: default is Telos mainnet. - String pushTransactionNodeUrl({required Networks network}) { + String pushTransactionNodeUrl({required Network network}) { final networkConfig = _getNetworkConfig(network: network); final endpoint = networkConfig['fastEndpoint']; return endpoint; } - String graphQLEndpoint({required Networks network}) { + String graphQLEndpoint({required Network network}) { final networkConfig = _getNetworkConfig(network: network); final endpoint = networkConfig['graphQlEndpoint']; return endpoint; } - String loginContract({Networks? network}) { + String loginContract({Network? network}) { final networkConfig = _getNetworkConfig(network: network); return networkConfig['loginContract']; } - String loginAction({Networks? network}) { + String loginAction({Network? network}) { final networkConfig = _getNetworkConfig(network: network); return networkConfig['loginAction']; } - String inviteContract({Networks? network}) { + String inviteContract({Network? network}) { final networkConfig = _getNetworkConfig(network: network); return networkConfig['inviteContract']; } - String payCpuContract({Networks? network}) { + String payCpuContract({Network? network}) { final networkConfig = _getNetworkConfig(network: network); return networkConfig['payCpuContract']; } - String daoContract({Networks? network}) { + String daoContract({Network? network}) { final networkConfig = _getNetworkConfig(network: network); return networkConfig['daoContract']; } bool get isSignUpEnabled => FirebaseRemoteConfig.instance.getBool('signUpEnabled'); + bool get isWalletEnabled => FirebaseRemoteConfig.instance.getBool('walletEnabled'); // PPP Profile Service Backend String get profileServiceEndpoint => FirebaseRemoteConfig.instance.getString('profileServiceEndpoint'); + String get accountCreatorEndpoint => FirebaseRemoteConfig.instance.getString('accountCreatorEndpoint'); // PPP Service AWS String get awsProfileServiceEndpoint => _pppService()['awsProfileServiceEndpoint']; + String get pppEndpoint => _pppService()['awsProfileServiceEndpoint']; + String get identityPoolId => _pppService()['identityPoolId']; + String get userPoolId => _pppService()['userPoolId']; + String get clientId => _pppService()['clientId']; + String get pppOriginAppId => _pppService()['pppOriginAppId']; + String get pppRegion => _pppService()['region']; + String get pppS3Region => _pppService()['s3Region']; + String get pppS3Bucket => _pppService()['s3Bucket']; // TODO(NIK): find the best endpoints for EOS @@ -157,10 +179,10 @@ class RemoteConfigService { 'accountCreatorEndpoint': 'http://34.236.29.152:9108', 'profileServiceEndpoint': 'http://34.236.29.152:9109', 'profileService': json.encode({ - 'telos': pppConfig.getProfileSeriviceConfig(Networks.telos), - 'telosTestnet': pppConfig.getProfileSeriviceConfig(Networks.telosTestnet), - 'eos': pppConfig.getProfileSeriviceConfig(Networks.eos), - 'eosTestnet': pppConfig.getProfileSeriviceConfig(Networks.eosTestnet), + 'telos': pppConfig.getProfileSeriviceConfig(Network.telos), + 'telosTestnet': pppConfig.getProfileSeriviceConfig(Network.telosTestnet), + 'eos': pppConfig.getProfileSeriviceConfig(Network.eos), + 'eosTestnet': pppConfig.getProfileSeriviceConfig(Network.eosTestnet), }), 'signUpEnabled': false, 'walletEnabled': false, @@ -178,12 +200,12 @@ class RemoteConfigService { } extension MapExtensions on Map { - Map getProfileSeriviceConfig(Networks network) { + Map getProfileSeriviceConfig(Network network) { final networkMap = { - Networks.telos: 'prod', - Networks.telosTestnet: 'test', - Networks.eos: 'eos', - Networks.eosTestnet: 'eosTestNet', + Network.telos: 'prod', + Network.telosTestnet: 'test', + Network.eos: 'eos', + Network.eosTestnet: 'eosTestNet', }; final data = this[networkMap[network]]; diff --git a/lib/core/network/models/user_profile_data.dart b/lib/core/network/models/user_profile_data.dart index 5e6645d7..9de1bc8a 100644 --- a/lib/core/network/models/user_profile_data.dart +++ b/lib/core/network/models/user_profile_data.dart @@ -1,4 +1,5 @@ import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:hypha_wallet/core/network/api/services/remote_config_service.dart'; part 'user_profile_data.freezed.dart'; part 'user_profile_data.g.dart'; @@ -9,6 +10,7 @@ class UserProfileData with _$UserProfileData { factory UserProfileData({ required String accountName, + required Network network, @Default(null) String? userImage, @Default(null) String? bio, @Default(null) String? userName, diff --git a/lib/core/network/models/user_profile_data.freezed.dart b/lib/core/network/models/user_profile_data.freezed.dart index 41578a4f..f83a3c5d 100644 --- a/lib/core/network/models/user_profile_data.freezed.dart +++ b/lib/core/network/models/user_profile_data.freezed.dart @@ -21,6 +21,7 @@ UserProfileData _$UserProfileDataFromJson(Map json) { /// @nodoc mixin _$UserProfileData { String get accountName => throw _privateConstructorUsedError; + Network get network => throw _privateConstructorUsedError; String? get userImage => throw _privateConstructorUsedError; String? get bio => throw _privateConstructorUsedError; String? get userName => throw _privateConstructorUsedError; @@ -38,7 +39,11 @@ abstract class $UserProfileDataCopyWith<$Res> { _$UserProfileDataCopyWithImpl<$Res, UserProfileData>; @useResult $Res call( - {String accountName, String? userImage, String? bio, String? userName}); + {String accountName, + Network network, + String? userImage, + String? bio, + String? userName}); } /// @nodoc @@ -55,6 +60,7 @@ class _$UserProfileDataCopyWithImpl<$Res, $Val extends UserProfileData> @override $Res call({ Object? accountName = null, + Object? network = null, Object? userImage = freezed, Object? bio = freezed, Object? userName = freezed, @@ -64,6 +70,10 @@ class _$UserProfileDataCopyWithImpl<$Res, $Val extends UserProfileData> ? _value.accountName : accountName // ignore: cast_nullable_to_non_nullable as String, + network: null == network + ? _value.network + : network // ignore: cast_nullable_to_non_nullable + as Network, userImage: freezed == userImage ? _value.userImage : userImage // ignore: cast_nullable_to_non_nullable @@ -89,7 +99,11 @@ abstract class _$$_UserProfileDataCopyWith<$Res> @override @useResult $Res call( - {String accountName, String? userImage, String? bio, String? userName}); + {String accountName, + Network network, + String? userImage, + String? bio, + String? userName}); } /// @nodoc @@ -104,6 +118,7 @@ class __$$_UserProfileDataCopyWithImpl<$Res> @override $Res call({ Object? accountName = null, + Object? network = null, Object? userImage = freezed, Object? bio = freezed, Object? userName = freezed, @@ -113,6 +128,10 @@ class __$$_UserProfileDataCopyWithImpl<$Res> ? _value.accountName : accountName // ignore: cast_nullable_to_non_nullable as String, + network: null == network + ? _value.network + : network // ignore: cast_nullable_to_non_nullable + as Network, userImage: freezed == userImage ? _value.userImage : userImage // ignore: cast_nullable_to_non_nullable @@ -134,6 +153,7 @@ class __$$_UserProfileDataCopyWithImpl<$Res> class _$_UserProfileData extends _UserProfileData { _$_UserProfileData( {required this.accountName, + required this.network, this.userImage = null, this.bio = null, this.userName = null}) @@ -145,6 +165,8 @@ class _$_UserProfileData extends _UserProfileData { @override final String accountName; @override + final Network network; + @override @JsonKey() final String? userImage; @override @@ -156,7 +178,7 @@ class _$_UserProfileData extends _UserProfileData { @override String toString() { - return 'UserProfileData(accountName: $accountName, userImage: $userImage, bio: $bio, userName: $userName)'; + return 'UserProfileData(accountName: $accountName, network: $network, userImage: $userImage, bio: $bio, userName: $userName)'; } @override @@ -166,6 +188,7 @@ class _$_UserProfileData extends _UserProfileData { other is _$_UserProfileData && (identical(other.accountName, accountName) || other.accountName == accountName) && + (identical(other.network, network) || other.network == network) && (identical(other.userImage, userImage) || other.userImage == userImage) && (identical(other.bio, bio) || other.bio == bio) && @@ -176,7 +199,7 @@ class _$_UserProfileData extends _UserProfileData { @JsonKey(ignore: true) @override int get hashCode => - Object.hash(runtimeType, accountName, userImage, bio, userName); + Object.hash(runtimeType, accountName, network, userImage, bio, userName); @JsonKey(ignore: true) @override @@ -195,6 +218,7 @@ class _$_UserProfileData extends _UserProfileData { abstract class _UserProfileData extends UserProfileData { factory _UserProfileData( {required final String accountName, + required final Network network, final String? userImage, final String? bio, final String? userName}) = _$_UserProfileData; @@ -206,6 +230,8 @@ abstract class _UserProfileData extends UserProfileData { @override String get accountName; @override + Network get network; + @override String? get userImage; @override String? get bio; diff --git a/lib/core/network/models/user_profile_data.g.dart b/lib/core/network/models/user_profile_data.g.dart index 3f2b8799..dbc49216 100644 --- a/lib/core/network/models/user_profile_data.g.dart +++ b/lib/core/network/models/user_profile_data.g.dart @@ -9,6 +9,7 @@ part of 'user_profile_data.dart'; _$_UserProfileData _$$_UserProfileDataFromJson(Map json) => _$_UserProfileData( accountName: json['accountName'] as String, + network: $enumDecode(_$NetworkEnumMap, json['network']), userImage: json['userImage'] as String? ?? null, bio: json['bio'] as String? ?? null, userName: json['userName'] as String? ?? null, @@ -17,7 +18,15 @@ _$_UserProfileData _$$_UserProfileDataFromJson(Map json) => Map _$$_UserProfileDataToJson(_$_UserProfileData instance) => { 'accountName': instance.accountName, + 'network': _$NetworkEnumMap[instance.network]!, 'userImage': instance.userImage, 'bio': instance.bio, 'userName': instance.userName, }; + +const _$NetworkEnumMap = { + Network.telos: 'telos', + Network.telosTestnet: 'telosTestnet', + Network.eos: 'eos', + Network.eosTestnet: 'eosTestnet', +}; diff --git a/lib/core/network/repository/auth_repository.dart b/lib/core/network/repository/auth_repository.dart index 5371772f..e12c3168 100644 --- a/lib/core/network/repository/auth_repository.dart +++ b/lib/core/network/repository/auth_repository.dart @@ -10,6 +10,7 @@ import 'package:hypha_wallet/core/local/services/secure_storage_service.dart'; import 'package:hypha_wallet/core/logging/log_helper.dart'; import 'package:hypha_wallet/core/network/api/aws_amplify/amplify_service.dart'; import 'package:hypha_wallet/core/network/api/aws_amplify/profile_upload_repository.dart'; +import 'package:hypha_wallet/core/network/api/services/remote_config_service.dart'; import 'package:hypha_wallet/core/network/api/services/user_account_service.dart'; import 'package:hypha_wallet/core/network/models/user_profile_data.dart'; import 'package:hypha_wallet/core/shared_preferences/hypha_shared_prefs.dart'; @@ -66,7 +67,15 @@ class AuthRepository { publicKey: userAuthData.publicKey.toString(), ); - _saveUserData(UserProfileData(accountName: accountName, userName: userName), userAuthData, false); + _saveUserData( + UserProfileData( + accountName: accountName, + userName: userName, + network: Network.fromString(inviteLinkData.chain), + ), + userAuthData, + false, + ); print('create ppp account for $accountName with image ${image?.path}'); await _uploadRepository.scheduleUpload(accountName: accountName, userName: userName, fileName: image?.path); diff --git a/lib/core/network/repository/profile_repository.dart b/lib/core/network/repository/profile_repository.dart index dba50feb..ea157b3d 100644 --- a/lib/core/network/repository/profile_repository.dart +++ b/lib/core/network/repository/profile_repository.dart @@ -11,13 +11,13 @@ class ProfileService extends NetworkingManager { ProfileService(this._remoteConfigService) : super(_remoteConfigService.profileServiceEndpoint); - Future> getProfile(String accountName) async { + Future> getProfile(String accountName, Network network) async { final url = '${_remoteConfigService.profileServiceEndpoint}${Endpoints.pppProfile}/$accountName'; try { final response = await get(url); if (response.statusCode == 200) { final map = Map.from(response.data); - return Result.value(ProfileData.fromJson(map)); + return Result.value(ProfileData.fromJson(map, network)); } else { print('get profile status error: ${response.statusCode} ${response.statusMessage}'); return Result.error(HyphaError(type: HyphaErrorType.api, message: 'server error ${response.statusMessage}')); diff --git a/lib/core/network/repository/user_account_repository.dart b/lib/core/network/repository/user_account_repository.dart index 35969fba..48f36e6c 100644 --- a/lib/core/network/repository/user_account_repository.dart +++ b/lib/core/network/repository/user_account_repository.dart @@ -20,7 +20,7 @@ class UserAccountRepository { return _userService.findAvailableUserAccount(fullName); } - Future, HyphaError>> findHyphaAccounts(String prefix, Networks network) { + Future, HyphaError>> findHyphaAccounts(String prefix, Network network) { return _memberService.findHyphaAccounts(prefix: prefix, network: network); } } diff --git a/lib/ui/onboarding/import_account/usecases/find_account_use_case.dart b/lib/ui/onboarding/import_account/usecases/find_account_use_case.dart index 56c9acb6..f663d9e0 100644 --- a/lib/ui/onboarding/import_account/usecases/find_account_use_case.dart +++ b/lib/ui/onboarding/import_account/usecases/find_account_use_case.dart @@ -18,13 +18,13 @@ class FindAccountsUseCase extends InputUseCase, // For this we need to find the correct PPP service for each chain, each chain uses a different PPP serivice // instance. final eosClient = EOSClient( - baseUrl: remoteConfigService.baseUrl(network: Networks.eos), + baseUrl: remoteConfigService.baseUrl(network: Network.eos), privateKeys: [], version: 'v1', ); final telosClient = EOSClient( - baseUrl: remoteConfigService.baseUrl(network: Networks.telos), + baseUrl: remoteConfigService.baseUrl(network: Network.telos), privateKeys: [], version: 'v1', ); @@ -33,15 +33,17 @@ class FindAccountsUseCase extends InputUseCase, final eosResult = results[0]; final telosResult = results[1]; - AccountNames? data; + final Map> data = {}; + + // AccountNames? data; if (eosResult.isValue) { - data = eosResult.asValue!.value; + data.putIfAbsent(Network.eos, () => eosResult.asValue!.value.accountNames); } else if (telosResult.isValue) { - data = telosResult.asValue!.value; + data.putIfAbsent(Network.telos, () => telosResult.asValue!.value.accountNames); } - if (data != null) { - return getUserProfilesFromAccountsUseCase.run(data.accountNames); + if (data.isNotEmpty) { + return getUserProfilesFromAccountsUseCase.run(data); } else { return Result.error(HyphaError.api('Failed to fetch accounts')); } diff --git a/lib/ui/profile/components/profile_view.dart b/lib/ui/profile/components/profile_view.dart index 91fcc923..d541c472 100644 --- a/lib/ui/profile/components/profile_view.dart +++ b/lib/ui/profile/components/profile_view.dart @@ -72,7 +72,7 @@ class ProfileView extends StatelessWidget { child: HyphaEditableAvatarImage( imageRadius: 50, name: state.profileData?.name, - imageFromUrl: state.profileData?.getAvatarUrl(), + imageFromUrl: state.profileData?.avatarUrl, onImageRemoved: () { context.read().add(const ProfileEvent.onRemoveImageTapped()); }, diff --git a/lib/ui/profile/interactor/profile_bloc.dart b/lib/ui/profile/interactor/profile_bloc.dart index f284c08d..eec60131 100644 --- a/lib/ui/profile/interactor/profile_bloc.dart +++ b/lib/ui/profile/interactor/profile_bloc.dart @@ -16,8 +16,11 @@ import 'package:hypha_wallet/ui/profile/usecases/set_name_use_case.dart'; import 'package:image_picker/image_picker.dart'; part 'page_command.dart'; + part 'profile_bloc.freezed.dart'; + part 'profile_event.dart'; + part 'profile_state.dart'; class ProfileBloc extends Bloc { @@ -50,7 +53,10 @@ class ProfileBloc extends Bloc { Future _initial(_Initial event, Emitter emit) async { emit(state.copyWith(pageState: PageState.loading)); final userData = _authRepository.authDataOrCrash; - final Result result = await _fetchProfileUseCase.run(userData.userProfileData.accountName); + final Result result = await _fetchProfileUseCase.run( + userData.userProfileData.accountName, + userData.userProfileData.network, + ); if (result.isValue) { emit(state.copyWith(pageState: PageState.success, profileData: result.asValue!.value)); } else { @@ -58,6 +64,7 @@ class ProfileBloc extends Bloc { final profileData = ProfileData( name: userData.userProfileData.userName, account: userData.userProfileData.accountName, + network: userData.userProfileData.network, ); emit(state.copyWith(pageState: PageState.success, profileData: profileData)); } @@ -108,9 +115,13 @@ class ProfileBloc extends Bloc { FutureOr _setAvatarImage(_SetAvatarImage event, Emitter emit) async { emit(state.copyWith(showUpdateImageLoading: true)); final result = await _setImageUseCase.run(event.image, state.profileData!.account); + final userData = _authRepository.authDataOrCrash; if (result.isValue) { - final Result profileResult = await _fetchProfileUseCase.run(state.profileData!.account); + final Result profileResult = await _fetchProfileUseCase.run( + state.profileData!.account, + userData.userProfileData.network, + ); if (profileResult.isValue) { final profile = profileResult.asValue!.value; emit(state.copyWith(showUpdateImageLoading: false, profileData: profile)); diff --git a/lib/ui/profile/interactor/profile_data.dart b/lib/ui/profile/interactor/profile_data.dart index 3805a409..cd9c65de 100644 --- a/lib/ui/profile/interactor/profile_data.dart +++ b/lib/ui/profile/interactor/profile_data.dart @@ -1,3 +1,5 @@ +import 'package:hypha_wallet/core/network/api/services/remote_config_service.dart'; + class ProfileData { final String? avatarUrl; final String? name; @@ -8,6 +10,7 @@ class ProfileData { final String? s3Identity; final String? avatar; final bool? deleted; + final Network network; ProfileData({ required this.name, @@ -19,9 +22,10 @@ class ProfileData { this.s3Identity, this.avatar, this.deleted, + required this.network, }); - factory ProfileData.fromJson(Map json) { + factory ProfileData.fromJson(Map json, Network network) { final account = json['eosAccount']; final avatarUrl = json['avatarUrl']; final publicData = json['publicData']; @@ -34,25 +38,7 @@ class ProfileData { avatarUrl: avatarUrl, bio: bio, deleted: deleted, - ); - } - - factory ProfileData.fromPPPDataJson(Map json) { - final account = json['eosAccount']; - final publicData = json['publicData']; - final avatar = publicData['avatar']; - final s3Identity = publicData['s3Identity']; - final name = publicData['name']; - final bio = publicData['bio']; - final deleted = publicData['deleted']; - return ProfileData( - name: name, - account: account, - avatarUrl: avatar, - bio: bio, - s3Identity: s3Identity, - avatar: avatar, - deleted: deleted, + network: network, ); } @@ -65,6 +51,7 @@ class ProfileData { bitCoinData: bitCoinData, eosData: eosData, s3Identity: s3Identity, + network: network, ); ProfileData updateName(String? name) => ProfileData( @@ -76,6 +63,7 @@ class ProfileData { bitCoinData: bitCoinData, eosData: eosData, s3Identity: s3Identity, + network: network, ); ProfileData updateImageAvatar(String avatar) => ProfileData( @@ -87,6 +75,7 @@ class ProfileData { bitCoinData: bitCoinData, eosData: eosData, s3Identity: s3Identity, + network: network, ); ProfileData removeAvatar() => ProfileData( @@ -98,11 +87,8 @@ class ProfileData { bitCoinData: bitCoinData, eosData: eosData, s3Identity: s3Identity, + network: network, ); - - String? getAvatarUrl() { - return avatarUrl; - } } class CryptoAccountData { diff --git a/lib/ui/profile/usecases/fetch_profile_use_case.dart b/lib/ui/profile/usecases/fetch_profile_use_case.dart index e9b843f0..42afda3c 100644 --- a/lib/ui/profile/usecases/fetch_profile_use_case.dart +++ b/lib/ui/profile/usecases/fetch_profile_use_case.dart @@ -1,21 +1,19 @@ import 'package:hypha_wallet/core/error_handler/model/hypha_error.dart'; +import 'package:hypha_wallet/core/network/api/services/remote_config_service.dart'; import 'package:hypha_wallet/core/network/models/user_profile_data.dart'; import 'package:hypha_wallet/core/network/repository/profile_repository.dart'; import 'package:hypha_wallet/core/shared_preferences/hypha_shared_prefs.dart'; -import 'package:hypha_wallet/ui/architecture/interactor/base_usecase.dart'; import 'package:hypha_wallet/ui/architecture/result/result.dart'; import 'package:hypha_wallet/ui/profile/interactor/profile_data.dart'; -class FetchProfileUseCase extends InputUseCase, String> { +class FetchProfileUseCase { final ProfileService _profileService; final HyphaSharedPrefs _appSharedPrefs; FetchProfileUseCase(this._profileService, this._appSharedPrefs); - @override - // ignore: avoid_renaming_method_parameters - Future> run(String accountName) async { - final Result result = await _profileService.getProfile(accountName); + Future> run(String accountName, Network network) async { + final Result result = await _profileService.getProfile(accountName, network); if (result.isValue) { final ProfileData profile = result.asValue!.value; await _appSharedPrefs.setUserProfileData( @@ -23,7 +21,8 @@ class FetchProfileUseCase extends InputUseCase, accountName: accountName, userName: profile.name, bio: profile.bio, - userImage: profile.getAvatarUrl(), + userImage: profile.avatarUrl, + network: network, ), ); } diff --git a/lib/ui/search_user/interactor/search_user_bloc.dart b/lib/ui/search_user/interactor/search_user_bloc.dart index bd7efa57..f3ba2a68 100644 --- a/lib/ui/search_user/interactor/search_user_bloc.dart +++ b/lib/ui/search_user/interactor/search_user_bloc.dart @@ -5,6 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:hypha_wallet/core/error_handler/model/hypha_error.dart'; import 'package:hypha_wallet/core/network/api/services/remote_config_service.dart'; import 'package:hypha_wallet/core/network/models/user_profile_data.dart'; +import 'package:hypha_wallet/core/network/repository/auth_repository.dart'; import 'package:hypha_wallet/ui/architecture/interactor/page_states.dart'; import 'package:hypha_wallet/ui/architecture/result/result.dart'; import 'package:hypha_wallet/ui/search_user/usecases/search_for_user_use_case.dart'; @@ -20,9 +21,10 @@ part 'search_user_state.dart'; class SearchUserBloc extends Bloc { final int _minTextLengthBeforeValidSearch = 2; - final SearchForMemberUseCase searchForMemberUseCase; + final SearchForMemberUseCase _searchForMemberUseCase; + final AuthRepository _authRepository; - SearchUserBloc(this.searchForMemberUseCase) : super(const SearchUserState()) { + SearchUserBloc(this._searchForMemberUseCase, this._authRepository) : super(const SearchUserState()) { on<_Initial>(_initial); on<_ClearPageCommand>((_, emit) => emit(state.copyWith(command: null))); on<_OnSearchQueryChanged>(_onSearchQueryChanged, transformer: _transformEvents); @@ -40,10 +42,10 @@ class SearchUserBloc extends Bloc { Future _onSearchQueryChanged(_OnSearchQueryChanged event, Emitter emit) async { emit(state.copyWith(pageState: PageState.loading, showClearIcon: event.query.isNotEmpty)); + final user = _authRepository.authDataOrCrash; if (event.query.length > _minTextLengthBeforeValidSearch) { - final searchNetwork = Networks.telos; // TODO(Gery): This needs to be the account's network final Result, HyphaError> results = - await searchForMemberUseCase.run(event.query.toLowerCase(), searchNetwork); + await _searchForMemberUseCase.run(event.query.toLowerCase(), user.userProfileData.network); if (results.isValue) { emit(state.copyWith(users: results.asValue!.value, pageState: PageState.success)); } else { diff --git a/lib/ui/search_user/usecases/search_for_user_use_case.dart b/lib/ui/search_user/usecases/search_for_user_use_case.dart index 1e08cc1a..3d729965 100644 --- a/lib/ui/search_user/usecases/search_for_user_use_case.dart +++ b/lib/ui/search_user/usecases/search_for_user_use_case.dart @@ -11,10 +11,10 @@ class SearchForMemberUseCase { SearchForMemberUseCase(this.userAccountRepository, this.getUserProfilesFromAccountsUseCase); - Future, HyphaError>> run(String searchQuery, Networks network) async { + Future, HyphaError>> run(String searchQuery, Network network) async { final Result, HyphaError> result = await userAccountRepository.findHyphaAccounts(searchQuery, network); if (result.isValue) { - return getUserProfilesFromAccountsUseCase.run(result.asValue!.value); + return getUserProfilesFromAccountsUseCase.run({network: result.asValue!.value}); } return Result.error(HyphaError.generic('Error fetching accounts that start with $searchQuery')); diff --git a/lib/ui/send/usecases/send_token_use_case.dart b/lib/ui/send/usecases/send_token_use_case.dart index 2d4b489e..23b378a1 100644 --- a/lib/ui/send/usecases/send_token_use_case.dart +++ b/lib/ui/send/usecases/send_token_use_case.dart @@ -33,7 +33,7 @@ class SendTokenUseCase { ), ), memo: memo ?? '', - network: Networks.telos, + network: user.userProfileData.network, ); if(result.isValue) { diff --git a/lib/ui/shared/usercases/get_user_profiles_from_accounts_use_case.dart b/lib/ui/shared/usercases/get_user_profiles_from_accounts_use_case.dart index b510f4c2..fbd3fb19 100644 --- a/lib/ui/shared/usercases/get_user_profiles_from_accounts_use_case.dart +++ b/lib/ui/shared/usercases/get_user_profiles_from_accounts_use_case.dart @@ -1,5 +1,6 @@ import 'package:collection/collection.dart'; import 'package:hypha_wallet/core/error_handler/model/hypha_error.dart'; +import 'package:hypha_wallet/core/network/api/services/remote_config_service.dart'; import 'package:hypha_wallet/core/network/models/user_profile_data.dart'; import 'package:hypha_wallet/core/network/repository/profile_repository.dart'; import 'package:hypha_wallet/ui/architecture/result/result.dart'; @@ -10,10 +11,16 @@ class GetUserProfilesFromAccountsUseCase { GetUserProfilesFromAccountsUseCase(this._profileService); - Future, HyphaError>> run(List accounts) async { - final Iterable>> futures = accounts.map( - (accountName) => _profileService.getProfile(accountName), - ); + Future, HyphaError>> run(Map> data) async { + final List<(Network, String)> pairs = []; + data.forEach((key, value) { + final Iterable<(Network, String)> ll = value.map((e) => (key, e)); + pairs.addAll(ll); + }); + + final List>> futures = + pairs.map((e) => _profileService.getProfile(e.$2, e.$1)).toList(); + final List> profiles = await Future.wait(futures); @@ -25,15 +32,17 @@ class GetUserProfilesFromAccountsUseCase { userProfiles.add(UserProfileData( accountName: profileData.account, userName: profileData.name, - userImage: profileData.getAvatarUrl(), + userImage: profileData.avatarUrl, bio: profileData.bio, + network: profileData.network, )); } else { userProfiles.add(UserProfileData( - accountName: accounts[index], + accountName: pairs[index].$2, userName: null, userImage: null, bio: null, + network: pairs[index].$1, )); } }); diff --git a/test/parse_esr_link_test.dart b/test/parse_esr_link_test.dart index 9db84849..57b182a3 100644 --- a/test/parse_esr_link_test.dart +++ b/test/parse_esr_link_test.dart @@ -9,7 +9,7 @@ import 'mocks/mock_secure_storage_service.dart'; class MockEosService extends EOSService { MockEosService(super.secureStorageService, super.remoteConfigService); @override - EOSClient getEosClientForNetwork(Networks network, {List privateKeys = const []}) { + EOSClient getEosClientForNetwork(Network network, {List privateKeys = const []}) { return EOSClient(baseUrl: 'https://mainnet.telos.net', privateKeys: [], version: 'v1'); } }