dev
dart 253 lines 6.47 KB
Raw
1 import 'package:cw_core/utils/proxy_wrapper.dart';
2 import 'package:cw_core/utils/print_verbose.dart';
3 import 'package:intl/intl.dart';
4 import 'package:cw_core/get_height_by_date_xmr.dart';
5 import 'dart:convert';
6
7 // FIXME: Hardcoded values; Works only for monero
8
9 int getMoneroHeigthByDate({required DateTime date}) =>
10 MoneroHeight.getBlockHeightByTime(date..subtract(Duration(days: 1)));
11
12 const havenDates = {
13 "2023-05": 1352995,
14 "2023-04": 1331460,
15 "2023-03": 1309180,
16 "2023-01": 1266810,
17 "2022-12": 1244510,
18 "2022-11": 1222970,
19 "2022-10": 1200700,
20 "2022-09": 1179140,
21 "2022-08": 1156870,
22 "2022-07": 1134600,
23 "2022-06": 1113030,
24 "2022-05": 1090800,
25 "2022-04": 1069250,
26 "2022-03": 1047000,
27 "2022-02": 1026960,
28 "2022-01": 1004700,
29 "2021-12": 982400,
30 "2021-11": 961000,
31 "2021-10": 938600,
32 "2021-09": 917000,
33 "2021-08": 894800,
34 "2021-07": 886000,
35 "2021-06": 867300,
36 "2021-05": 845000,
37 "2021-04": 823500,
38 "2021-03": 801500,
39 "2021-02": 781000,
40 "2021-01": 759000,
41 "2020-12": 736500,
42 "2020-11": 715000,
43 "2020-10": 693000,
44 "2020-09": 671000,
45 "2020-08": 649000,
46 "2020-07": 626600,
47 "2020-06": 605000,
48 "2020-05": 582700,
49 "2020-04": 561100,
50 "2020-03": 539000,
51 "2020-02": 518000,
52 "2020-01": 496000,
53 "2019-12": 473400,
54 "2019-11": 451900,
55 "2019-10": 429600,
56 "2019-09": 408000,
57 "2019-08": 385700,
58 "2019-07": 363800,
59 "2019-06": 342200,
60 "2019-05": 320000,
61 "2019-04": 298400,
62 "2019-03": 276000,
63 "2019-02": 256000,
64 "2019-01": 233700,
65 "2018-12": 211400,
66 "2018-11": 189800,
67 "2018-10": 167500,
68 "2018-09": 145900,
69 "2018-08": 123700,
70 "2018-07": 101400,
71 "2018-06": 80000,
72 "2018-05": 57550,
73 "2018-04": 32000,
74 "2018-03": 8500
75 };
76 final dateFormat = DateFormat('yyyy-MM');
77
78 DateTime formatMapKey(String key) => dateFormat.parse(key);
79
80 int getHavenHeightByDate({required DateTime date}) {
81 String closestKey =
82 havenDates.keys.firstWhere((key) => formatMapKey(key).isBefore(date), orElse: () => '');
83
84 return havenDates[closestKey] ?? 0;
85 }
86
87 Future<int> getHavenCurrentHeight() async {
88 final req = await ProxyWrapper()
89 .getHttpClient()
90 .getUrl(Uri.parse('https://explorer.havenprotocol.org/api/networkinfo'))
91 .timeout(Duration(seconds: 15));
92 final response = await req.close();
93 final stringResponse = await response.transform(utf8.decoder).join();
94
95 if (response.statusCode == 200) {
96 final info = jsonDecode(stringResponse);
97 return info['data']['height'] as int;
98 } else {
99 throw Exception('Failed to load current blockchain height');
100 }
101 }
102
103 // Data taken from https://timechaincalendar.com/
104 const bitcoinDates = {
105 "2024-08": 854889,
106 "2024-07": 850182,
107 "2024-06": 846005,
108 "2024-05": 841590,
109 "2024-04": 837182,
110 "2024-03": 832623,
111 "2024-02": 828319,
112 "2024-01": 823807,
113 "2023-12": 819206,
114 "2023-11": 814765,
115 "2023-10": 810098,
116 "2023-09": 805675,
117 "2023-08": 801140,
118 "2023-07": 796640,
119 "2023-06": 792330,
120 "2023-05": 787733,
121 "2023-04": 783403,
122 "2023-03": 778740,
123 "2023-02": 774525,
124 "2023-01": 769810,
125 };
126
127 Future<int> getBitcoinHeightByDateAPI({required DateTime date}) async {
128 final req = await ProxyWrapper()
129 .getHttpClient()
130 .getUrl(Uri.parse(
131 "https://mempool.cakewallet.com/api/v1/mining/blocks/timestamp/${(date.millisecondsSinceEpoch / 1000).round()}"))
132 .timeout(Duration(seconds: 15));
133 final response = await req.close();
134 final stringResponse = await response.transform(utf8.decoder).join();
135
136 return jsonDecode(stringResponse)['height'] as int;
137 }
138
139 int getBitcoinHeightByDate({required DateTime date}) {
140 String dateKey = '${date.year}-${date.month.toString().padLeft(2, '0')}';
141 final closestKey = bitcoinDates.keys
142 .firstWhere((key) => formatMapKey(key).isBefore(date), orElse: () => bitcoinDates.keys.last);
143 final beginningBlock = bitcoinDates[dateKey] ?? bitcoinDates[closestKey]!;
144
145 final startOfMonth = DateTime(date.year, date.month);
146 final daysDifference = date.difference(startOfMonth).inDays;
147
148 // approximately 6 blocks per hour, 24 hours per day
149 int estimatedBlocksSinceStartOfMonth = (daysDifference * 24 * 6);
150
151 return beginningBlock + estimatedBlocksSinceStartOfMonth;
152 }
153
154 DateTime getDateByBitcoinHeight(int height) {
155 final closestEntry = bitcoinDates.entries
156 .lastWhere((entry) => entry.value >= height, orElse: () => bitcoinDates.entries.first);
157 final beginningBlock = closestEntry.value;
158
159 final startOfMonth = formatMapKey(closestEntry.key);
160 final blocksDifference = height - beginningBlock;
161 final hoursDifference = blocksDifference / 5.5;
162
163 final estimatedDate = startOfMonth.add(Duration(hours: hoursDifference.ceil()));
164
165 if (estimatedDate.isAfter(DateTime.now())) {
166 return DateTime.now();
167 }
168
169 return estimatedDate;
170 }
171
172 int getLtcHeightByDate({required DateTime date}) {
173 // TODO: use the proxy layer to get the height with a binary search of blocked header heights
174 return 0;
175 }
176
177 // TODO: enhance all of this global const lists
178 const wowDates = {
179 "2023-12": 583048,
180 "2023-11": 575048,
181 "2023-10": 566048,
182 "2023-09": 558048,
183 "2023-08": 549048,
184 "2023-07": 540048,
185 "2023-06": 532048,
186 "2023-05": 523048,
187 "2023-04": 514048,
188 "2023-03": 505048,
189 "2023-02": 497048,
190 "2023-01": 488048,
191 "2022-12": 479048,
192 "2022-11": 471048,
193 "2022-10": 462048,
194 "2022-09": 453048,
195 "2022-08": 444048,
196 "2022-07": 435048,
197 "2022-06": 427048,
198 "2022-05": 418048,
199 "2022-04": 410048,
200 "2022-03": 401048,
201 "2022-02": 393048,
202 "2022-01": 384048,
203 "2021-12": 375048,
204 "2021-11": 367048,
205 "2021-10": 358048,
206 "2021-09": 349048,
207 "2021-08": 340048,
208 "2021-07": 331048,
209 "2021-06": 322048,
210 "2021-05": 313048,
211 "2021-04": 305048,
212 "2021-03": 295048,
213 "2021-02": 287048,
214 "2021-01": 279148,
215 "2020-10": 252000,
216 "2020-09": 243000,
217 "2020-08": 234000,
218 "2020-07": 225000,
219 "2020-06": 217500,
220 "2020-05": 208500,
221 "2020-04": 199500,
222 "2020-03": 190500,
223 "2020-02": 183000,
224 "2020-01": 174000,
225 "2019-12": 165000,
226 "2019-11": 156000,
227 "2019-10": 147000,
228 "2019-09": 138000,
229 "2019-08": 129000,
230 "2019-07": 120000,
231 "2019-06": 112500,
232 "2019-05": 103500,
233 "2019-04": 94500,
234 "2019-03": 85500,
235 "2019-02": 79500,
236 "2019-01": 73500,
237 "2018-12": 67500,
238 "2018-11": 61500,
239 "2018-10": 52500,
240 "2018-09": 45000,
241 "2018-08": 36000,
242 "2018-07": 27000,
243 "2018-06": 18000,
244 "2018-05": 9000,
245 "2018-04": 1
246 };
247
248 int getWowneroHeightByDate({required DateTime date}) {
249 String closestKey =
250 wowDates.keys.firstWhere((key) => formatMapKey(key).isBefore(date), orElse: () => '');
251
252 return wowDates[closestKey] ?? 0;
253 }