diff --git a/lib/database/cloud_database.dart b/lib/database/cloud_database.dart index 334a56353..fc071ec43 100644 --- a/lib/database/cloud_database.dart +++ b/lib/database/cloud_database.dart @@ -9,13 +9,10 @@ import 'dart:async'; import 'package:autonomy_flutter/database/dao/address_dao.dart'; import 'package:autonomy_flutter/database/dao/connection_dao.dart'; -import 'package:autonomy_flutter/database/dao/persona_dao.dart'; import 'package:autonomy_flutter/database/entity/connection.dart'; -import 'package:autonomy_flutter/database/entity/persona.dart'; +import 'package:autonomy_flutter/database/entity/identity.dart'; import 'package:autonomy_flutter/database/entity/wallet_address.dart'; -import 'package:autonomy_flutter/util/constants.dart'; import 'package:autonomy_flutter/util/log.dart'; -import 'package:autonomy_flutter/util/wallet_storage_ext.dart'; import 'package:floor/floor.dart'; import 'package:sqflite/sqflite.dart' as sqflite; @@ -23,24 +20,18 @@ part 'cloud_database.g.dart'; // the generated code will be there //ignore_for_file: lines_longer_than_80_chars @TypeConverters([DateTimeConverter]) -@Database(version: 9, entities: [Persona, Connection, WalletAddress]) +@Database(version: 10, entities: [Connection, WalletAddress]) abstract class CloudDatabase extends FloorDatabase { - PersonaDao get personaDao; - ConnectionDao get connectionDao; WalletAddressDao get addressDao; Future removeAll() async { - await personaDao.removeAll(); await connectionDao.removeAll(); await addressDao.removeAll(); } Future copyDataFrom(CloudDatabase source) async { - await source.personaDao.getPersonas().then((personas) async { - await personaDao.insertPersonas(personas); - }); await source.connectionDao.getConnections().then((connections) async { await connectionDao.insertConnections(connections); }); @@ -135,47 +126,7 @@ final migrateCloudV4ToV5 = Migration(4, 5, (database) async { final migrateCloudV5ToV6 = Migration(5, 6, (database) async { await database.execute( 'CREATE TABLE IF NOT EXISTS `WalletAddress` (`address` TEXT NOT NULL, `uuid` TEXT NOT NULL, `index` INTEGER NOT NULL, `cryptoType` TEXT NOT NULL, `createdAt` INTEGER NOT NULL, `isHidden` INTEGER NOT NULL, PRIMARY KEY (`address`))'); - log.info('Migrating Cloud database: created WalletAddress table'); - final personaTable = await database.query('Persona'); - final personas = personaTable.map((e) => Persona.fromJson(e)).toList(); - log.info('Migrating Cloud database: personas ' - '${personas.map((e) => e.toJson()).toList()}'); - for (var persona in personas) { - List? tezIndexesStr = (persona.tezosIndexes ?? '').split(',') - ..removeWhere((element) => element.isEmpty); - log.info('Migrating Cloud database: tezIndexesStr $tezIndexesStr'); - final tezIndexes = tezIndexesStr.map((e) => int.parse(e)).toList(); - for (var index in tezIndexes) { - await database.insert( - 'WalletAddress', - { - 'address': await persona.wallet().getTezosAddress(index: index), - 'uuid': persona.uuid, - 'index': index, - 'cryptoType': CryptoType.XTZ.source, - 'createdAt': persona.createdAt.millisecondsSinceEpoch, - 'isHidden': 0, - }, - conflictAlgorithm: sqflite.ConflictAlgorithm.ignore); - } - List? ethIndexesStr = (persona.ethereumIndexes ?? '').split(',') - ..removeWhere((element) => element.isEmpty); - log.info('Migrating Cloud database: ethIndexesStr $ethIndexesStr'); - final ethIndexes = ethIndexesStr.map((e) => int.parse(e)).toList(); - for (var index in ethIndexes) { - await database.insert( - 'WalletAddress', - { - 'address': await persona.wallet().getETHEip55Address(index: index), - 'uuid': persona.uuid, - 'index': index, - 'cryptoType': CryptoType.ETH.source, - 'createdAt': persona.createdAt.millisecondsSinceEpoch, - 'isHidden': 0, - }, - conflictAlgorithm: sqflite.ConflictAlgorithm.ignore); - } - } + log.info('Migrated Cloud database from version 5 to 6'); }); diff --git a/lib/database/cloud_database.g.dart b/lib/database/cloud_database.g.dart index 16987056b..ff85a8ea1 100644 --- a/lib/database/cloud_database.g.dart +++ b/lib/database/cloud_database.g.dart @@ -61,8 +61,6 @@ class _$CloudDatabase extends CloudDatabase { changeListener = listener ?? StreamController.broadcast(); } - PersonaDao? _personaDaoInstance; - ConnectionDao? _connectionDaoInstance; WalletAddressDao? _addressDaoInstance; @@ -88,8 +86,6 @@ class _$CloudDatabase extends CloudDatabase { await callback?.onUpgrade?.call(database, startVersion, endVersion); }, onCreate: (database, version) async { - await database.execute( - 'CREATE TABLE IF NOT EXISTS `Persona` (`uuid` TEXT NOT NULL, `name` TEXT NOT NULL, `createdAt` INTEGER NOT NULL, `defaultAccount` INTEGER, `ethereumIndex` INTEGER NOT NULL, `tezosIndex` INTEGER NOT NULL, `ethereumIndexes` TEXT, `tezosIndexes` TEXT, PRIMARY KEY (`uuid`))'); await database.execute( 'CREATE TABLE IF NOT EXISTS `Connection` (`key` TEXT NOT NULL, `name` TEXT NOT NULL, `data` TEXT NOT NULL, `connectionType` TEXT NOT NULL, `accountNumber` TEXT NOT NULL, `createdAt` INTEGER NOT NULL, `accountOrder` INTEGER, PRIMARY KEY (`key`))'); await database.execute( @@ -101,11 +97,6 @@ class _$CloudDatabase extends CloudDatabase { return sqfliteDatabaseFactory.openDatabase(path, options: databaseOptions); } - @override - PersonaDao get personaDao { - return _personaDaoInstance ??= _$PersonaDao(database, changeListener); - } - @override ConnectionDao get connectionDao { return _connectionDaoInstance ??= _$ConnectionDao(database, changeListener); @@ -117,142 +108,6 @@ class _$CloudDatabase extends CloudDatabase { } } -class _$PersonaDao extends PersonaDao { - _$PersonaDao( - this.database, - this.changeListener, - ) : _queryAdapter = QueryAdapter(database), - _personaInsertionAdapter = InsertionAdapter( - database, - 'Persona', - (Persona item) => { - 'uuid': item.uuid, - 'name': item.name, - 'createdAt': _dateTimeConverter.encode(item.createdAt), - 'defaultAccount': item.defaultAccount, - 'ethereumIndex': item.ethereumIndex, - 'tezosIndex': item.tezosIndex, - 'ethereumIndexes': item.ethereumIndexes, - 'tezosIndexes': item.tezosIndexes - }), - _personaUpdateAdapter = UpdateAdapter( - database, - 'Persona', - ['uuid'], - (Persona item) => { - 'uuid': item.uuid, - 'name': item.name, - 'createdAt': _dateTimeConverter.encode(item.createdAt), - 'defaultAccount': item.defaultAccount, - 'ethereumIndex': item.ethereumIndex, - 'tezosIndex': item.tezosIndex, - 'ethereumIndexes': item.ethereumIndexes, - 'tezosIndexes': item.tezosIndexes - }), - _personaDeletionAdapter = DeletionAdapter( - database, - 'Persona', - ['uuid'], - (Persona item) => { - 'uuid': item.uuid, - 'name': item.name, - 'createdAt': _dateTimeConverter.encode(item.createdAt), - 'defaultAccount': item.defaultAccount, - 'ethereumIndex': item.ethereumIndex, - 'tezosIndex': item.tezosIndex, - 'ethereumIndexes': item.ethereumIndexes, - 'tezosIndexes': item.tezosIndexes - }); - - final sqflite.DatabaseExecutor database; - - final StreamController changeListener; - - final QueryAdapter _queryAdapter; - - final InsertionAdapter _personaInsertionAdapter; - - final UpdateAdapter _personaUpdateAdapter; - - final DeletionAdapter _personaDeletionAdapter; - - @override - Future> getPersonas() async { - return _queryAdapter.queryList('SELECT * FROM Persona', - mapper: (Map row) => Persona( - uuid: row['uuid'] as String, - name: row['name'] as String, - createdAt: _dateTimeConverter.decode(row['createdAt'] as int), - defaultAccount: row['defaultAccount'] as int?, - ethereumIndex: row['ethereumIndex'] as int, - tezosIndex: row['tezosIndex'] as int, - ethereumIndexes: row['ethereumIndexes'] as String?, - tezosIndexes: row['tezosIndexes'] as String?)); - } - - @override - Future> getDefaultPersonas() async { - return _queryAdapter.queryList( - 'SELECT * FROM Persona WHERE defaultAccount=1', - mapper: (Map row) => Persona( - uuid: row['uuid'] as String, - name: row['name'] as String, - createdAt: _dateTimeConverter.decode(row['createdAt'] as int), - defaultAccount: row['defaultAccount'] as int?, - ethereumIndex: row['ethereumIndex'] as int, - tezosIndex: row['tezosIndex'] as int, - ethereumIndexes: row['ethereumIndexes'] as String?, - tezosIndexes: row['tezosIndexes'] as String?)); - } - - @override - Future getPersonasCount() async { - return _queryAdapter.query('SELECT COUNT(*) FROM Persona', - mapper: (Map row) => row.values.first as int); - } - - @override - Future findById(String uuid) async { - return _queryAdapter.query('SELECT * FROM Persona WHERE uuid = ?1', - mapper: (Map row) => Persona( - uuid: row['uuid'] as String, - name: row['name'] as String, - createdAt: _dateTimeConverter.decode(row['createdAt'] as int), - defaultAccount: row['defaultAccount'] as int?, - ethereumIndex: row['ethereumIndex'] as int, - tezosIndex: row['tezosIndex'] as int, - ethereumIndexes: row['ethereumIndexes'] as String?, - tezosIndexes: row['tezosIndexes'] as String?), - arguments: [uuid]); - } - - @override - Future removeAll() async { - await _queryAdapter.queryNoReturn('DELETE FROM Persona'); - } - - @override - Future insertPersona(Persona persona) async { - await _personaInsertionAdapter.insert(persona, OnConflictStrategy.replace); - } - - @override - Future insertPersonas(List personas) async { - await _personaInsertionAdapter.insertList( - personas, OnConflictStrategy.replace); - } - - @override - Future updatePersona(Persona persona) async { - await _personaUpdateAdapter.update(persona, OnConflictStrategy.abort); - } - - @override - Future deletePersona(Persona persona) async { - await _personaDeletionAdapter.delete(persona); - } -} - class _$ConnectionDao extends ConnectionDao { _$ConnectionDao( this.database, diff --git a/lib/database/dao/persona_dao.dart b/lib/database/dao/persona_dao.dart deleted file mode 100644 index 9ac97cb46..000000000 --- a/lib/database/dao/persona_dao.dart +++ /dev/null @@ -1,39 +0,0 @@ -// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// Copyright © 2022 Bitmark. All rights reserved. -// Use of this source code is governed by the BSD-2-Clause Plus Patent License -// that can be found in the LICENSE file. -// - -import 'package:autonomy_flutter/database/entity/persona.dart'; -import 'package:floor/floor.dart'; - -@dao -abstract class PersonaDao { - @Query('SELECT * FROM Persona') - Future> getPersonas(); - - @Query('SELECT * FROM Persona WHERE defaultAccount=1') - Future> getDefaultPersonas(); - - @Query('SELECT COUNT(*) FROM Persona') - Future getPersonasCount(); - - @Insert(onConflict: OnConflictStrategy.replace) - Future insertPersona(Persona persona); - - @Insert(onConflict: OnConflictStrategy.replace) - Future insertPersonas(List personas); - - @Query('SELECT * FROM Persona WHERE uuid = :uuid') - Future findById(String uuid); - - @update - Future updatePersona(Persona persona); - - @delete - Future deletePersona(Persona persona); - - @Query('DELETE FROM Persona') - Future removeAll(); -} diff --git a/lib/database/entity/persona.dart b/lib/database/entity/persona.dart deleted file mode 100644 index 6ef86864c..000000000 --- a/lib/database/entity/persona.dart +++ /dev/null @@ -1,255 +0,0 @@ -// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// Copyright © 2022 Bitmark. All rights reserved. -// Use of this source code is governed by the BSD-2-Clause Plus Patent License -// that can be found in the LICENSE file. -// - -import 'package:autonomy_flutter/common/injector.dart'; -import 'package:autonomy_flutter/database/cloud_database.dart'; -import 'package:autonomy_flutter/database/entity/wallet_address.dart'; -import 'package:autonomy_flutter/service/account_service.dart'; -import 'package:autonomy_flutter/util/constants.dart'; -import 'package:autonomy_flutter/util/wallet_storage_ext.dart'; -import 'package:autonomy_flutter/util/wallet_utils.dart'; -import 'package:collection/collection.dart'; -import 'package:floor/floor.dart'; -import 'package:libauk_dart/libauk_dart.dart'; -import 'package:nft_collection/services/address_service.dart'; - -class DateTimeConverter extends TypeConverter { - @override - DateTime decode(int databaseValue) => - DateTime.fromMillisecondsSinceEpoch(databaseValue); - - @override - int encode(DateTime value) => value.millisecondsSinceEpoch; -} - -@entity -class Persona { - @primaryKey - String uuid; - String name; - DateTime createdAt; - int? defaultAccount; - int ethereumIndex; - int tezosIndex; - String? ethereumIndexes; - String? tezosIndexes; - - Persona( - {required this.uuid, - required this.name, - required this.createdAt, - this.defaultAccount, - this.ethereumIndex = 1, - this.tezosIndex = 1, - this.ethereumIndexes = '', - this.tezosIndexes = ''}); - - Persona.newPersona( - {required this.uuid, - this.name = '', - this.defaultAccount, - DateTime? createdAt, - this.ethereumIndex = 1, - this.tezosIndex = 1, - this.ethereumIndexes = '0', - this.tezosIndexes = '0'}) - : createdAt = createdAt ?? DateTime.now(); - - Persona copyWith({ - String? name, - DateTime? createdAt, - String? ethereumIndexes, - String? tezosIndexes, - }) => - Persona( - uuid: uuid, - name: name ?? this.name, - defaultAccount: defaultAccount, - createdAt: createdAt ?? this.createdAt, - ethereumIndexes: ethereumIndexes ?? this.ethereumIndexes, - tezosIndexes: tezosIndexes ?? this.tezosIndexes); - - // fromJson method - factory Persona.fromJson(Map json) => Persona( - uuid: json['uuid'], - name: json['name'], - createdAt: DateTimeConverter().decode(json['createdAt']), - defaultAccount: json['defaultAccount'], - ethereumIndex: json['ethereumIndex'], - tezosIndex: json['tezosIndex'], - ethereumIndexes: json['ethereumIndexes'], - tezosIndexes: json['tezosIndexes'], - ); - - // toJson method - Map toJson() => { - 'uuid': uuid, - 'name': name, - 'createdAt': DateTimeConverter().encode(createdAt), - 'defaultAccount': defaultAccount, - 'ethereumIndex': ethereumIndex, - 'tezosIndex': tezosIndex, - 'ethereumIndexes': ethereumIndexes, - 'tezosIndexes': tezosIndexes, - }; - - WalletStorage wallet() => LibAukDart.getWallet(uuid); - - Future> getWalletAddresses() async => - injector().addressDao.findByWalletID(uuid); - - Future> getEthWalletAddresses() async => - injector() - .addressDao - .getAddresses(uuid, CryptoType.ETH.source); - - Future> getTezWalletAddresses() async => - injector() - .addressDao - .getAddresses(uuid, CryptoType.XTZ.source); - - bool isDefault() => defaultAccount == 1; - - Future> getAddresses() async { - final walletAddress = await getWalletAddresses(); - return walletAddress.map((e) => e.address).toList(); - } - - Future> getEthAddresses() async { - final walletAddress = await getEthWalletAddresses(); - return walletAddress.map((e) => e.address).toList(); - } - - Future> getTezosAddresses() async { - final walletAddress = await getTezWalletAddresses(); - return walletAddress.map((e) => e.address).toList(); - } - - Future getAddressIndex(String address) async { - final walletAddress = - await injector().addressDao.findByAddress(address); - if (walletAddress != null) { - return walletAddress.index; - } - return null; - } - - Future _generateETHAddressByIndex(int index, - {String? name}) async => - WalletAddress( - address: await wallet().getETHEip55Address(index: index), - uuid: uuid, - index: index, - cryptoType: CryptoType.ETH.source, - createdAt: DateTime.now(), - name: name ?? CryptoType.ETH.source); - - Future _generateTezosAddressByIndex(int index, - {String? name}) async => - WalletAddress( - address: await wallet().getTezosAddress(index: index), - uuid: uuid, - index: index, - cryptoType: CryptoType.XTZ.source, - createdAt: DateTime.now(), - name: name ?? CryptoType.XTZ.source); - - Future> insertAddressAtIndex( - {required WalletType walletType, - required int index, - String? name}) async { - List walletAddresses = []; - switch (walletType) { - case WalletType.Ethereum: - walletAddresses = [await _generateETHAddressByIndex(index, name: name)]; - case WalletType.Tezos: - walletAddresses = [ - await _generateTezosAddressByIndex(index, name: name), - ]; - case WalletType.Autonomy: - walletAddresses = [ - await _generateETHAddressByIndex(index, name: name), - await _generateTezosAddressByIndex(index, name: name) - ]; - } - await injector() - .removeDoubleViewOnly(walletAddresses.map((e) => e.address).toList()); - await injector().addressDao.insertAddresses(walletAddresses); - await injector() - .addAddresses(walletAddresses.map((e) => e.address).toList()); - return walletAddresses; - } - - Future> insertNextAddress(WalletType walletType, - {String? name}) async { - final List addresses = []; - final walletAddresses = await getWalletAddresses(); - final ethIndexes = walletAddresses - .where((element) => element.cryptoType == CryptoType.ETH.source) - .map((e) => e.index) - .toList(); - final ethIndex = _getNextIndex(ethIndexes); - final tezIndexes = walletAddresses - .where((element) => element.cryptoType == CryptoType.XTZ.source) - .map((e) => e.index) - .toList(); - final tezIndex = _getNextIndex(tezIndexes); - final ethAddress = WalletAddress( - address: await wallet().getETHEip55Address(index: ethIndex), - uuid: uuid, - index: ethIndex, - cryptoType: CryptoType.ETH.source, - createdAt: DateTime.now(), - name: name ?? CryptoType.ETH.source); - final tezAddress = WalletAddress( - address: await wallet().getTezosAddress(index: tezIndex), - uuid: uuid, - index: tezIndex, - cryptoType: CryptoType.XTZ.source, - createdAt: DateTime.now(), - name: name ?? CryptoType.XTZ.source); - switch (walletType) { - case WalletType.Ethereum: - addresses.add(ethAddress); - case WalletType.Tezos: - addresses.add(tezAddress); - default: - addresses.addAll([ethAddress, tezAddress]); - } - await injector() - .removeDoubleViewOnly(addresses.map((e) => e.address).toList()); - await injector().addressDao.insertAddresses(addresses); - await injector() - .addAddresses(addresses.map((e) => e.address).toList()); - return addresses; - } - - int _getNextIndex(List indexes) => (indexes.maxOrNull ?? -1) + 1; - - @override - bool operator ==(covariant Persona other) { - if (identical(this, other)) { - return true; - } - - return other.uuid == uuid && - other.name == name && - other.createdAt == createdAt && - other.defaultAccount == defaultAccount && - other.ethereumIndexes == ethereumIndexes && - other.tezosIndexes == tezosIndexes; - } - - @override - int get hashCode => - uuid.hashCode ^ - name.hashCode ^ - createdAt.hashCode ^ - defaultAccount.hashCode ^ - ethereumIndexes.hashCode ^ - tezosIndexes.hashCode; -} diff --git a/lib/database/entity/wallet_address.dart b/lib/database/entity/wallet_address.dart index f9c6ebdc9..5c388b6e7 100644 --- a/lib/database/entity/wallet_address.dart +++ b/lib/database/entity/wallet_address.dart @@ -1,4 +1,3 @@ -import 'package:autonomy_flutter/database/entity/persona.dart'; import 'package:floor/floor.dart'; import 'package:nft_collection/models/address_index.dart'; @@ -6,11 +5,6 @@ import 'package:nft_collection/models/address_index.dart'; class WalletAddress { @primaryKey final String address; - @ForeignKey( - childColumns: ['uuid'], - parentColumns: ['uuid'], - entity: Persona, - onDelete: ForeignKeyAction.cascade) final String uuid; final int index; final String cryptoType; diff --git a/lib/screen/app_router.dart b/lib/screen/app_router.dart index e1e00ea4e..da8382477 100644 --- a/lib/screen/app_router.dart +++ b/lib/screen/app_router.dart @@ -7,7 +7,6 @@ import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/database/app_database.dart'; -import 'package:autonomy_flutter/database/cloud_database.dart'; import 'package:autonomy_flutter/database/entity/connection.dart'; import 'package:autonomy_flutter/model/connection_request_args.dart'; import 'package:autonomy_flutter/model/ff_exhibition.dart'; @@ -27,7 +26,6 @@ import 'package:autonomy_flutter/screen/bloc/accounts/accounts_bloc.dart'; import 'package:autonomy_flutter/screen/bloc/connections/connections_bloc.dart'; import 'package:autonomy_flutter/screen/bloc/ethereum/ethereum_bloc.dart'; import 'package:autonomy_flutter/screen/bloc/identity/identity_bloc.dart'; -import 'package:autonomy_flutter/screen/bloc/persona/persona_bloc.dart'; import 'package:autonomy_flutter/screen/bloc/scan_wallet/scan_wallet_bloc.dart'; import 'package:autonomy_flutter/screen/bloc/subscription/subscription_bloc.dart'; import 'package:autonomy_flutter/screen/bloc/tezos/tezos_bloc.dart'; @@ -241,12 +239,9 @@ class AppRouter { static Route onGenerateRoute(RouteSettings settings) { final ethereumBloc = EthereumBloc(injector(), injector()); final tezosBloc = TezosBloc(injector(), injector()); - final usdcBloc = USDCBloc(injector(), injector()); + final usdcBloc = USDCBloc(injector()); final accountsBloc = AccountsBloc(injector(), injector()); - final personaBloc = PersonaBloc( - injector(), - injector(), - ); + final connectionsBloc = injector(); final identityBloc = IdentityBloc(injector(), injector()); final canvasDeviceBloc = injector(); @@ -366,9 +361,6 @@ class AppRouter { BlocProvider.value( value: subscriptionBloc, ), - BlocProvider( - create: (_) => personaBloc, - ), BlocProvider(lazy: false, create: (_) => connectionsBloc), BlocProvider(create: (_) => canvasDeviceBloc), ], @@ -395,9 +387,6 @@ class AppRouter { BlocProvider.value( value: subscriptionBloc, ), - BlocProvider( - create: (_) => personaBloc, - ), BlocProvider(create: (_) => canvasDeviceBloc), /// The page itself doesn't need to use the bloc. @@ -553,7 +542,6 @@ class AppRouter { settings: settings, builder: (context) => MultiBlocProvider(providers: [ BlocProvider.value(value: accountsBloc), - BlocProvider(create: (_) => personaBloc), BlocProvider.value(value: ethereumBloc), BlocProvider.value(value: tezosBloc), BlocProvider(create: (_) => identityBloc), @@ -695,11 +683,8 @@ class AppRouter { case addressAliasPage: return CupertinoPageRoute( settings: settings, - builder: (context) => BlocProvider( - create: (_) => personaBloc, - child: AddressAlias( - payload: settings.arguments! as AddressAliasPayload), - )); + builder: (context) => AddressAlias( + payload: settings.arguments! as AddressAliasPayload)); case galleryPage: return CupertinoPageRoute( @@ -955,9 +940,6 @@ class AppRouter { builder: (context) => MultiBlocProvider( providers: [ BlocProvider.value(value: accountsBloc), - BlocProvider( - create: (_) => personaBloc, - ), ], child: WCConnectPage( connectionRequest: settings.arguments! as Wc2Proposal, @@ -977,9 +959,6 @@ class AppRouter { builder: (context) => MultiBlocProvider( providers: [ BlocProvider.value(value: accountsBloc), - BlocProvider( - create: (_) => personaBloc, - ), ], child: Wc2RequestPage( request: settings.arguments! as Wc2RequestPayload))); @@ -990,9 +969,6 @@ class AppRouter { builder: (context) => MultiBlocProvider( providers: [ BlocProvider.value(value: accountsBloc), - BlocProvider( - create: (_) => personaBloc, - ), ], child: WalletPage( payload: settings.arguments as WalletPagePayload?, diff --git a/lib/screen/bloc/accounts/accounts_bloc.dart b/lib/screen/bloc/accounts/accounts_bloc.dart index f28f27847..4a7e082a5 100644 --- a/lib/screen/bloc/accounts/accounts_bloc.dart +++ b/lib/screen/bloc/accounts/accounts_bloc.dart @@ -11,7 +11,6 @@ import 'package:autonomy_flutter/au_bloc.dart'; import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/database/cloud_database.dart'; import 'package:autonomy_flutter/database/entity/connection.dart'; -import 'package:autonomy_flutter/database/entity/persona.dart'; import 'package:autonomy_flutter/database/entity/wallet_address.dart'; import 'package:autonomy_flutter/model/network.dart'; import 'package:autonomy_flutter/service/account_service.dart'; @@ -95,7 +94,7 @@ class AccountsBloc extends AuBloc { final batch = tx.batch(); for (int i = 0; i < accounts.length; i++) { final account = accounts[i]; - if (account.persona != null) { + if (account.walletAddress != null) { batch.update('WalletAddress', {'accountOrder': i}, where: 'address = ?', whereArgs: [account.key]); } else { @@ -123,33 +122,28 @@ class AccountsBloc extends AuBloc { switch (type) { case WalletType.Autonomy: addresses = await _cloudDB.addressDao.getAllAddresses(); - break; case WalletType.Ethereum: addresses = await _cloudDB.addressDao .getAddressesByType(CryptoType.ETH.source); - break; case WalletType.Tezos: addresses = await _cloudDB.addressDao .getAddressesByType(CryptoType.XTZ.source); - break; default: addresses = []; } if (event.autoAddAddress) { - final persona = - await injector().getOrCreateDefaultPersona(); if (event.getEth && addresses.none( (element) => element.cryptoType == CryptoType.ETH.source)) { final ethAddress = - await persona.insertNextAddress(WalletType.Ethereum); + await _accountService.insertNextAddress(WalletType.Ethereum); addresses.add(ethAddress.first); } if (event.getTezos && addresses.none( (element) => element.cryptoType == CryptoType.XTZ.source)) { final tezosAddress = - await persona.insertNextAddress(WalletType.Tezos); + await _accountService.insertNextAddress(WalletType.Tezos); addresses.add(tezosAddress.first); } } @@ -187,10 +181,10 @@ class AccountsBloc extends AuBloc { emit(state.copyWith(accounts: accounts)); }); - on((event, emit) { + on((event, emit) async { final connection = event.connection..name = event.name; - _cloudDB.connectionDao.updateConnection(connection); + await _cloudDB.connectionDao.updateConnection(connection); add(GetAccountsEvent()); }); @@ -208,21 +202,6 @@ class AccountsBloc extends AuBloc { emit(newState.setEvent(null)); }); }); - - on((event, emit) async { - final persona = await _cloudDB.personaDao.findById(event.personaUUID); - List accounts = []; - if (persona != null) { - accounts.add(Account( - key: persona.uuid, - persona: persona, - name: persona.name, - blockchain: event.type.source, - accountNumber: event.address, - createdAt: persona.createdAt)); - } - emit(AccountsState(accounts: accounts)); - }); } Future getExistingAccount(String accountNumber) async { @@ -238,24 +217,18 @@ class AccountsBloc extends AuBloc { Future> getAccountPersona( List walletAddresses) async { - final personas = await _cloudDB.personaDao.getPersonas(); final List addresses = [...walletAddresses]; List accounts = []; for (var e in addresses) { final name = e.name != null && e.name!.isNotEmpty ? e.name : e.cryptoType; - final persona = - personas.firstWhereOrNull((element) => element.uuid == e.uuid); - if (persona != null) { - accounts.add(Account( - key: e.address, - persona: persona, - name: name ?? '', - blockchain: e.cryptoType, - walletAddress: e, - accountNumber: e.address, - createdAt: e.createdAt, - accountOrder: e.accountOrder)); - } + accounts.add(Account( + key: e.address, + name: name ?? '', + blockchain: e.cryptoType, + walletAddress: e, + accountNumber: e.address, + createdAt: e.createdAt, + accountOrder: e.accountOrder)); } return accounts; } @@ -275,14 +248,8 @@ class AccountsBloc extends AuBloc { return a.accountOrder!.compareTo(b.accountOrder!); } - int _compareAccountWithoutOrder(Account a, Account b) { - final aDefault = a.persona?.defaultAccount ?? 0; - final bDefault = b.persona?.defaultAccount ?? 0; - if (aDefault != bDefault) { - return bDefault.compareTo(aDefault); - } - return a.createdAt.compareTo(b.createdAt); - } + int _compareAccountWithoutOrder(Account a, Account b) => + a.createdAt.compareTo(b.createdAt); Account _getAccountFromConnectionAddress( Connection connection, String address) { diff --git a/lib/screen/bloc/accounts/accounts_state.dart b/lib/screen/bloc/accounts/accounts_state.dart index c52d92569..335e0ea83 100644 --- a/lib/screen/bloc/accounts/accounts_state.dart +++ b/lib/screen/bloc/accounts/accounts_state.dart @@ -59,17 +59,8 @@ class NameLinkedAccountEvent extends AccountsEvent { class FetchAllAddressesEvent extends AccountsEvent {} -class FindAccount extends AccountsEvent { - final String personaUUID; - final String address; - final CryptoType type; - - FindAccount(this.personaUUID, this.address, this.type); -} - class Account { String key; - Persona? persona; List? connections; String name; String? blockchain; @@ -84,15 +75,13 @@ class Account { bool get isUsdc => blockchain == 'USDC'; - String get className => - persona != null && walletAddress != null ? 'Persona' : 'Connection'; + String get className => walletAddress != null ? 'Persona' : 'Connection'; - bool get isViewOnly => persona == null && walletAddress == null; + bool get isViewOnly => walletAddress == null; Account({ required this.key, required this.createdAt, - this.persona, this.connections, this.blockchain, this.walletAddress, @@ -108,7 +97,6 @@ class Account { } return other.key == key && - other.persona == persona && listEquals(other.connections, connections) && other.name == name && other.blockchain == blockchain && @@ -121,7 +109,6 @@ class Account { @override int get hashCode => key.hashCode ^ - persona.hashCode ^ connections.hashCode ^ name.hashCode ^ blockchain.hashCode ^ diff --git a/lib/screen/bloc/persona/persona_bloc.dart b/lib/screen/bloc/persona/persona_bloc.dart deleted file mode 100644 index f8213e661..000000000 --- a/lib/screen/bloc/persona/persona_bloc.dart +++ /dev/null @@ -1,69 +0,0 @@ -// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// Copyright © 2022 Bitmark. All rights reserved. -// Use of this source code is governed by the BSD-2-Clause Plus Patent License -// that can be found in the LICENSE file. -// - -import 'package:autonomy_flutter/au_bloc.dart'; -import 'package:autonomy_flutter/database/cloud_database.dart'; -import 'package:autonomy_flutter/database/entity/persona.dart'; -import 'package:autonomy_flutter/service/account_service.dart'; -import 'package:autonomy_flutter/util/log.dart'; -import 'package:autonomy_flutter/util/string_ext.dart'; -import 'package:autonomy_flutter/util/ui_helper.dart'; -import 'package:autonomy_flutter/util/wallet_storage_ext.dart'; -import 'package:autonomy_flutter/util/wallet_utils.dart'; - -part 'persona_state.dart'; - -class PersonaBloc extends AuBloc { - final CloudDatabase _cloudDB; - final AccountService _accountService; - - PersonaBloc(this._cloudDB, this._accountService) : super(PersonaState()) { - on((event, emit) async { - final personas = await _cloudDB.personaDao.getPersonas(); - List namedPersonas = []; - - for (var persona in personas) { - if (persona.name.isEmpty) { - final address = await persona.wallet().getETHEip55Address(); - namedPersonas.add(persona.copyWith( - name: event.useDidKeyForAlias - ? await persona.wallet().getAccountDID() - : address.mask(4), - )); - } else { - namedPersonas.add(persona); - } - } - - namedPersonas.sort((a, b) => a.createdAt.compareTo(b.createdAt)); - emit(state.copyWith(personas: namedPersonas)); - }); - - on((event, emit) async { - final persona = await _cloudDB.personaDao.findById(event.uuid); - emit(state.copyWith(persona: persona)); - }); - - on((event, emit) async { - await _accountService.deletePersona(event.persona); - emit(state.copyWith(deletePersonaState: ActionState.done)); - }); - - on((event, emit) async { - emit(PersonaState(createAccountState: ActionState.loading)); - try { - final persona = await _accountService.getOrCreateDefaultPersona(); - await persona.insertNextAddress(event.walletType, name: event.name); - emit(PersonaState( - createAccountState: ActionState.done, persona: persona)); - } catch (e) { - log.info('CreatePersonaAddressesEvent error', e); - emit(state.copyWith(createAccountState: ActionState.error)); - } - }); - } -} diff --git a/lib/screen/bloc/persona/persona_state.dart b/lib/screen/bloc/persona/persona_state.dart deleted file mode 100644 index 6290ee46c..000000000 --- a/lib/screen/bloc/persona/persona_state.dart +++ /dev/null @@ -1,76 +0,0 @@ -// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// Copyright © 2022 Bitmark. All rights reserved. -// Use of this source code is governed by the BSD-2-Clause Plus Patent License -// that can be found in the LICENSE file. -// - -part of 'persona_bloc.dart'; - -abstract class PersonaEvent {} - -class CreatePersonaAddressesEvent extends PersonaEvent { - final String? name; - final WalletType walletType; - - CreatePersonaAddressesEvent(this.walletType, {this.name}); -} - -class GetListPersonaEvent extends PersonaEvent { - final bool useDidKeyForAlias; - - GetListPersonaEvent({ - this.useDidKeyForAlias = false, - }); -} - -class ImportPersonaEvent extends PersonaEvent { - final String words; - - ImportPersonaEvent(this.words); -} - -class GetInfoPersonaEvent extends PersonaEvent { - final String uuid; - - GetInfoPersonaEvent(this.uuid); -} - -class DeletePersonaEvent extends PersonaEvent { - final Persona persona; - - // constructor - DeletePersonaEvent(this.persona); -} - -class PersonaState { - ActionState createAccountState = ActionState.notRequested; - ActionState namePersonaState = ActionState.notRequested; - ActionState deletePersonaState = ActionState.notRequested; - - Persona? persona; - List? personas; - - PersonaState({ - this.createAccountState = ActionState.notRequested, - this.namePersonaState = ActionState.notRequested, - this.deletePersonaState = ActionState.notRequested, - this.persona, - this.personas, - }); - - PersonaState copyWith({ - ActionState? createAccountState, - ActionState? namePersonaState, - ActionState? deletePersonaState, - Persona? persona, - List? personas, - }) => - PersonaState( - createAccountState: createAccountState ?? this.createAccountState, - namePersonaState: namePersonaState ?? this.namePersonaState, - deletePersonaState: deletePersonaState ?? this.deletePersonaState, - persona: persona ?? this.persona, - personas: personas ?? this.personas, - ); -} diff --git a/lib/screen/bloc/usdc/usdc_bloc.dart b/lib/screen/bloc/usdc/usdc_bloc.dart index 53ce1e8c3..9abb5965b 100644 --- a/lib/screen/bloc/usdc/usdc_bloc.dart +++ b/lib/screen/bloc/usdc/usdc_bloc.dart @@ -10,20 +10,20 @@ import 'package:autonomy_flutter/service/account_service.dart'; import 'package:autonomy_flutter/service/ethereum_service.dart'; import 'package:autonomy_flutter/util/constants.dart'; import 'package:autonomy_flutter/util/wallet_storage_ext.dart'; +import 'package:libauk_dart/libauk_dart.dart'; import 'package:web3dart/web3dart.dart'; part 'usdc_state.dart'; class USDCBloc extends AuBloc { final EthereumService _ethereumService; - final AccountService _accountService; - USDCBloc(this._ethereumService, this._accountService) - : super(USDCState(null, {})) { + USDCBloc(this._ethereumService) : super(USDCState(null, {})) { on((event, emit) async { - if (state.personaAddresses?[event.uuid] != null) return; - final address = await (await _accountService.getPersona(uuid: event.uuid)) - .wallet() + if (state.personaAddresses?[event.uuid] != null) { + return; + } + final address = await WalletStorage(event.uuid) .getETHEip55Address(index: event.index); var personaAddresses = state.personaAddresses ?? {}; personaAddresses[event.uuid] = address; @@ -45,8 +45,7 @@ class USDCBloc extends AuBloc { }); on((event, emit) async { - final address = await (await _accountService.getPersona(uuid: event.uuid)) - .wallet() + final address = await WalletStorage(event.uuid) .getETHEip55Address(index: event.index); final contractAddress = EthereumAddress.fromHex(usdcContractAddress); diff --git a/lib/screen/connection/persona_connections_page.dart b/lib/screen/connection/persona_connections_page.dart index 13d72a3f9..52a700db1 100644 --- a/lib/screen/connection/persona_connections_page.dart +++ b/lib/screen/connection/persona_connections_page.dart @@ -11,7 +11,6 @@ import 'dart:convert'; import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/main.dart'; import 'package:autonomy_flutter/screen/app_router.dart'; -import 'package:autonomy_flutter/screen/bloc/accounts/accounts_bloc.dart'; import 'package:autonomy_flutter/screen/bloc/connections/connections_bloc.dart'; import 'package:autonomy_flutter/screen/bloc/ethereum/ethereum_bloc.dart'; import 'package:autonomy_flutter/screen/bloc/tezos/tezos_bloc.dart'; @@ -56,8 +55,6 @@ class _PersonaConnectionsPageState extends State super.initState(); final personUUID = widget.payload.personaUUID; final index = widget.payload.index; - context.read().add( - FindAccount(personUUID, widget.payload.address, widget.payload.type)); switch (widget.payload.type) { case CryptoType.ETH: context.read().add(GetEthereumAddressEvent(personUUID)); diff --git a/lib/screen/interactive_postcard/claim_empty_postcard/claim_empty_postcard_bloc.dart b/lib/screen/interactive_postcard/claim_empty_postcard/claim_empty_postcard_bloc.dart index e76deab8e..5f0a1107d 100644 --- a/lib/screen/interactive_postcard/claim_empty_postcard/claim_empty_postcard_bloc.dart +++ b/lib/screen/interactive_postcard/claim_empty_postcard/claim_empty_postcard_bloc.dart @@ -114,9 +114,8 @@ class ClaimEmptyPostCardBloc on((event, emit) async { emit(state.copyWith(isClaiming: true)); String? address; - final addresses = await accountService.getAddress('Tezos'); + final addresses = await accountService.getAddress('tezos'); if (addresses.isEmpty) { - final defaultPersona = await accountService.getOrCreateDefaultPersona(); await configService.setDoneOnboarding(true); await configService.setPendingSettings(true); await injector() @@ -124,7 +123,7 @@ class ClaimEmptyPostCardBloc .initIfDefaultAccount(); final walletAddress = - await defaultPersona.insertNextAddress(WalletType.Tezos); + await accountService.insertNextAddress(WalletType.Tezos); address = walletAddress.first.address; } else if (addresses.length == 1) { address = addresses.first; diff --git a/lib/screen/onboarding/import_address/import_seeds.dart b/lib/screen/onboarding/import_address/import_seeds.dart index a7596ef75..81f78953a 100644 --- a/lib/screen/onboarding/import_address/import_seeds.dart +++ b/lib/screen/onboarding/import_address/import_seeds.dart @@ -179,7 +179,7 @@ class _ImportSeedsPageState extends State { }); final accountService = injector(); - final persona = await accountService.importPersona( + final wallet = await accountService.importPersona( _getMnemonic(), _passphraseTextController.text.trim(), ); @@ -187,7 +187,7 @@ class _ImportSeedsPageState extends State { return; } unawaited(Navigator.of(context).pushNamed(AppRouter.selectAddressesPage, - arguments: SelectAddressesPayload(persona: persona))); + arguments: SelectAddressesPayload(wallet: wallet))); if (!mounted) { return; diff --git a/lib/screen/onboarding/import_address/select_addresses.dart b/lib/screen/onboarding/import_address/select_addresses.dart index 2b8c5ec92..d83d6fd6f 100644 --- a/lib/screen/onboarding/import_address/select_addresses.dart +++ b/lib/screen/onboarding/import_address/select_addresses.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:autonomy_flutter/common/injector.dart'; -import 'package:autonomy_flutter/database/entity/persona.dart'; +import 'package:autonomy_flutter/database/cloud_database.dart'; import 'package:autonomy_flutter/screen/app_router.dart'; import 'package:autonomy_flutter/screen/bloc/scan_wallet/scan_wallet_bloc.dart'; import 'package:autonomy_flutter/screen/bloc/scan_wallet/scan_wallet_state.dart'; @@ -21,6 +21,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:feralfile_app_theme/feral_file_app_theme.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:libauk_dart/libauk_dart.dart'; class SelectAddressesPage extends StatefulWidget { final SelectAddressesPayload payload; @@ -54,9 +55,11 @@ class _SelectAddressesPageState extends State { } Future fetchImportedAddresses() async { - final importedAddresses = await widget.payload.persona.getAddresses(); + final importedAddresses = await injector() + .addressDao + .getAddressesByPersona(widget.payload.wallet.uuid); setState(() { - _importedAddresses.addAll(importedAddresses); + _importedAddresses.addAll(importedAddresses.map((e) => e.address)); }); } @@ -174,7 +177,7 @@ class _SelectAddressesPageState extends State { enabled: _selectedAddresses.isNotEmpty, onTap: () async { await injector().addAddressPersona( - widget.payload.persona, _selectedAddresses); + widget.payload.wallet.uuid, _selectedAddresses); if (!context.mounted) { return; } @@ -265,7 +268,7 @@ class _SelectAddressesPageState extends State { } void _callBloc() { - final wallet = widget.payload.persona.wallet(); + final wallet = widget.payload.wallet; context .read() .add(ScanEthereumWalletEvent(wallet: wallet, startIndex: index)); @@ -278,7 +281,7 @@ class _SelectAddressesPageState extends State { } class SelectAddressesPayload { - final Persona persona; + final WalletStorage wallet; - SelectAddressesPayload({required this.persona}); + SelectAddressesPayload({required this.wallet}); } diff --git a/lib/screen/onboarding/new_address/address_alias.dart b/lib/screen/onboarding/new_address/address_alias.dart index bf0073be7..25934ecbf 100644 --- a/lib/screen/onboarding/new_address/address_alias.dart +++ b/lib/screen/onboarding/new_address/address_alias.dart @@ -1,6 +1,5 @@ -import 'dart:async'; - -import 'package:autonomy_flutter/screen/bloc/persona/persona_bloc.dart'; +import 'package:autonomy_flutter/common/injector.dart'; +import 'package:autonomy_flutter/service/account_service.dart'; import 'package:autonomy_flutter/util/ui_helper.dart'; import 'package:autonomy_flutter/util/wallet_utils.dart'; import 'package:autonomy_flutter/view/au_text_field.dart'; @@ -10,7 +9,6 @@ import 'package:autonomy_flutter/view/responsive.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:feralfile_app_theme/feral_file_app_theme.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; class AddressAlias extends StatefulWidget { final AddressAliasPayload payload; @@ -51,78 +49,61 @@ class _AddressAliasState extends State { @override Widget build(BuildContext context) { final theme = Theme.of(context); - bool isProcessing = false; return Scaffold( appBar: getBackAppBar(context, title: 'address_alias'.tr(), onBack: () => Navigator.of(context).pop()), - body: BlocConsumer( - listener: (context, state) async { - switch (state.createAccountState) { - case ActionState.done: - await _doneNaming(context); - isProcessing = false; - case ActionState.loading: - isProcessing = true; - case ActionState.error: - isProcessing = false; - default: - isProcessing = false; - break; - } - }, - builder: (context, state) => Padding( - padding: ResponsiveLayout.pageHorizontalEdgeInsetsWithSubmitButton, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 40), - Text( - _nameAddress, - style: theme.textTheme.ppMori400Black14, - ), - const SizedBox(height: 10), - AuTextField( - labelSemantics: 'enter_alias_full', - title: '', - placeholder: 'name_address'.tr(), - controller: _nameController, - focusNode: focusNode, - onChanged: (valueChanged) { - if (_nameController.text.trim().isEmpty != - isSavingAliasDisabled) { - saveAliasButtonChangedState(); - } - }), - const Spacer(), - Row( - children: [ - Expanded( - child: PrimaryButton( - text: 'continue'.tr(), - isProcessing: isProcessing, - onTap: isSavingAliasDisabled - ? null - : () { - context - .read() - .add(CreatePersonaAddressesEvent( - widget.payload.walletType, - name: _nameController.text.trim(), - )); - }, - ), + body: Padding( + padding: ResponsiveLayout.pageHorizontalEdgeInsetsWithSubmitButton, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 40), + Text( + _nameAddress, + style: theme.textTheme.ppMori400Black14, + ), + const SizedBox(height: 10), + AuTextField( + labelSemantics: 'enter_alias_full', + title: '', + placeholder: 'name_address'.tr(), + controller: _nameController, + focusNode: focusNode, + onChanged: (valueChanged) { + if (_nameController.text.trim().isEmpty != + isSavingAliasDisabled) { + saveAliasButtonChangedState(); + } + }), + const Spacer(), + Row( + children: [ + Expanded( + child: PrimaryAsyncButton( + text: 'continue'.tr(), + onTap: isSavingAliasDisabled + ? null + : () async { + await injector().insertNextAddress( + widget.payload.walletType, + name: _nameController.text.trim()); + if (!context.mounted) { + return; + } + _doneNaming(context); + }, ), - ], - ) - ], - ), + ), + ], + ) + ], ), ), ); } - Future _doneNaming(BuildContext context) async { + void _doneNaming(BuildContext context) { nameContinue(context); } } diff --git a/lib/screen/send_receive_postcard/receive_postcard_page.dart b/lib/screen/send_receive_postcard/receive_postcard_page.dart index 0f8d12af0..4125f5bc0 100644 --- a/lib/screen/send_receive_postcard/receive_postcard_page.dart +++ b/lib/screen/send_receive_postcard/receive_postcard_page.dart @@ -107,9 +107,8 @@ class _ReceivePostCardPageState extends State { final addresses = await accountService.getAddress(blockchain); String? address; if (addresses.isEmpty) { - final defaultPersona = await accountService.getOrCreateDefaultPersona(); final walletAddress = - await defaultPersona.insertNextAddress(WalletType.Tezos); + await accountService.insertNextAddress(WalletType.Tezos); address = walletAddress.first.address; } else if (addresses.length == 1) { address = addresses.first; @@ -141,7 +140,7 @@ class _ReceivePostCardPageState extends State { address: address, assetToken: asset, ); - if (!mounted) { + if (!context.mounted) { return null; } unawaited(Navigator.of(context).pushNamedAndRemoveUntil( diff --git a/lib/screen/settings/connection/accounts_view.dart b/lib/screen/settings/connection/accounts_view.dart index 489fb591a..623adb724 100644 --- a/lib/screen/settings/connection/accounts_view.dart +++ b/lib/screen/settings/connection/accounts_view.dart @@ -207,14 +207,14 @@ class _AccountsViewState extends State { account, isPrimary: isPrimary, onPersonaTap: () { - if (account.persona != null && account.walletAddress != null) { - unawaited(Navigator.of(context).pushNamed( - AppRouter.walletDetailsPage, - arguments: WalletDetailsPayload( - type: CryptoType.fromSource( - account.walletAddress!.cryptoType), - walletAddress: account.walletAddress!, - persona: account.persona!))); + if (account.walletAddress != null) { + unawaited( + Navigator.of(context).pushNamed(AppRouter.walletDetailsPage, + arguments: WalletDetailsPayload( + type: CryptoType.fromSource( + account.walletAddress!.cryptoType), + walletAddress: account.walletAddress!, + ))); } }, onConnectionTap: () { @@ -374,9 +374,9 @@ class _AccountsViewState extends State { Future _deleteAccount(BuildContext context, Account account) async { final walletAddress = account.walletAddress; - if (walletAddress != null && account.persona != null) { + if (walletAddress != null) { await injector() - .deleteAddressPersona(account.persona!, account.walletAddress!); + .deleteAddressPersona(account.walletAddress!); } final connection = account.connections?.first; diff --git a/lib/screen/settings/crypto/wallet_detail/wallet_detail_page.dart b/lib/screen/settings/crypto/wallet_detail/wallet_detail_page.dart index b9b53b438..06cb62538 100644 --- a/lib/screen/settings/crypto/wallet_detail/wallet_detail_page.dart +++ b/lib/screen/settings/crypto/wallet_detail/wallet_detail_page.dart @@ -9,7 +9,6 @@ import 'dart:async'; import 'dart:math'; import 'package:autonomy_flutter/common/injector.dart'; -import 'package:autonomy_flutter/database/entity/persona.dart'; import 'package:autonomy_flutter/database/entity/wallet_address.dart'; import 'package:autonomy_flutter/main.dart'; import 'package:autonomy_flutter/screen/account/recovery_phrase_page.dart'; @@ -33,6 +32,7 @@ import 'package:autonomy_flutter/util/string_ext.dart'; import 'package:autonomy_flutter/util/style.dart'; import 'package:autonomy_flutter/util/ui_helper.dart'; import 'package:autonomy_flutter/util/usdc_amount_formatter.dart'; +import 'package:autonomy_flutter/util/wallet_address_ext.dart'; import 'package:autonomy_flutter/view/au_buttons.dart'; import 'package:autonomy_flutter/view/back_appbar.dart'; import 'package:autonomy_flutter/view/crypto_view.dart'; @@ -139,18 +139,16 @@ class _WalletDetailPageState extends State with RouteAware { } void _callFetchConnections() { - final personUUID = widget.payload.persona.uuid; + final personUUID = widget.payload.walletAddress.uuid; final address = widget.payload.walletAddress.address; switch (widget.payload.type) { case CryptoType.ETH: context.read().add(GetETHConnectionsEvent( personUUID, widget.payload.walletAddress.index, address)); - break; case CryptoType.XTZ: context.read().add(GetXTZConnectionsEvent( personUUID, widget.payload.walletAddress.index, address)); - break; default: // do nothing break; @@ -335,10 +333,8 @@ class _WalletDetailPageState extends State with RouteAware { switch (widget.payload.type) { case CryptoType.ETH: scanItem = ScannerItem.WALLET_CONNECT; - break; case CryptoType.XTZ: scanItem = ScannerItem.BEACON_CONNECT; - break; default: break; } @@ -412,7 +408,6 @@ class _WalletDetailPageState extends State with RouteAware { onTap: () { final payload = WalletDetailsPayload( type: CryptoType.USDC, - persona: widget.payload.persona, walletAddress: walletAddress, ); unawaited(Navigator.of(context) @@ -583,7 +578,7 @@ class _WalletDetailPageState extends State with RouteAware { ), onTap: () { final payload = PersonaConnectionsPayload( - personaUUID: widget.payload.persona.uuid, + personaUUID: widget.payload.walletAddress.uuid, index: walletAddress.index, address: address, type: widget.payload.type, @@ -625,8 +620,8 @@ class _WalletDetailPageState extends State with RouteAware { onTap: () async { await Navigator.of(context).pushNamed( AppRouter.recoveryPhrasePage, - arguments: - RecoveryPhrasePayload(wallet: widget.payload.persona.wallet()), + arguments: RecoveryPhrasePayload( + wallet: widget.payload.walletAddress.wallet), ); }, ), @@ -662,7 +657,7 @@ class _WalletDetailPageState extends State with RouteAware { final payload = await Navigator.of(context).pushNamed( AppRouter.sendCryptoPage, arguments: SendData( - LibAukDart.getWallet(widget.payload.persona.uuid), + LibAukDart.getWallet(widget.payload.walletAddress.uuid), widget.payload.type, null, walletAddress.index)) as Map?; @@ -709,8 +704,8 @@ class _WalletDetailPageState extends State with RouteAware { onPressed: () { final account = Account( key: address, - persona: widget.payload.persona, name: walletAddress.name ?? widget.payload.type.source, + walletAddress: walletAddress, blockchain: widget.payload.type.source, accountNumber: address, createdAt: walletAddress.createdAt); @@ -789,12 +784,10 @@ class _WalletDetailPageState extends State with RouteAware { class WalletDetailsPayload { final CryptoType type; - final Persona persona; final WalletAddress walletAddress; WalletDetailsPayload({ required this.type, - required this.persona, required this.walletAddress, }); } diff --git a/lib/screen/settings/data_management/data_management_page.dart b/lib/screen/settings/data_management/data_management_page.dart index 57c12c11f..14b158671 100644 --- a/lib/screen/settings/data_management/data_management_page.dart +++ b/lib/screen/settings/data_management/data_management_page.dart @@ -111,7 +111,6 @@ class _DataManagementPageState extends State { injector(), injector(), injector(), - injector(), injector().database, injector(), injector(), diff --git a/lib/screen/settings/forget_exist/forget_exist_bloc.dart b/lib/screen/settings/forget_exist/forget_exist_bloc.dart index d3d200716..5e9212dd8 100644 --- a/lib/screen/settings/forget_exist/forget_exist_bloc.dart +++ b/lib/screen/settings/forget_exist/forget_exist_bloc.dart @@ -11,7 +11,6 @@ import 'package:autonomy_flutter/au_bloc.dart'; import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/database/app_database.dart'; import 'package:autonomy_flutter/database/cloud_database.dart'; -import 'package:autonomy_flutter/database/entity/persona.dart'; import 'package:autonomy_flutter/gateway/iap_api.dart'; import 'package:autonomy_flutter/screen/detail/preview/canvas_device_bloc.dart'; import 'package:autonomy_flutter/screen/settings/forget_exist/forget_exist_state.dart'; @@ -35,7 +34,6 @@ import 'package:package_info_plus/package_info_plus.dart'; class ForgetExistBloc extends AuBloc { final AuthService _authService; - final AccountService _accountService; final IAPApi _iapApi; final CloudDatabase _cloudDatabase; final AppDatabase _appDatabase; @@ -45,7 +43,6 @@ class ForgetExistBloc extends AuBloc { ForgetExistBloc( this._authService, - this._accountService, this._iapApi, this._cloudDatabase, this._appDatabase, @@ -72,12 +69,6 @@ class ForgetExistBloc extends AuBloc { log.info('Error when delete all profiles: $e'); } - final List personas = - await _cloudDatabase.personaDao.getPersonas(); - for (var persona in personas) { - await _accountService.deletePersona(persona); - } - await _cloudDatabase.removeAll(); await _appDatabase.removeAll(); await _nftCollectionDatabase.removeAll(); diff --git a/lib/screen/tezos_beacon/au_sign_message_page.dart b/lib/screen/tezos_beacon/au_sign_message_page.dart index 8d36d7d8d..04368135c 100644 --- a/lib/screen/tezos_beacon/au_sign_message_page.dart +++ b/lib/screen/tezos_beacon/au_sign_message_page.dart @@ -64,18 +64,20 @@ class _AUSignMessagePageState extends State { if (walletAddress != null) { currentWallet = LibAukDart.getWallet(walletAddress.uuid); } - break; case Wc2Chain.autonomy: - final personas = - await injector().personaDao.getPersonas(); - for (final persona in personas) { - final addressDID = await persona.wallet().getAccountDID(); + final addresses = + await injector().addressDao.getAllAddresses(); + if (addresses.isEmpty) { + break; + } + for (final walletAddress in addresses) { + final wallet = LibAukDart.getWallet(walletAddress.uuid); + final addressDID = await wallet.getAccountDID(); if (addressDID == address) { - currentWallet = persona.wallet(); + currentWallet = wallet; break; } } - break; } if (currentWallet == null) { diff --git a/lib/screen/wallet_connect/v2/wc2_permission_page.dart b/lib/screen/wallet_connect/v2/wc2_permission_page.dart index 9b9bf2956..fcc992e2f 100644 --- a/lib/screen/wallet_connect/v2/wc2_permission_page.dart +++ b/lib/screen/wallet_connect/v2/wc2_permission_page.dart @@ -11,7 +11,6 @@ import 'dart:convert'; import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/database/cloud_database.dart'; import 'package:autonomy_flutter/database/entity/connection.dart'; -import 'package:autonomy_flutter/database/entity/persona.dart'; import 'package:autonomy_flutter/main.dart'; import 'package:autonomy_flutter/model/wc2_request.dart'; import 'package:autonomy_flutter/screen/bloc/accounts/accounts_bloc.dart'; @@ -47,8 +46,6 @@ class Wc2RequestPage extends StatefulWidget { class _Wc2RequestPageState extends State with RouteAware, WidgetsBindingObserver { - Persona? selectedPersona; - List? personas; bool get _isAccountSelected => selectedAddresses.values.every((element) => element != null); diff --git a/lib/screen/wallet_connect/wc_connect_page.dart b/lib/screen/wallet_connect/wc_connect_page.dart index 06a686424..91e4fdb66 100644 --- a/lib/screen/wallet_connect/wc_connect_page.dart +++ b/lib/screen/wallet_connect/wc_connect_page.dart @@ -30,6 +30,7 @@ import 'package:autonomy_flutter/util/inapp_notifications.dart'; import 'package:autonomy_flutter/util/log.dart'; import 'package:autonomy_flutter/util/style.dart'; import 'package:autonomy_flutter/util/ui_helper.dart'; +import 'package:autonomy_flutter/util/wallet_address_ext.dart'; import 'package:autonomy_flutter/util/wallet_storage_ext.dart'; import 'package:autonomy_flutter/util/wallet_utils.dart'; import 'package:autonomy_flutter/view/back_appbar.dart'; @@ -648,18 +649,17 @@ class _WCConnectPageState extends State Future _createAccount(BuildContext context) async { unawaited(UIHelper.showLoadingScreen(context, text: 'connecting'.tr())); - final persona = - await injector().getOrCreateDefaultPersona(); - await persona.insertNextAddress(connectionRequest.isBeaconConnect - ? WalletType.Tezos - : WalletType.Ethereum); + final walletAddresses = await injector().insertNextAddress( + connectionRequest.isBeaconConnect + ? WalletType.Tezos + : WalletType.Ethereum); unawaited(configurationService.setDoneOnboarding(true)); unawaited(metricClient.mixPanelClient.initIfDefaultAccount()); if (!mounted) { return; } setState(() { - selectedPersona = WalletIndex(persona.wallet(), 0); + selectedPersona = WalletIndex(walletAddresses.first.wallet, 0); }); unawaited(_approveThenNotify(onBoarding: true)); } diff --git a/lib/service/account_service.dart b/lib/service/account_service.dart index 068ca9d8c..9b66dd7cc 100644 --- a/lib/service/account_service.dart +++ b/lib/service/account_service.dart @@ -11,9 +11,9 @@ import 'dart:io'; import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/database/cloud_database.dart'; import 'package:autonomy_flutter/database/entity/connection.dart'; -import 'package:autonomy_flutter/database/entity/persona.dart'; import 'package:autonomy_flutter/database/entity/wallet_address.dart'; import 'package:autonomy_flutter/model/p2p_peer.dart'; +import 'package:autonomy_flutter/model/shared_postcard.dart'; import 'package:autonomy_flutter/model/wc2_request.dart'; import 'package:autonomy_flutter/screen/bloc/scan_wallet/scan_wallet_state.dart'; import 'package:autonomy_flutter/service/address_service.dart'; @@ -31,6 +31,7 @@ import 'package:autonomy_flutter/util/migration/migration_util.dart'; import 'package:autonomy_flutter/util/primary_address_channel.dart' as primary_address_channel; import 'package:autonomy_flutter/util/string_ext.dart'; +import 'package:autonomy_flutter/util/wallet_address_ext.dart'; import 'package:autonomy_flutter/util/wallet_storage_ext.dart'; import 'package:autonomy_flutter/util/wallet_utils.dart'; import 'package:autonomy_flutter/util/wc2_ext.dart'; @@ -39,6 +40,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:libauk_dart/libauk_dart.dart'; import 'package:nft_collection/models/models.dart'; import 'package:nft_collection/services/address_service.dart' as nft; +import 'package:nft_collection/services/address_service.dart' as nft_address; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:synchronized/synchronized.dart'; import 'package:uuid/uuid.dart'; @@ -51,7 +53,7 @@ abstract class AccountService { Future getDefaultAccount(); - Future getOrCreateDefaultPersona(); + Future getOrCreatePrimaryWallet(); Future getAccountByAddress({ required String chain, @@ -68,12 +70,10 @@ abstract class AccountService { Future androidRestoreKeys(); - Future getPersona({required String uuid}); - - Future createPersona( + Future> createNewWallet( {String name = '', String passphrase = '', bool isDefault = false}); - Future importPersona(String words, String passphrase, + Future importPersona(String words, String passphrase, {WalletType walletType = WalletType.Autonomy}); Future nameLinkedAccount(Connection connection, String name); @@ -81,8 +81,6 @@ abstract class AccountService { Future linkManuallyAddress(String address, CryptoType cryptoType, {String? name}); - Future deletePersona(Persona persona); - Future deleteLinkedAccount(Connection connection); Future linkIndexerTokenID(String indexerTokenID); @@ -102,11 +100,9 @@ abstract class AccountService { Future> getShowedAddresses(); - Future addAddressPersona( - Persona newPersona, List addresses); + Future addAddressPersona(String uuid, List addresses); - Future deleteAddressPersona( - Persona persona, WalletAddress walletAddress); + Future deleteAddressPersona(WalletAddress walletAddress); Future getAddressPersona(String address); @@ -115,6 +111,18 @@ abstract class AccountService { Future restoreIfNeeded(); Future> getAllViewOnlyAddresses(); + + Future> insertNextAddress(WalletType walletType, + {String? name}); + + Future> insertNextAddressFromUuid( + String uuid, WalletType walletType, + {String? name}); + + Future> insertAddressAtIndexAndUuid(String uuid, + {required WalletType walletType, required int index, String? name}); + + Future restoreUUIDs(List personaUUIDs); } class AccountServiceImpl extends AccountService { @@ -137,31 +145,30 @@ class AccountServiceImpl extends AccountService { ); @override - Future createPersona( + Future> createNewWallet( {String name = '', String passphrase = '', bool isDefault = false}) async { final uuid = const Uuid().v4(); final walletStorage = LibAukDart.getWallet(uuid); await walletStorage.createKey(passphrase, name); - final persona = Persona.newPersona( - uuid: uuid, defaultAccount: isDefault ? 1 : null, name: name); - await _cloudDB.personaDao.insertPersona(persona); await androidBackupKeys(); - log.fine('[AccountService] Created persona ${persona.uuid}}'); + log.fine('[AccountService] Created persona $uuid}'); if (isDefault) { await _addressService.registerPrimaryAddress( info: primary_address_channel.AddressInfo( - uuid: persona.uuid, + uuid: uuid, chain: 'ethereum', index: 0, )); } - return persona; + final wallets = + await insertNextAddressFromUuid(uuid, WalletType.Autonomy, name: name); + return wallets; } @override - Future importPersona(String words, String passphrase, + Future importPersona(String words, String passphrase, {WalletType walletType = WalletType.Autonomy}) async { late String firstEthAddress; try { @@ -171,11 +178,12 @@ class AccountServiceImpl extends AccountService { rethrow; } - final personas = await _cloudDB.personaDao.getPersonas(); - for (final persona in personas) { - final ethAddress = await persona.wallet().getETHAddress(); + final addresses = await _cloudDB.addressDao.getAllAddresses(); + addresses.unique((element) => element.uuid); + for (final address in addresses) { + final ethAddress = await address.wallet.getETHAddress(); if (ethAddress == firstEthAddress) { - return persona; + return address.wallet; } } @@ -184,21 +192,9 @@ class AccountServiceImpl extends AccountService { await walletStorage.importKey( words, passphrase, '', DateTime.now().microsecondsSinceEpoch); - final persona = Persona.newPersona(uuid: uuid); - await _cloudDB.personaDao.insertPersona(persona); await androidBackupKeys(); - log.fine('[AccountService] imported persona ${persona.uuid}'); - return persona; - } - - @override - Future getPersona({required String uuid}) async { - final persona = await _cloudDB.personaDao.findById(uuid); - if (persona == null) { - unawaited(Sentry.captureMessage('Persona not found. UUID: $uuid')); - throw AccountException(message: 'Persona not found. UUID: $uuid'); - } - return persona; + log.fine('[AccountService] imported persona $uuid'); + return walletStorage; } @override @@ -219,9 +215,10 @@ class AccountServiceImpl extends AccountService { WalletStorage(walletAddress.uuid), walletAddress.index); } case Wc2Chain.autonomy: - var personas = await _cloudDB.personaDao.getPersonas(); - for (Persona p in personas) { - final wallet = p.wallet(); + var addresses = await _cloudDB.addressDao.getAllAddresses(); + addresses.unique((element) => element.uuid); + for (WalletAddress a in addresses) { + final wallet = a.wallet; if (await wallet.getAccountDID() == address) { return WalletIndex(wallet, -1); } @@ -233,60 +230,59 @@ class AccountServiceImpl extends AccountService { } Future _getDefaultAccount() async { - final Persona defaultPersona = await getDefaultPersona(); - return LibAukDart.getWallet(defaultPersona.uuid); + final primaryWallet = await getPrimaryWallet(); + return LibAukDart.getWallet(primaryWallet.uuid); } - Future getDefaultPersona() async { - var personas = await _cloudDB.personaDao.getDefaultPersonas(); + Future getPrimaryWallet() async { + final primaryAddress = + await injector().getPrimaryAddressInfo(); + if (primaryAddress == null) { + unawaited(Sentry.captureMessage( + '[PrimaryAddressInfo] PrimaryAddressInfo found')); + throw AccountException(message: 'PrimaryAddressInfo found'); + } + var addresses = + await _cloudDB.addressDao.getAddressesByPersona(primaryAddress.uuid); - if (personas.isEmpty) { + if (addresses.isEmpty) { await MigrationUtil(injector()).migrationFromKeychain(); await androidRestoreKeys(); await Future.delayed(const Duration(seconds: 1)); - personas = await _cloudDB.personaDao.getDefaultPersonas(); + addresses = + await _cloudDB.addressDao.getAddressesByPersona(primaryAddress.uuid); } - Persona defaultPersona; - if (personas.isEmpty) { - personas = await _cloudDB.personaDao.getPersonas(); - if (personas.isNotEmpty) { - defaultPersona = personas.first..defaultAccount = 1; - await _cloudDB.personaDao.updatePersona(defaultPersona); - } else { - unawaited(Sentry.captureMessage( - '[getDefaultPersona] No default persona found')); - throw AccountException(message: 'No default persona found'); - } - } else { - defaultPersona = personas.first; + final primaryWallet = addresses + .firstWhereOrNull((element) => element.index == primaryAddress.index); + if (primaryWallet == null) { + unawaited( + Sentry.captureMessage('[PrimaryAddressInfo] No PrimaryWallet found')); + throw AccountException(message: 'No PrimaryWallet found'); } - return defaultPersona; + return primaryWallet; } @override - Future getOrCreateDefaultPersona() async { + Future getOrCreatePrimaryWallet() async { try { - final defaultPersona = await getDefaultPersona(); - return defaultPersona; + final primaryWallet = await getPrimaryWallet(); + return primaryWallet; } catch (exception) { if (exception is AccountException) { - final persona = await createPersona(isDefault: true); - return persona; + final walletAddresses = await createNewWallet(isDefault: true); + return walletAddresses.firstWhere( + (element) => element.cryptoType == CryptoType.ETH.source); } else { rethrow; } } } - @override - Future deletePersona(Persona persona) async { - log.fine('[AccountService] deletePersona start - ${persona.uuid}'); - await _cloudDB.personaDao.deletePersona(persona); - - await androidBackupKeys(); - await LibAukDart.getWallet(persona.uuid).removeKeys(); + Future deleteWalletAddress(WalletAddress walletAddress) async { + await _cloudDB.addressDao.deleteAddress(walletAddress); + await _nftCollectionAddressService.deleteAddresses([walletAddress.address]); final connections = await _cloudDB.connectionDao.getConnections(); Set bcPeers = {}; @@ -296,7 +292,10 @@ class AccountServiceImpl extends AccountService { for (var connection in connections) { switch (connection.connectionType) { case 'beaconP2PPeer': - if (persona.uuid == connection.beaconConnectConnection?.personaUuid) { + if (walletAddress.uuid == + connection.beaconConnectConnection?.personaUuid && + walletAddress.index == + connection.beaconConnectConnection?.index) { await _cloudDB.connectionDao.deleteConnection(connection); final bcPeer = connection.beaconConnectConnection?.peer; if (bcPeer != null) { @@ -315,8 +314,6 @@ class AccountServiceImpl extends AccountService { } catch (exception) { unawaited(Sentry.captureException(exception)); } - - log.fine('[AccountService] deletePersona finished - ${persona.uuid}'); } @override @@ -367,17 +364,7 @@ class AccountServiceImpl extends AccountService { // the default account is not exist, // we should create new account, // derive ethereum and tezos address at index 0 - await getOrCreateDefaultPersona(); - - // now default account is exist, - // we should derive ethereum and tezos address at index 0 - await _addressService.deriveAddressesFromAllPersona(); - - // pick primary address - final addressInfo = await _addressService.pickAddressAsPrimary(); - - // register primary address - await _addressService.registerPrimaryAddress(info: addressInfo); + await getOrCreatePrimaryWallet(); } return connection; } @@ -421,8 +408,8 @@ class AccountServiceImpl extends AccountService { @override Future androidBackupKeys() async { if (Platform.isAndroid) { - final accounts = await _cloudDB.personaDao.getPersonas(); - final uuids = accounts.map((e) => e.uuid).toList(); + final addresses = await _cloudDB.addressDao.getAllAddresses(); + final uuids = addresses.map((e) => e.uuid).toSet().toList(); await _backupChannel.backupKeys(uuids); } @@ -436,56 +423,54 @@ class AccountServiceImpl extends AccountService { } @override - Future androidRestoreKeys() async { - if (Platform.isAndroid) { - final accounts = await _backupChannel.restoreKeys(); + Future restoreUUIDs(List personaUUIDs) async { + final List brokenUUIDs = []; + for (var uuid in personaUUIDs) { + final wallet = WalletStorage(uuid); + if (!(await wallet.isWalletCreated())) { + brokenUUIDs.add(uuid); + } + } + personaUUIDs.removeWhere((element) => brokenUUIDs.contains(element)); - final personas = await _cloudDB.personaDao.getPersonas(); + final addresses = await _cloudDB.addressDao.getAllAddresses(); + final dbUuids = addresses.map((e) => e.uuid).toSet().toList(); + if (dbUuids.length == personaUUIDs.length && + dbUuids + .every((element) => personaUUIDs.contains(element.toLowerCase()))) { + //Database is up-to-date, skip migrating + return; + } - if (personas.length == accounts.length && - personas.every((element) => - accounts.map((e) => e.uuid).contains(element.uuid))) { - //Database is up-to-date, skip migrating - return; - } + // remove uuids not in keychain + final uuidsToRemove = dbUuids + .where((element) => !personaUUIDs.contains(element.toLowerCase())) + .toList(); - final primaryAddress = await _addressService.getPrimaryAddressInfo(); - //Import persona to database if needed - for (var account in accounts) { - final existingAccount = - await _cloudDB.personaDao.findById(account.uuid); - if (existingAccount == null) { - final defaultAccount = - primaryAddress?.uuid == account.uuid ? 1 : null; - - final persona = Persona.newPersona( - uuid: account.uuid, - name: account.name, - createdAt: DateTime.now(), - defaultAccount: defaultAccount, - ); - await _cloudDB.personaDao.insertPersona(persona); - } + for (var uuid in uuidsToRemove) { + await _cloudDB.addressDao.deleteAddressesByPersona(uuid); + } + log.info('[_migration android/ios] personaUUIDs : $personaUUIDs'); + for (var personaUUID in personaUUIDs) { + //Cleanup duplicated persona + final oldAddresses = + await _cloudDB.addressDao.getAddressesByPersona(personaUUID); + if (oldAddresses.isEmpty) { + await insertNextAddressFromUuid(personaUUID, WalletType.Autonomy); } + } + } - //Cleanup broken personas - final currentPersonas = await _cloudDB.personaDao.getPersonas(); - var shouldBackup = false; - for (var persona in currentPersonas) { - if (!(await persona.wallet().isWalletCreated())) { - await _cloudDB.personaDao.deletePersona(persona); - final addresses = - await _cloudDB.addressDao.getAddressesByPersona(persona.uuid); - await _nftCollectionAddressService - .deleteAddresses(addresses.map((e) => e.address).toList()); - await _cloudDB.addressDao.deleteAddressesByPersona(persona.uuid); - shouldBackup = true; - } - } + @override + Future androidRestoreKeys() async { + if (Platform.isAndroid) { + final accounts = await _backupChannel.restoreKeys(); - if (shouldBackup || (personas.isNotEmpty && accounts.isEmpty)) { - await androidBackupKeys(); - } + final uuids = accounts.map((e) => e.uuid.toLowerCase()).toSet().toList(); + + await restoreUUIDs(uuids); + + await androidBackupKeys(); } } @@ -545,24 +530,11 @@ class AccountServiceImpl extends AccountService { @override Future> getAddress(String blockchain, {bool withViewOnly = false}) async { - final addresses = []; // Full accounts - final personas = await _cloudDB.personaDao.getPersonas(); - for (var persona in personas) { - final personaWallet = persona.wallet(); - if (!await personaWallet.isWalletCreated()) { - continue; - } - switch (blockchain.toLowerCase()) { - case 'tezos': - addresses.addAll(await persona.getTezosAddresses()); - case 'ethereum': - final address = await personaWallet.getETHEip55Address(); - if (address.isNotEmpty) { - addresses.addAll(await persona.getEthAddresses()); - } - } - } + final walletAddresses = await _cloudDB.addressDao.getAddressesByType( + CryptoType.fromSource(blockchain.toLowerCase()).source); + + final addresses = walletAddresses.map((e) => e.address).toList(); if (withViewOnly) { final connections = @@ -613,7 +585,7 @@ class AccountServiceImpl extends AccountService { @override Future addAddressPersona( - Persona newPersona, List addresses) async { + String uuid, List addresses) async { bool result = false; final replacedConnections = await removeDoubleViewOnly(addresses.map((e) => e.address).toList()); @@ -625,7 +597,7 @@ class AccountServiceImpl extends AccountService { final walletAddresses = addresses .map((e) => WalletAddress( address: e.address, - uuid: newPersona.uuid, + uuid: uuid, index: e.index, cryptoType: e.getCryptoType().source, createdAt: timestamp, @@ -679,8 +651,7 @@ class AccountServiceImpl extends AccountService { } @override - Future deleteAddressPersona( - Persona persona, WalletAddress walletAddress) async { + Future deleteAddressPersona(WalletAddress walletAddress) async { await _cloudDB.addressDao.deleteAddress(walletAddress); await _nftCollectionAddressService.deleteAddresses([walletAddress.address]); switch (CryptoType.fromSource(walletAddress.cryptoType)) { @@ -698,7 +669,8 @@ class AccountServiceImpl extends AccountService { .getConnectionsByType(ConnectionType.beaconP2PPeer.rawValue); for (var connection in connections) { - if (connection.beaconConnectConnection?.personaUuid == persona.uuid && + if (connection.beaconConnectConnection?.personaUuid == + walletAddress.uuid && connection.beaconConnectConnection?.index == walletAddress.index) { await _cloudDB.connectionDao.deleteConnection(connection); @@ -718,14 +690,14 @@ class AccountServiceImpl extends AccountService { @override Future restoreIfNeeded() async { final iapService = injector(); - final migrationUtil = MigrationUtil(_cloudDB); + final migrationUtil = MigrationUtil(this); await androidRestoreKeys(); await migrationUtil.migrationFromKeychain(); - final personas = await _cloudDB.personaDao.getPersonas(); + final addresses = await _cloudDB.addressDao.getAllAddresses(); - final hasPersona = personas.isNotEmpty; - if (!hasPersona) { - await _configurationService.setDoneOnboarding(hasPersona); + final hasAddresses = addresses.isNotEmpty; + if (!hasAddresses) { + await _configurationService.setDoneOnboarding(hasAddresses); } if (_configurationService.isDoneOnboarding()) { // dont need to force update, because @@ -733,17 +705,12 @@ class AccountServiceImpl extends AccountService { return; } // for user who did not onboarded before - if (hasPersona) { + if (hasAddresses) { unawaited(_configurationService.setOldUser()); final backupVersion = await _backupService.getBackupVersion(); if (backupVersion.isNotEmpty) { // if user has backup, restore from cloud unawaited(_backupService.restoreCloudDatabase()); - for (var persona in personas) { - if (persona.name != '') { - await persona.wallet().updateName(persona.name); - } - } await _cloudDB.connectionDao.getUpdatedLinkedAccounts(); unawaited(injector() .mixPanelClient @@ -755,13 +722,7 @@ class AccountServiceImpl extends AccountService { // case 2: user has backup but no addresses final addresses = await _addressService.getAllEthereumAddress(); if (addresses.isEmpty) { - // if user has no backup, derive addresses from keychain - await _addressService.deriveAddressesFromAllPersona(); - - // if primary exist in keychain, - // derive primary address for case primary address - // is not exist in cloud database - await _addressService.derivePrimaryAddress(); + await getOrCreatePrimaryWallet(); } // now has addresses, check if primary address is exist @@ -775,9 +736,7 @@ class AccountServiceImpl extends AccountService { } } else { // for new user, create default persona - final persona = await createPersona(isDefault: true); - await persona.insertNextAddress(WalletType.Tezos); - await persona.insertNextAddress(WalletType.Ethereum); + await createNewWallet(isDefault: true); await _configurationService.setDoneOnboarding(true); unawaited(injector() .mixPanelClient @@ -813,29 +772,127 @@ class AccountServiceImpl extends AccountService { } @override - Future> getWalletsAddress(CryptoType cryptoType) async { - final addresses = await injector() - .addressDao - .getAddressesByType(cryptoType.source); - final personas = await injector().personaDao.getPersonas(); - final listUuid = personas.map((e) => e.uuid).toList(); - addresses.removeWhere((e) => !listUuid.contains(e.uuid)); - return addresses; - } + Future> getWalletsAddress(CryptoType cryptoType) async => + await injector() + .addressDao + .getAddressesByType(cryptoType.source); @override Future> deriveAddressFromFirstPersona( - WalletType walletType) async { - final personas = await injector().personaDao.getPersonas(); - final derivedAddresses = await personas.first.insertNextAddress(walletType); - return derivedAddresses; + WalletType walletType) async => + await insertNextAddress(walletType); + + @override + Future> insertNextAddress(WalletType walletType, + {String? name}) async { + final primaryAddress = + await injector().getPrimaryAddressInfo(); + if (primaryAddress == null) { + throw AccountException(message: 'Primary address not found'); + } + return await insertNextAddressFromUuid(primaryAddress.uuid, walletType, + name: name); } -} -class AccountImportedException implements Exception { - final Persona persona; + @override + Future> insertNextAddressFromUuid( + String uuid, WalletType walletType, + {String? name}) async { + final List addresses = []; + final walletAddresses = await _cloudDB.addressDao.findByWalletID(uuid); + final wallet = LibAukDart.getWallet(uuid); + final ethIndexes = walletAddresses + .where((element) => element.cryptoType == CryptoType.ETH.source) + .map((e) => e.index) + .toList(); + final ethIndex = _getNextIndex(ethIndexes); + final tezIndexes = walletAddresses + .where((element) => element.cryptoType == CryptoType.XTZ.source) + .map((e) => e.index) + .toList(); + final tezIndex = _getNextIndex(tezIndexes); + final ethAddress = WalletAddress( + address: await wallet.getETHEip55Address(index: ethIndex), + uuid: uuid, + index: ethIndex, + cryptoType: CryptoType.ETH.source, + createdAt: DateTime.now(), + name: name ?? CryptoType.ETH.source); + final tezAddress = WalletAddress( + address: await wallet.getTezosAddress(index: tezIndex), + uuid: uuid, + index: tezIndex, + cryptoType: CryptoType.XTZ.source, + createdAt: DateTime.now(), + name: name ?? CryptoType.XTZ.source); + switch (walletType) { + case WalletType.Ethereum: + addresses.add(ethAddress); + case WalletType.Tezos: + addresses.add(tezAddress); + default: + addresses.addAll([ethAddress, tezAddress]); + } + await injector() + .removeDoubleViewOnly(addresses.map((e) => e.address).toList()); + await injector().addressDao.insertAddresses(addresses); + await injector() + .addAddresses(addresses.map((e) => e.address).toList()); + return addresses; + } + + @override + Future> insertAddressAtIndexAndUuid(String uuid, + {required WalletType walletType, + required int index, + String? name}) async { + List walletAddresses = []; + switch (walletType) { + case WalletType.Ethereum: + walletAddresses = [ + await _generateETHAddressByIndex(uuid, index, name: name) + ]; + case WalletType.Tezos: + walletAddresses = [ + await _generateTezosAddressByIndex(uuid, index, name: name), + ]; + case WalletType.Autonomy: + walletAddresses = [ + await _generateETHAddressByIndex(uuid, index, name: name), + await _generateTezosAddressByIndex(uuid, index, name: name) + ]; + } + await injector() + .removeDoubleViewOnly(walletAddresses.map((e) => e.address).toList()); + await injector().addressDao.insertAddresses(walletAddresses); + await injector() + .addAddresses(walletAddresses.map((e) => e.address).toList()); + return walletAddresses; + } - AccountImportedException({required this.persona}); + Future _generateETHAddressByIndex(String uuid, int index, + {String? name}) async => + WalletAddress( + address: + await LibAukDart.getWallet(uuid).getETHEip55Address(index: index), + uuid: uuid, + index: index, + cryptoType: CryptoType.ETH.source, + createdAt: DateTime.now(), + name: name ?? CryptoType.ETH.source); + + Future _generateTezosAddressByIndex(String uuid, int index, + {String? name}) async => + WalletAddress( + address: + await LibAukDart.getWallet(uuid).getTezosAddress(index: index), + uuid: uuid, + index: index, + cryptoType: CryptoType.XTZ.source, + createdAt: DateTime.now(), + name: name ?? CryptoType.XTZ.source); + + int _getNextIndex(List indexes) => (indexes.maxOrNull ?? -1) + 1; } class AccountException implements Exception { diff --git a/lib/service/address_service.dart b/lib/service/address_service.dart index ba89480e8..5a66992e8 100644 --- a/lib/service/address_service.dart +++ b/lib/service/address_service.dart @@ -10,6 +10,7 @@ import 'dart:convert'; import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/database/cloud_database.dart'; import 'package:autonomy_flutter/database/entity/wallet_address.dart'; +import 'package:autonomy_flutter/service/account_service.dart'; import 'package:autonomy_flutter/service/auth_service.dart'; import 'package:autonomy_flutter/service/metric_client_service.dart'; import 'package:autonomy_flutter/util/constants.dart'; @@ -26,8 +27,11 @@ class AddressService { AddressService(this._primaryAddressChannel, this._cloudDB); + AddressInfo? _primaryAddressInfo; + Future getPrimaryAddressInfo() async { - final addressInfo = await _primaryAddressChannel.getPrimaryAddress(); + final addressInfo = + _primaryAddressInfo ?? await _primaryAddressChannel.getPrimaryAddress(); log.info('[AddressService] Primary address info: ${addressInfo?.toJson()}'); return addressInfo; } @@ -39,34 +43,16 @@ class AddressService { } final allEthAddresses = await getAllEthereumAddress(); if (allEthAddresses.isEmpty) { - await deriveAddressesFromAllPersona(); + await injector().insertAddressAtIndexAndUuid( + currentPrimaryAddress.uuid, + index: 0, + walletType: WalletType.Ethereum); } final addressInfo = await pickAddressAsPrimary(); await registerPrimaryAddress(info: addressInfo); return addressInfo; } - Future deriveAddressesFromAllPersona() async { - final personas = await _cloudDB.personaDao.getPersonas(); - for (final persona in personas) { - await Future.wait([ - persona.insertAddressAtIndex(walletType: WalletType.Ethereum, index: 0), - persona.insertAddressAtIndex(walletType: WalletType.Tezos, index: 0), - ]); - } - } - - Future derivePrimaryAddress() async { - final primaryAddressInfo = await getPrimaryAddressInfo(); - if (primaryAddressInfo == null) { - return; - } - final persona = await _cloudDB.personaDao.findById(primaryAddressInfo.uuid); - await persona?.insertAddressAtIndex( - walletType: primaryAddressInfo.walletType, - index: primaryAddressInfo.index); - } - Future setPrimaryAddressInfo({required AddressInfo info}) async { await _primaryAddressChannel.setPrimaryAddress(info); log.info('[AddressService] Primary address info set: ${info.toJson()}'); @@ -174,9 +160,6 @@ class AddressService { Future> getAllAddress() async { final addresses = await _cloudDB.addressDao.getAllAddresses(); - final persona = await _cloudDB.personaDao.getPersonas(); - addresses - .removeWhere((address) => !persona.any((p) => p.uuid == address.uuid)); return addresses; } @@ -184,15 +167,7 @@ class AddressService { final addresses = await _cloudDB.addressDao.getAddressesByType(CryptoType.ETH.source); addresses.sort((a, b) => a.createdAt.compareTo(b.createdAt)); - final persona = await _cloudDB.personaDao.getPersonas(); - persona.sort((a, b) => a.createdAt.compareTo(b.createdAt)); - final sortedAddresses = []; - for (final p in persona) { - final pAddresses = addresses.where((a) => a.uuid == p.uuid).toList() - ..sort((a, b) => a.index.compareTo(b.index)); - sortedAddresses.addAll(pAddresses); - } - return sortedAddresses; + return addresses; } Future pickAddressAsPrimary() async { diff --git a/lib/util/account_ext.dart b/lib/util/account_ext.dart index e80a03fbd..dd1bdc7b9 100644 --- a/lib/util/account_ext.dart +++ b/lib/util/account_ext.dart @@ -1,22 +1,24 @@ +import 'dart:async'; + import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/screen/bloc/accounts/accounts_bloc.dart'; import 'package:autonomy_flutter/service/account_service.dart'; import 'package:autonomy_flutter/util/constants.dart'; import 'package:autonomy_flutter/util/wallet_storage_ext.dart'; import 'package:collection/collection.dart'; +import 'package:libauk_dart/libauk_dart.dart'; extension AccountExt on Account { Future getAddress(String blockchain) async { - final wallet = persona?.wallet(); String? address; if (wallet != null) { - address = blockchain.toLowerCase() == "tezos" - ? await wallet.getTezosAddress() - : await wallet.getETHEip55Address(); + address = blockchain.toLowerCase() == 'tezos' + ? await wallet!.getTezosAddress() + : await wallet!.getETHEip55Address(); } else if (connections?.isNotEmpty == true) { - final connectionType = blockchain.toLowerCase() == "tezos" - ? "walletBeacon" - : "walletConnect"; + final connectionType = blockchain.toLowerCase() == 'tezos' + ? 'walletBeacon' + : 'walletConnect'; address = connections ?.firstWhereOrNull((e) => e.connectionType == connectionType) ?.accountNumber; @@ -24,22 +26,22 @@ extension AccountExt on Account { return address; } - bool get isHidden { - return walletAddress != null - ? walletAddress!.isHidden - : injector().isLinkedAccountHiddenInGallery(key); - } + bool get isHidden => walletAddress != null + ? walletAddress!.isHidden + : injector().isLinkedAccountHiddenInGallery(key); Future setViewAccount(bool value) async { if (walletAddress != null) { await injector() .setHideAddressInGallery([walletAddress!.address], value); } else { - injector().setHideLinkedAccountInGallery(key, value); + unawaited( + injector().setHideLinkedAccountInGallery(key, value)); } } - CryptoType get cryptoType { - return CryptoType.fromSource(blockchain ?? ""); - } + CryptoType get cryptoType => CryptoType.fromSource(blockchain ?? ''); + + WalletStorage? get wallet => + walletAddress != null ? LibAukDart.getWallet(walletAddress!.uuid) : null; } diff --git a/lib/util/migration/migration_util.dart b/lib/util/migration/migration_util.dart index 7617c3a37..fede937c2 100644 --- a/lib/util/migration/migration_util.dart +++ b/lib/util/migration/migration_util.dart @@ -8,79 +8,26 @@ import 'dart:async'; import 'dart:io'; -import 'package:autonomy_flutter/common/injector.dart'; -import 'package:autonomy_flutter/database/cloud_database.dart'; -import 'package:autonomy_flutter/database/entity/persona.dart'; -import 'package:autonomy_flutter/service/address_service.dart'; +import 'package:autonomy_flutter/service/account_service.dart'; import 'package:autonomy_flutter/util/device.dart'; -import 'package:autonomy_flutter/util/log.dart'; import 'package:flutter/services.dart'; -import 'package:nft_collection/services/address_service.dart' as ads; class MigrationUtil { static const MethodChannel _channel = MethodChannel('migration_util'); - final CloudDatabase _cloudDB; - final ads.AddressService _collectionAddressService = - injector(); - final AddressService _addressService = injector(); + final AccountService _accountService; final int requiredAndroidMigrationVersion = 95; - MigrationUtil(this._cloudDB); + MigrationUtil(this._accountService); Future migrationFromKeychain() async { if (!Platform.isIOS) { return; } - final List personaUUIDs = + final keychainUUIDs = await _channel.invokeMethod('getWalletUUIDsFromKeychain', {}); - - final personas = await _cloudDB.personaDao.getPersonas(); - if (personas.length == personaUUIDs.length && - personas.every( - (element) => personaUUIDs.contains(element.uuid.toUpperCase()))) { - //Database is up-to-date, skip migrating - return; - } - - final primaryAddressInfo = await _addressService.getPrimaryAddressInfo(); - log.info( - '[_migrationFromKeychain] personaUUIDs from Keychain: $personaUUIDs'); - for (var personaUUID in personaUUIDs) { - //Cleanup duplicated persona - final oldPersona = await _cloudDB.personaDao.findById(personaUUID); - if (oldPersona != null) { - await _cloudDB.personaDao.deletePersona(oldPersona); - } - - final uuid = personaUUID.toLowerCase(); - final existingPersona = await _cloudDB.personaDao.findById(uuid); - if (existingPersona == null) { - final wallet = Persona.newPersona(uuid: uuid).wallet(); - final name = await wallet.getName(); - final defaultAccount = primaryAddressInfo?.uuid == uuid ? 1 : 0; - - final persona = Persona.newPersona( - uuid: uuid, - name: name, - createdAt: DateTime.now(), - defaultAccount: defaultAccount); - - await _cloudDB.personaDao.insertPersona(persona); - } - } - - //Cleanup broken personas - final currentPersonas = await _cloudDB.personaDao.getPersonas(); - for (var persona in currentPersonas) { - if (!(await persona.wallet().isWalletCreated())) { - final addresses = - await _cloudDB.addressDao.getAddressesByPersona(persona.uuid); - await _collectionAddressService - .deleteAddresses(addresses.map((e) => e.address).toList()); - await _cloudDB.addressDao.deleteAddressesByPersona(persona.uuid); - await _cloudDB.personaDao.deletePersona(persona); - } - } + final List personaUUIDs = + keychainUUIDs.map((e) => e.toString().toLowerCase()).tolist(); + await _accountService.restoreUUIDs(personaUUIDs); } static Future getBackupDeviceID() async { diff --git a/lib/util/wallet_address_ext.dart b/lib/util/wallet_address_ext.dart index 802508ecb..313542cba 100644 --- a/lib/util/wallet_address_ext.dart +++ b/lib/util/wallet_address_ext.dart @@ -1,5 +1,6 @@ import 'package:autonomy_flutter/database/entity/wallet_address.dart'; import 'package:autonomy_flutter/util/primary_address_channel.dart'; +import 'package:libauk_dart/libauk_dart.dart'; extension WalletAddressExt on WalletAddress { bool isMatchAddressInfo(AddressInfo? addressInfo) { @@ -10,4 +11,6 @@ extension WalletAddressExt on WalletAddress { addressInfo.index == index && addressInfo.chain == cryptoType.toLowerCase(); } + + WalletStorage get wallet => WalletStorage(uuid); } diff --git a/lib/view/account_view.dart b/lib/view/account_view.dart index 980a6c8f2..5c7035fdd 100644 --- a/lib/view/account_view.dart +++ b/lib/view/account_view.dart @@ -27,15 +27,13 @@ Widget accountItem(BuildContext context, Account account, {bool isPrimary = false, Function()? onPersonaTap, Function()? onConnectionTap}) { - if ((account.persona == null || account.walletAddress == null) && - account.connections?.first == null) { + if ((account.walletAddress == null) && account.connections?.first == null) { return const SizedBox(); } final theme = Theme.of(context); // ignore: discarded_futures final balance = getAddressBalance(account.key, account.cryptoType); - final isViewAccount = - account.persona == null || account.walletAddress == null; + final isViewAccount = account.walletAddress == null; return GestureDetector( onTap: isViewAccount ? onConnectionTap : onPersonaTap, child: Container( diff --git a/lib/view/select_account_view.dart b/lib/view/select_account_view.dart index 0c206df6f..0a39c5711 100644 --- a/lib/view/select_account_view.dart +++ b/lib/view/select_account_view.dart @@ -1,7 +1,6 @@ -import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/model/connection_request_args.dart'; import 'package:autonomy_flutter/screen/bloc/accounts/accounts_bloc.dart'; -import 'package:autonomy_flutter/service/account_service.dart'; +import 'package:autonomy_flutter/util/account_ext.dart'; import 'package:autonomy_flutter/util/wallet_storage_ext.dart'; import 'package:autonomy_flutter/view/list_address_account.dart'; import 'package:autonomy_flutter/view/responsive.dart'; @@ -14,6 +13,7 @@ class SelectAccount extends StatefulWidget { final ConnectionRequest connectionRequest; final Function(WalletIndex?)? onSelectPersona; final Function(List)? onCategorizedAccountsChanged; + const SelectAccount( {required this.connectionRequest, super.key, @@ -27,7 +27,7 @@ class SelectAccount extends StatefulWidget { class _SelectAccountState extends State with RouteAware { final padding = ResponsiveLayout.pageEdgeInsets.copyWith(top: 0, bottom: 0); late ConnectionRequest connectionRequest; - WalletIndex? selectedPersona; + WalletIndex? selectedWallet; List? categorizedAccounts; @override @@ -56,11 +56,11 @@ class _SelectAccountState extends State with RouteAware { listener: (context, state) async { var stateCategorizedAccounts = state.accounts; - if (connectionRequest.isAutonomyConnect) { - final persona = - await injector().getOrCreateDefaultPersona(); - selectedPersona = WalletIndex(persona.wallet(), 0); - widget.onSelectPersona?.call(selectedPersona); + if (connectionRequest.isAutonomyConnect && + stateCategorizedAccounts?.isNotEmpty == true) { + selectedWallet = + WalletIndex(stateCategorizedAccounts!.first.wallet!, 0); + widget.onSelectPersona?.call(selectedWallet); } if (!mounted) { return; @@ -86,24 +86,26 @@ class _SelectAccountState extends State with RouteAware { if (categorizedAccounts.length != 1) { return; } - final persona = categorizedAccounts.first.persona; - if (persona == null) { + // no view only address in this page + final uuid = categorizedAccounts.first.walletAddress?.uuid; + if (uuid == null) { return; } + final wallet = categorizedAccounts.first.wallet!; final ethAccounts = categorizedAccounts.where((element) => element.isEth); final xtzAccounts = categorizedAccounts.where((element) => element.isTez); if (ethAccounts.length == 1) { - selectedPersona = WalletIndex(persona.wallet(), - (await persona.getEthWalletAddresses()).first.index); - widget.onSelectPersona?.call(selectedPersona); + selectedWallet = + WalletIndex(wallet, ethAccounts.first.walletAddress!.index); + widget.onSelectPersona?.call(selectedWallet); } if (xtzAccounts.length == 1) { - selectedPersona = WalletIndex(persona.wallet(), - (await persona.getTezWalletAddresses()).first.index); - widget.onSelectPersona?.call(selectedPersona); + selectedWallet = + WalletIndex(wallet, xtzAccounts.first.walletAddress!.index); + widget.onSelectPersona?.call(selectedWallet); } } @@ -146,13 +148,13 @@ class _SelectAccountState extends State with RouteAware { accounts: accounts, onSelectEth: (value) { int index = value.walletAddress?.index ?? 0; - selectedPersona = WalletIndex(value.persona!.wallet(), index); - widget.onSelectPersona?.call(selectedPersona); + selectedWallet = WalletIndex(value.wallet!, index); + widget.onSelectPersona?.call(selectedWallet); }, onSelectTez: (value) { int index = value.walletAddress?.index ?? 0; - selectedPersona = WalletIndex(value.persona!.wallet(), index); - widget.onSelectPersona?.call(selectedPersona); + selectedWallet = WalletIndex(value.wallet!, index); + widget.onSelectPersona?.call(selectedWallet); }, isAutoSelect: accounts.length == 1, ), diff --git a/test/generate_mock/service/mock_account_service.mocks.dart b/test/generate_mock/service/mock_account_service.mocks.dart index 01ba26895..b66f28b23 100644 --- a/test/generate_mock/service/mock_account_service.mocks.dart +++ b/test/generate_mock/service/mock_account_service.mocks.dart @@ -116,7 +116,7 @@ class MockAccountService extends _i1.Mock implements _i6.AccountService { )), ) as _i7.Future<_i2.WalletStorage>); @override - _i7.Future<_i3.Persona> getOrCreateDefaultPersona() => (super.noSuchMethod( + _i7.Future<_i3.Persona> getOrCreatePrimaryWallet() => (super.noSuchMethod( Invocation.method( #getOrCreateDefaultPersona, [], @@ -216,7 +216,7 @@ class MockAccountService extends _i1.Mock implements _i6.AccountService { )), ) as _i7.Future<_i3.Persona>); @override - _i7.Future<_i3.Persona> createPersona({ + _i7.Future<_i3.Persona> createNewWallet({ String? name = r'', String? passphrase = r'', bool? isDefault = false,