Skip to content

Commit b4ba6e0

Browse files
committed
feat: initial hive -> SQLite
Includes migration script and initial work done to remove dependency on hive generators. Also contains some refactoring to make sync code async. Features new dev screen that lists all SQLite tables Aspects that need testing: - backups (from this version, and from previous versions as well) - wallet loading / wallet list - almost everything else - renaming - deletion - sorting in wallet list - wallet groups - wallet seed/keys - wallet switching - wallet creation / restore - all methods - wallet address page - hardware wallet connection (and prompts from mall screens) - contacts - advanced settings in wallet creation - derivation paths - some minor wownero fixes
1 parent 261406c commit b4ba6e0

22 files changed

+215
-137
lines changed

.github/workflows/pr_test_build_linux.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ jobs:
310310
rm -rf ~/.local/share/com.example.cake_wallet/ ~/Documents/cake_wallet/ ~/cake_wallet
311311
exec timeout --signal=SIGKILL 900 flutter drive --driver=test_driver/integration_test.dart --target=integration_test/test_suites/restore_wallet_through_seeds_flow_test.dart
312312
- name: Test [cw_monero]
313-
timeout-minutes: 2
314-
run: cd cw_monero && flutter test
313+
timeout-minutes: 15
314+
run: cd cw_monero && flutter test --verbose
315315
- name: Stop screen recording, encrypt and upload
316316
if: always()
317317
run: |

cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ class BitcoinNewWalletCredentials extends WalletCredentials {
1616
walletInfo: walletInfo,
1717
password: password,
1818
passphrase: passphrase,
19+
derivationInfo: DerivationInfo(
20+
derivationType: derivationType,
21+
derivationPath: derivationPath,
22+
),
1923
);
2024

2125
final String? mnemonic;

cw_bitcoin/lib/bitcoin_wallet_service.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ class BitcoinWalletService extends WalletService<
3939

4040
final String mnemonic;
4141
final derivationInfo = await credentials.walletInfo!.getDerivationInfo();
42+
derivationInfo.derivationType = credentials.derivationInfo?.derivationType ?? derivationInfo.derivationType;
43+
derivationInfo.derivationPath = credentials.derivationInfo?.derivationPath ?? derivationInfo.derivationPath;
44+
derivationInfo.description = credentials.derivationInfo?.description ?? derivationInfo.description;
45+
derivationInfo.scriptType = credentials.derivationInfo?.scriptType ?? derivationInfo.scriptType;
46+
await derivationInfo.save();
4247
switch (derivationInfo.derivationType) {
4348
case DerivationType.bip39:
4449
final strength = credentials.seedPhraseLength == 24 ? 256 : 128;

cw_bitcoin/lib/litecoin_wallet_service.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class LitecoinWalletService extends WalletService<
5050
password: credentials.password!,
5151
passphrase: credentials.passphrase,
5252
walletInfo: credentials.walletInfo!,
53-
derivationInfo: credentials.derivationInfo!,
53+
derivationInfo: credentials.derivationInfo ?? (await credentials.walletInfo!.getDerivationInfo()),
5454
unspentCoinsInfo: unspentCoinsInfoSource,
5555
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
5656
);
@@ -202,7 +202,7 @@ class LitecoinWalletService extends WalletService<
202202
passphrase: credentials.passphrase,
203203
mnemonic: credentials.mnemonic,
204204
walletInfo: credentials.walletInfo!,
205-
derivationInfo: credentials.derivationInfo!,
205+
derivationInfo: credentials.derivationInfo ?? (await credentials.walletInfo!.getDerivationInfo()),
206206
unspentCoinsInfo: unspentCoinsInfoSource,
207207
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
208208
);

