dev
dart 147 lines 4.26 KB
Raw
1 import 'package:cw_monero/api/account_list.dart';
2 import 'package:cw_monero/api/transaction_history.dart';
3 import 'package:cw_monero/api/wallet.dart';
4 import 'package:monero/monero.dart';
5
6 bool isUpdating = false;
7
8 class SubaddressInfoMetadata {
9 SubaddressInfoMetadata({
10 required this.accountIndex,
11 });
12 int accountIndex;
13 }
14
15 SubaddressInfoMetadata? subaddress = null;
16
17 String getRawLabel({required int accountIndex, required int addressIndex}) {
18 return currentWallet?.getSubaddressLabel(
19 accountIndex: accountIndex, addressIndex: addressIndex) ??
20 "";
21 }
22
23 void refreshSubaddresses({required int accountIndex}) {
24 try {
25 isUpdating = true;
26 subaddress = SubaddressInfoMetadata(accountIndex: accountIndex);
27 isUpdating = false;
28 } catch (e) {
29 isUpdating = false;
30 rethrow;
31 }
32 }
33
34 class Subaddress {
35 Subaddress({
36 required this.addressIndex,
37 required this.accountIndex,
38 required this.received,
39 required this.txCount,
40 });
41 late String address = getAddress(
42 accountIndex: accountIndex,
43 addressIndex: addressIndex,
44 );
45 final int addressIndex;
46 final int accountIndex;
47 final int received;
48 final int txCount;
49 String get label {
50 final localLabel =
51 currentWallet?.getSubaddressLabel(accountIndex: accountIndex, addressIndex: addressIndex) ??
52 "";
53 if (localLabel.startsWith("#$addressIndex"))
54 return localLabel; // don't duplicate the ID if it was user-providen
55 return "#$addressIndex ${localLabel}".trim();
56 }
57 }
58
59 class TinyTransactionDetails {
60 TinyTransactionDetails({
61 required this.address,
62 required this.amount,
63 });
64 final List<String> address;
65 final int amount;
66 }
67
68 int lastWptr = 0;
69 int lastTxCount = 0;
70 List<TinyTransactionDetails> ttDetails = [];
71
72 Future<List<Subaddress>> getAllSubaddresses() async {
73 try {
74 await txHistoryMutex.acquire();
75 txhistory = currentWallet!.history();
76 final txCount = txhistory!.count();
77 if (lastTxCount != txCount && lastWptr != currentWallet!.ffiAddress()) {
78 final List<TinyTransactionDetails> newttDetails = [];
79 lastTxCount = txCount;
80 lastWptr = currentWallet!.ffiAddress();
81 for (var i = 0; i < txCount; i++) {
82 final tx = txhistory!.transaction(i);
83 if (tx.direction() == TransactionInfo_Direction.Out.index) continue;
84 final subaddrs = tx.subaddrIndex().split(",");
85 final account = tx.subaddrAccount();
86 newttDetails.add(TinyTransactionDetails(
87 address: List.generate(
88 subaddrs.length,
89 (index) => getAddress(
90 accountIndex: account, addressIndex: int.tryParse(subaddrs[index]) ?? 0)),
91 amount: tx.amount(),
92 ));
93 }
94 ttDetails.clear();
95 ttDetails.addAll(newttDetails);
96 }
97 } finally {
98 txHistoryMutex.release();
99 }
100 final size = currentWallet!.numSubaddresses(accountIndex: subaddress!.accountIndex);
101 final list = List.generate(size, (index) {
102 final ttDetailsLocal = ttDetails.where((element) {
103 final address = getAddress(
104 accountIndex: subaddress!.accountIndex,
105 addressIndex: index,
106 );
107 if (element.address.contains(address)) return true;
108 return false;
109 }).toList();
110 int received = 0;
111 for (var i = 0; i < ttDetailsLocal.length; i++) {
112 received += ttDetailsLocal[i].amount;
113 }
114 return Subaddress(
115 accountIndex: subaddress!.accountIndex,
116 addressIndex: index,
117 received: received,
118 txCount: ttDetailsLocal.length,
119 );
120 }).reversed.toList();
121 if (list.length == 0) {
122 list.add(Subaddress(
123 addressIndex: subaddress!.accountIndex,
124 accountIndex: 0,
125 received: 0,
126 txCount: 0,
127 ));
128 }
129 return list;
130 }
131
132 int numSubaddresses(int subaccountIndex) {
133 return currentWallet?.numSubaddresses(accountIndex: subaccountIndex) ?? 0;
134 }
135
136 Future<void> addSubaddress({required int accountIndex, required String label}) async {
137 currentWallet?.addSubaddress(accountIndex: accountIndex, label: label);
138 refreshSubaddresses(accountIndex: accountIndex);
139 await store();
140 }
141
142 Future<void> setLabelForSubaddress(
143 {required int accountIndex, required int addressIndex, required String label}) async {
144 currentWallet?.setSubaddressLabel(
145 accountIndex: accountIndex, addressIndex: addressIndex, label: label);
146 await store();
147 }