dev
dart 96 lines 2.96 KB
Raw
1 import 'dart:math';
2
3 import 'package:cw_core/get_height_by_date_zec.dart';
4 import 'package:cw_core/pathForWallet.dart';
5 import 'package:cw_core/utils/print_verbose.dart';
6 import 'package:cw_core/wallet_type.dart';
7 import 'package:cw_zcash/cw_zcash.dart';
8 import 'package:sqflite_common_ffi/sqflite_ffi.dart';
9 import 'package:path/path.dart' as p;
10
11 class ZkoolSeed {
12 ZkoolSeed({required this.seed, required this.passphrase});
13
14 factory ZkoolSeed.fromYwalletSeed({required final String ywalletSeed}) {
15 final splSeed = ywalletSeed.split(" ");
16 String seed = "";
17 ;
18 String passphrase = "";
19 if ([13, 25].contains(splSeed.length)) {
20 seed = splSeed.take(splSeed.length - 1).join(" ");
21 passphrase = ywalletSeed.replaceFirst("${seed} ", "");
22 } else {
23 seed = ywalletSeed;
24 }
25 return ZkoolSeed(seed: seed, passphrase: passphrase);
26 }
27
28 String seed;
29 String passphrase;
30 }
31
32 class YwalletAccountInfo {
33 YwalletAccountInfo({
34 required this.idAccount,
35 required this.name,
36 required this.seed,
37 required this.aindex,
38 required this.sk,
39 required this.ivk,
40 required this.address,
41 });
42 final int idAccount;
43 final String name;
44 final String seed;
45 late final zkoolSeed = ZkoolSeed.fromYwalletSeed(ywalletSeed: seed);
46 final int aindex;
47 final String sk;
48 final String ivk;
49 final String address;
50 static YwalletAccountInfo fromJson(final Map<String, dynamic> j) => YwalletAccountInfo(
51 idAccount: j['id_account'],
52 name: j['name'],
53 seed: j['seed'],
54 aindex: j['aindex'],
55 sk: j['sk'],
56 ivk: j['ivk'],
57 address: j['address'],
58 );
59 }
60
61 Future<void> migrateOldSqliteToZkool2({required final String walletName}) async {
62 final dbFile = p.join(await pathForWalletTypeDir(type: WalletType.zcash), "zec.db");
63 final migrateDb = await openDatabase(dbFile);
64 final outputRaw = await migrateDb.rawQuery(
65 "SELECT `id_account`, `name`, `seed`, `aindex`, `sk`, `ivk`, `address` FROM `accounts`",
66 );
67 final output = outputRaw.map(YwalletAccountInfo.fromJson);
68
69 final walletId = await ZcashWalletBase.getLegacyZcashAccountIdForName(walletName);
70 for (final ya in output) {
71 if (ya.idAccount != walletId) {
72 continue;
73 }
74 printV("migrating account: ${ya.name} - ${walletName}");
75 int birthHeight = await ZcashHeight.getBlockHeightByTime(DateTime(2026, 1, 1));
76
77 final accTxs = await migrateDb.rawQuery(
78 "SELECT height FROM transactions WHERE account = ${ya.idAccount}",
79 );
80 for (final tx in accTxs) {
81 final txHeight = int.tryParse(tx['height'].toString()) ?? birthHeight;
82 birthHeight = min(birthHeight, txHeight);
83 }
84
85 final accountId = await ZcashWalletBase.restoreZcashWalletFromSeed(
86 name: walletName,
87 seed: ya.zkoolSeed.seed,
88 passphrase: ya.zkoolSeed.passphrase,
89 birthHeight: birthHeight,
90 );
91 await ZcashWalletBase.saveAccountId(walletName, accountId);
92 return;
93 }
94
95 throw Exception("migration not finished (wallet name: $walletName not found)");
96 }