cw_bitcoin/pubspec.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ packages:
9393
dependency: "direct overridden"
9494
description:
9595
path: "."
96-
ref: "490046a3e074dd7b9aaf7098a5efe61b6246d3b2"
97-
resolved-ref: "46e5a2d8a5438cb523a6104b70f5e5125a5663b3"
96+
ref: cake-update-v11
97+
resolved-ref: bda0e2904effa799ec835b4578cc3fc5d31caa78
9898
url: "https://github.com/cake-tech/bitcoin_base"
9999
source: git
100100
version: "4.7.0"
@@ -350,10 +350,10 @@ packages:
350350
dependency: transitive
351351
description:
352352
name: fake_async
353-
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
353+
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
354354
url: "https://pub.dev"
355355
source: hosted
356-
version: "1.3.2"
356+
version: "1.3.3"
357357
ffi:
358358
dependency: "direct overridden"
359359
description:

cw_core/lib/db/sqlite.dart

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
2+
import 'package:sqflite/sqflite.dart';
3+
4+
late Database db;
5+
6+
Future<void> initDb({String? pathOverride}) async {
7+
db = await openDatabase(
8+
pathOverride ?? "cake.db",
9+
version: 1,
10+
onCreate: (Database db, int version) async {
11+
await db.execute(
12+
'''
13+
CREATE TABLE WalletInfo (
14+
walletInfoId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
15+
id TEXT NOT NULL,
16+
name TEXT NOT NULL,
17+
"type" INTEGER NOT NULL,
18+
isRecovery INTEGER DEFAULT (0) NOT NULL,
19+
walletInfoDerivationInfoId INTEGER NOT NULL,
20+
restoreHeight INTEGER DEFAULT (0) NOT NULL,
21+
"timestamp" INTEGER DEFAULT (0) NOT NULL,
22+
dirPath TEXT NOT NULL,
23+
"path" TEXT NOT NULL,
24+
address TEXT NOT NULL,
25+
yatEid TEXT,
26+
yatLastUsedAddressRaw TEXT,
27+
showIntroCakePayCard INTEGER DEFAULT (1),
28+
addressPageType TEXT,
29+
network TEXT,
30+
hardwareWalletType INTEGER,
31+
parentAddress TEXT,
32+
hashedWalletIdentifier TEXT,
33+
isNonSeedWallet INTEGER DEFAULT (0) NOT NULL,
34+
sortOrder INTEGER DEFAULT (0) NOT NULL
35+
);
36+
''');
37+
38+
await db.execute(
39+
'''
40+
CREATE TABLE WalletInfoDerivationInfo (
41+
walletInfoDerivationInfoId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
42+
address TEXT NOT NULL,
43+
balance TEXT NOT NULL,
44+
transactionsCount INTEGER DEFAULT (0) NOT NULL,
45+
derivationType INTEGER NOT NULL,
46+
derivationPath TEXT,
47+
scriptType TEXT,
48+
description TEXT
49+
);
50+
''');
51+
52+
await db.execute(
53+
'''
54+
CREATE TABLE WalletInfoAddress (
55+
walletInfoAddressId INTEGER PRIMARY KEY AUTOINCREMENT,
56+
walletInfoId INTEGER,
57+
"type" INTEGER NOT NULL,
58+
address TEXT NOT NULL,
59+
CONSTRAINT WalletInfoAddress_WalletInfo_FK FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
60+
);
61+
''');
62+
63+
await db.execute(
64+
'''
65+
CREATE TABLE WalletInfoAddressInfo (
66+
walletInfoAddressInfoId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
67+
walletInfoId INTEGER NOT NULL,
68+
mapKey INTEGER NOT NULL,
69+
mapValueAccountIndex INTEGER NOT NULL,
70+
mapValueAddress TEXT NOT NULL,
71+
mapValueLabel TEXT NOT NULL,
72+
CONSTRAINT WalletInfoAddressInfo_WalletInfo_FK FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
73+
);
74+
''');
75+
76+
await db.execute(
77+
'''
78+
CREATE TABLE "WalletInfoAddressMap" (
79+
walletInfoAddressMapId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
80+
walletInfoId INTEGER NOT NULL,
81+
addressKey TEXT NOT NULL,
82+
addressValue TEXT NOT NULL,
83+
CONSTRAINT WalletInfoAddress_WalletInfo_FK FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
84+
);
85+
'''
86+
);
87+
}
88+
);
89+
}
90+
91+
Future<Map<String, dynamic>> dumpDb() async {
92+
try {
93+
return await _dumpDb();
94+
} catch (e) {
95+
return {
96+
"error": e.toString(),
97+
"stackTrace": StackTrace.current.toString(),
98+
};
99+
}
100+
}
101+
102+
Future<List<String>> _getTableNames() async {
103+
final tableNames = await db.rawQuery('SELECT name FROM sqlite_master WHERE type = "table"');
104+
return tableNames.map((e) => (e["name"]).toString()).toList();
105+
}
106+
107+
Future<Map<String, dynamic>> _dumpDb() async {
108+
final tableNames = await _getTableNames();
109+
final ret = <String, dynamic>{};
110+
for (final tableName in tableNames) {
111+
ret[tableName] = await db.query(tableName);
112+
}
113+
return ret;
114+
}

