Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/services/accounts/accounts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ abstract class AccountsOptionsInterface {}
///
/// This is used to store wallet backups and the implementation is platform specific.
abstract class AccountsServiceInterface {
final int _version = 5; // TODO: figure out correct version number (Kevin, Others)
final int _version = 7;

int get version => _version;

Expand All @@ -31,7 +31,7 @@ abstract class AccountsServiceInterface {
// key = wb_$wallet_address, value = $name|$privateKey

// get all accounts
Future<List<DBAccountV4>> getAllAccounts();
Future<List<DBAccount>> getAllAccounts();

// set account
Future<void> setAccount(DBAccount account);
Expand Down
79 changes: 65 additions & 14 deletions lib/services/accounts/native/android.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ class AndroidAccountsService extends AccountsServiceInterface {
}

// write the account data in the accounts table
// TODO: use DBAccountV4, with getAccountFactoryAddressByAlias
final account = DBAccount(
alias: legacyBackup.alias,
address: EthereumAddress.fromHex(legacyBackup.address),
name: legacyBackup.name,
accountFactoryAddress: EthereumAddress.fromHex(
getAccountFactoryAddressByAlias(legacyBackup.alias)),
);

await _accountsDB.accounts.insert(account);
Expand All @@ -94,6 +95,15 @@ class AndroidAccountsService extends AccountsServiceInterface {
}
},
5: () async {
// bad migration, https://github.com/citizenwallet/app/blob/d4f72940e11f1812c34dfb47c0bffe7488a1c32e/lib/services/accounts/native/android.dart#L146
},
6: () async {
// bad migration, https://github.com/citizenwallet/app/blob/d4f72940e11f1812c34dfb47c0bffe7488a1c32e/lib/services/accounts/native/android.dart#L251
},
7: () async {
// distinguish migration starting from 4 (Others)
//distinguish migration starting from 6 (Kevin, Jonas)

// Read all credentials from secure storage
final allValues = await _credentials.readAll();

Expand Down Expand Up @@ -155,7 +165,8 @@ class AndroidAccountsService extends AccountsServiceInterface {
await _credentials.write(backup.key, backup.value);

// Mark old key for deletion
toDelete.add(oldKey);
// TODO: delete the old key
// toDelete.add(oldKey);
} catch (e) {
// If we can't determine the account factory address, skip this key
debugPrint('Error migrating key $oldKey: $e');
Expand Down Expand Up @@ -189,11 +200,18 @@ class AndroidAccountsService extends AccountsServiceInterface {

// get all wallet backups
@override
Future<List<DBAccountV4>> getAllAccounts() async {
final List<DBAccountV4> accounts = await _accountsDB.accounts.all();
Future<List<DBAccount>> getAllAccounts() async {
final List<DBAccount> accounts = await _accountsDB.accounts.all();

for (final account in accounts) {
final privateKey = await _credentials.read(account.id);
final backupKey = BackupWalletV5(
address: account.address.hexEip55,
alias: account.alias,
accountFactoryAddress: account.accountFactoryAddress.hexEip55,
privateKey: '',
).key;

final privateKey = await _credentials.read(backupKey);
if (privateKey == null) {
continue;
}
Expand All @@ -213,9 +231,16 @@ class AndroidAccountsService extends AccountsServiceInterface {
return;
}

final backup = BackupWalletV5(
address: account.address.hexEip55,
alias: account.alias,
accountFactoryAddress: account.accountFactoryAddress.hexEip55,
privateKey: bytesToHex(account.privateKey!.privateKey),
);

await _credentials.write(
account.id,
bytesToHex(account.privateKey!.privateKey),
backup.key,
backup.value,
);
}

Expand All @@ -231,7 +256,14 @@ class AndroidAccountsService extends AccountsServiceInterface {
return null;
}

final privateKey = await _credentials.read(account.id);
final backupKey = BackupWalletV5(
address: account.address.hexEip55,
alias: account.alias,
accountFactoryAddress: account.accountFactoryAddress.hexEip55,
privateKey: '',
).key;

final privateKey = await _credentials.read(backupKey);
if (privateKey == null) {
return account;
}
Expand All @@ -250,16 +282,28 @@ class AndroidAccountsService extends AccountsServiceInterface {
// delete wallet backup
@override
Future<void> deleteAccount(String address, String alias) async {
// Get the account before deleting it
final account =
await _accountsDB.accounts.get(EthereumAddress.fromHex(address), alias);

if (account == null) {
return;
}

await _accountsDB.accounts.delete(
EthereumAddress.fromHex(address),
alias,
);

final backupKey = BackupWalletV5(
address: account.address.hexEip55,
alias: account.alias,
accountFactoryAddress: account.accountFactoryAddress.hexEip55,
privateKey: '',
).key;

await _credentials.delete(
getAccountID(
EthereumAddress.fromHex(address),
alias,
),
backupKey,
);
}

Expand Down Expand Up @@ -357,9 +401,16 @@ class AndroidAccountsService extends AccountsServiceInterface {
final allAccounts = await getAllAccounts(); // accounts with private keys

for (final account in allAccounts) {
final backup = BackupWalletV5(
address: account.address.hexEip55,
alias: account.alias,
accountFactoryAddress: account.accountFactoryAddress.hexEip55,
privateKey: bytesToHex(account.privateKey!.privateKey),
);

await _credentials.write(
account.id,
bytesToHex(account.privateKey!.privateKey),
backup.key,
backup.value,
);

// null private key before updating in DB
Expand Down
71 changes: 59 additions & 12 deletions lib/services/accounts/native/apple.dart
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,12 @@ class AppleAccountsService extends AccountsServiceInterface {
}

// write the account data in the accounts table
// TODO: use DBAccountV4, with getAccountFactoryAddressByAlias
final DBAccount account = DBAccount(
alias: legacyBackup.alias,
address: EthereumAddress.fromHex(legacyBackup.address),
name: legacyBackup.name,
accountFactoryAddress: EthereumAddress.fromHex(
getAccountFactoryAddressByAlias(legacyBackup.alias)),
);

await _accountsDB.accounts.insert(account);
Expand Down Expand Up @@ -207,6 +208,17 @@ class AppleAccountsService extends AccountsServiceInterface {
}
},
5: () async {
// bad migration, https://github.com/citizenwallet/app/blob/d4f72940e11f1812c34dfb47c0bffe7488a1c32e/lib/services/accounts/native/apple.dart#L154
},
6: () async {
// bad migration, https://github.com/citizenwallet/app/blob/d4f72940e11f1812c34dfb47c0bffe7488a1c32e/lib/services/accounts/native/apple.dart#L264
},
7: () async {

// distinguish migration starting from 4 (Others)
//distinguish migration starting from 6 (Kevin, Jonas)


// Read all credentials from Keychain
final allValues = await _credentials.readAll();

Expand Down Expand Up @@ -265,7 +277,8 @@ class AppleAccountsService extends AccountsServiceInterface {
await _credentials.write(backup.key, backup.value);

// Mark old key for deletion
toDelete.add(oldKey);
// TODO: delete the old key
// toDelete.add(oldKey);
} catch (e) {
// If we can't determine the account factory address, skip this key
debugPrint('Error migrating key $oldKey: $e');
Expand Down Expand Up @@ -302,11 +315,18 @@ class AppleAccountsService extends AccountsServiceInterface {

// get all wallet backups
@override
Future<List<DBAccountV4>> getAllAccounts() async {
final List<DBAccountV4> accounts = await _accountsDB.accounts.all();
Future<List<DBAccount>> getAllAccounts() async {
final List<DBAccount> accounts = await _accountsDB.accounts.all();

for (final account in accounts) {
final privateKey = await _credentials.read(account.id);
final backupKey = BackupWalletV5(
address: account.address.hexEip55,
alias: account.alias,
accountFactoryAddress: account.accountFactoryAddress.hexEip55,
privateKey: '',
).key;

final privateKey = await _credentials.read(backupKey);
if (privateKey == null) {
continue;
}
Expand All @@ -326,9 +346,16 @@ class AppleAccountsService extends AccountsServiceInterface {
return;
}

final backup = BackupWalletV5(
address: account.address.hexEip55,
alias: account.alias,
accountFactoryAddress: account.accountFactoryAddress.hexEip55,
privateKey: bytesToHex(account.privateKey!.privateKey),
);

await _credentials.write(
account.id,
bytesToHex(account.privateKey!.privateKey),
backup.key,
backup.value,
);
}

Expand All @@ -344,7 +371,14 @@ class AppleAccountsService extends AccountsServiceInterface {
return null;
}

final privateKey = await _credentials.read(account.id);
final backupKey = BackupWalletV5(
address: account.address.hexEip55,
alias: account.alias,
accountFactoryAddress: account.accountFactoryAddress.hexEip55,
privateKey: '',
).key;

final privateKey = await _credentials.read(backupKey);
if (privateKey == null) {
return account;
}
Expand All @@ -363,16 +397,29 @@ class AppleAccountsService extends AccountsServiceInterface {
// delete wallet backup
@override
Future<void> deleteAccount(String address, String alias) async {
final account = await _accountsDB.accounts.get(
EthereumAddress.fromHex(address),
alias,
);

if (account == null) {
return;
}

await _accountsDB.accounts.delete(
EthereumAddress.fromHex(address),
alias,
);

final backupKey = BackupWalletV5(
address: account.address.hexEip55,
alias: account.alias,
accountFactoryAddress: account.accountFactoryAddress.hexEip55,
privateKey: '',
).key;

await _credentials.delete(
getAccountID(
EthereumAddress.fromHex(address),
alias,
),
backupKey,
);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/services/accounts/web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class WebAccountsService extends AccountsServiceInterface {

// get all wallet backups
@override
Future<List<DBAccountV4>> getAllAccounts() async {
Future<List<DBAccount>> getAllAccounts() async {
return [];
}

Expand Down
18 changes: 7 additions & 11 deletions lib/services/config/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,6 @@ class Config {
return primaryToken;
}

// TODO: remove use of getPrimaryAccountAbstractionConfig
ERC4337Config getPrimaryAccountAbstractionConfig() {
final primaryAccountAbstraction =
accounts[community.primaryAccountFactory.fullAddress];
Expand All @@ -727,14 +726,9 @@ class Config {
return primaryAccountAbstraction;
}

// TODO: force required accountFactoryAddress
// TODO: remove use of getPrimaryAccountAbstractionConfig
ERC4337Config getAccountAbstractionConfig({String? accountFactoryAddress}) {
// If no accountFactoryAddress is provided, return the primary config
if (accountFactoryAddress == null || accountFactoryAddress.isEmpty) {
return getPrimaryAccountAbstractionConfig();
}

ERC4337Config getAccountAbstractionConfig({
required String accountFactoryAddress,
}) {
// Build the full address key using chainId:accountFactoryAddress format
final chainId = community.primaryToken.chainId;
final fullAddress = '$chainId:$accountFactoryAddress';
Expand Down Expand Up @@ -765,8 +759,10 @@ class Config {
return chain.node.url;
}

// TODO: force required accountFactoryAddress
String getRpcUrl(String chainId, {String? accountFactoryAddress}) {
String getRpcUrl({
required String chainId,
required String accountFactoryAddress,
}) {
final chain = chains[chainId];

if (chain == null) {
Expand Down
Loading
Loading