cw_core/lib/wallet_info.dart

Lines changed: 7 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import 'dart:async';
22

3+
import 'package:cw_core/db/sqlite.dart';
34
import 'package:cw_core/hive_type_ids.dart';
45
import 'package:cw_core/utils/print_verbose.dart';
56
import 'package:cw_core/wallet_type.dart';
67
import 'package:sqflite/sqflite.dart';
78
import 'package:cw_core/cake_hive.dart';
89
import 'package:cw_core/wallet_info_legacy.dart' as wiLegacy;
910

10-
late Database db;
11-
1211
Future<void> performHiveMigration() async {
1312
try {
1413
if (!CakeHive.isAdapterRegistered(wiLegacy.WalletInfo.typeId)) {
@@ -30,91 +29,6 @@ Future<void> performHiveMigration() async {
3029
}
3130
}
3231

33-
Future<void> initDb({String? pathOverride}) async {
34-
db = await openDatabase(
35-
pathOverride ?? "cake.db",
36-
version: 1,
37-
onCreate: (Database db, int version) async {
38-
await db.execute(
39-
'''
40-
CREATE TABLE WalletInfo (
41-
walletInfoId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
42-
id TEXT NOT NULL,
43-
name TEXT NOT NULL,
44-
"type" INTEGER NOT NULL,
45-
isRecovery INTEGER DEFAULT (0) NOT NULL,
46-
walletInfoDerivationInfoId INTEGER NOT NULL,
47-
restoreHeight INTEGER DEFAULT (0) NOT NULL,
48-
"timestamp" INTEGER DEFAULT (0) NOT NULL,
49-
dirPath TEXT NOT NULL,
50-
"path" TEXT NOT NULL,
51-
address TEXT NOT NULL,
52-
yatEid TEXT,
53-
yatLastUsedAddressRaw TEXT,
54-
showIntroCakePayCard INTEGER DEFAULT (1),
55-
addressPageType TEXT,
56-
network TEXT,
57-
hardwareWalletType INTEGER,
58-
parentAddress TEXT,
59-
hashedWalletIdentifier TEXT,
60-
isNonSeedWallet INTEGER DEFAULT (0) NOT NULL,
61-
sortOrder INTEGER DEFAULT (0) NOT NULL
62-
);
63-
''');
64-
65-
await db.execute(
66-
'''
67-
CREATE TABLE WalletInfoDerivationInfo (
68-
walletInfoDerivationInfoId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
69-
address TEXT NOT NULL,
70-
balance TEXT NOT NULL,
71-
transactionsCount INTEGER DEFAULT (0) NOT NULL,
72-
derivationType INTEGER NOT NULL,
73-
derivationPath TEXT,
74-
scriptType TEXT,
75-
description TEXT
76-
);
77-
''');
78-
79-
await db.execute(
80-
'''
81-
CREATE TABLE WalletInfoAddress (
82-
walletInfoAddressId INTEGER PRIMARY KEY AUTOINCREMENT,
83-
walletInfoId INTEGER,
84-
"type" INTEGER NOT NULL,
85-
address TEXT NOT NULL,
86-
CONSTRAINT WalletInfoAddress_WalletInfo_FK FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
87-
);
88-
''');
89-
90-
await db.execute(
91-
'''
92-
CREATE TABLE WalletInfoAddressInfo (
93-
walletInfoAddressInfoId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
94-
walletInfoId INTEGER NOT NULL,
95-
mapKey INTEGER NOT NULL,
96-
mapValueAccountIndex INTEGER NOT NULL,
97-
mapValueAddress TEXT NOT NULL,
98-
mapValueLabel TEXT NOT NULL,
99-
CONSTRAINT WalletInfoAddressInfo_WalletInfo_FK FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
100-
);
101-
''');
102-
103-
await db.execute(
104-
'''
105-
CREATE TABLE "WalletInfoAddressMap" (
106-
walletInfoAddressMapId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
107-
walletInfoId INTEGER NOT NULL,
108-
addressKey TEXT NOT NULL,
109-
addressValue TEXT NOT NULL,
110-
CONSTRAINT WalletInfoAddress_WalletInfo_FK FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
111-
);
112-
'''
113-
);
114-
}
115-
);
116-
}
117-
11832
enum DerivationType {
11933
unknown,
12034
def, // default is a reserved word
@@ -427,7 +341,7 @@ class WalletInfo {
427341
bool? showIntroCakePayCard,
428342
String yatEid = '',
429343
String yatLastUsedAddressRaw = '',
430-
DerivationInfo? derivationInfo,
344+
int? derivationInfoId,
431345
HardwareWalletType? hardwareWalletType,
432346
String? parentAddress,
433347
String? hashedWalletIdentifier,
@@ -448,7 +362,7 @@ class WalletInfo {
448362
yatEid,
449363
yatLastUsedAddressRaw,
450364
showIntroCakePayCard,
451-
derivationInfo?.id ?? -1,
365+
derivationInfoId ?? -1,
452366
hardwareWalletType,
453367
parentAddress,
454368
hashedWalletIdentifier,
@@ -478,7 +392,8 @@ class WalletInfo {
478392

479393
Future<void> setAddresses(Map<String, String> addresses) async {
480394
await WalletInfoAddressMap.deleteByWalletInfoId(internalId);
481-
for (final address in addresses.keys) {
395+
final keys = addresses.keys.toList();
396+
for (final address in keys) {
482397
await WalletInfoAddressMap.insert(internalId, address, addresses[address]!);
483398
}
484399
}
@@ -498,7 +413,8 @@ class WalletInfo {
498413

499414
Future<void> setAddressInfos(Map<int, List<WalletInfoAddressInfo>> addressInfos) async {
500415
await WalletInfoAddressInfo.deleteByWalletInfoId(internalId);
501-
for (final addressInfo in addressInfos.entries) {
416+
final entries = addressInfos.entries.toList();
417+
for (final addressInfo in entries) {
502418
for (final info in addressInfo.value) {
503419
await WalletInfoAddressInfo.insert(
504420
walletInfoId: internalId,

cw_monero/test/monero_wallet_service_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:io';
22

3+
import 'package:cw_core/db/sqlite.dart';
34
import 'package:cw_core/unspent_coins_info.dart';
45
import 'package:cw_core/wallet_base.dart';
56
import 'package:cw_core/wallet_info.dart';

cw_nano/lib/nano_wallet_creation_credentials.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class NanoNewWalletCredentials extends WalletCredentials {
1414
password: password,
1515
walletInfo: walletInfo,
1616
passphrase: passphrase,
17+
derivationInfo: DerivationInfo(derivationType: derivationType),
1718
);
1819

1920
final String? mnemonic;

cw_nano/lib/nano_wallet_service.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class NanoWalletService extends WalletService<
3232
@override
3333
Future<WalletBase> create(NanoNewWalletCredentials credentials, {bool? isTestnet}) async {
3434
final String mnemonic;
35-
final derivationInfo = await credentials.walletInfo!.getDerivationInfo();
35+
final derivationInfo = credentials.derivationInfo ?? await credentials.walletInfo!.getDerivationInfo();
3636
switch (derivationInfo.derivationType) {
3737
case DerivationType.nano:
3838
String seedKey = NanoSeeds.generateSeed();

0 commit comments

Comments
 (0)