fix: get height by date for monero (#3158)
cyan committed
Apr 13, 2026 at 23:42 UTC
dee2b09ebe4ec67699dfe5735c7f2420b70600e6
2 files changed
+434
-159
cw_core/lib/get_height_by_date.dart
+12
-159
@@ -1,163 +1,12 @@
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
8
-final dateFormat = DateFormat('yyyy-MM');
9
-final dates = {
10
- "2014-5": 18844,
11
- "2014-6": 65406,
12
- "2014-7": 108882,
13
- "2014-8": 153594,
14
- "2014-9": 198072,
15
- "2014-10": 241088,
16
- "2014-11": 285305,
17
- "2014-12": 328069,
18
- "2015-1": 372369,
19
- "2015-2": 416505,
20
- "2015-3": 456631,
21
- "2015-4": 501084,
22
- "2015-5": 543973,
23
- "2015-6": 588326,
24
- "2015-7": 631187,
25
- "2015-8": 675484,
26
- "2015-9": 719725,
27
- "2015-10": 762463,
28
- "2015-11": 806528,
29
- "2015-12": 849041,
30
- "2016-1": 892866,
31
- "2016-2": 936736,
32
- "2016-3": 977691,
33
- "2016-4": 1015848,
34
- "2016-5": 1037417,
35
- "2016-6": 1059651,
36
- "2016-7": 1081269,
37
- "2016-8": 1103630,
38
- "2016-9": 1125983,
39
- "2016-10": 1147617,
40
- "2016-11": 1169779,
41
- "2016-12": 1191402,
42
- "2017-1": 1213861,
43
- "2017-2": 1236197,
44
- "2017-3": 1256358,
45
- "2017-4": 1278622,
46
- "2017-5": 1300239,
47
- "2017-6": 1322564,
48
- "2017-7": 1344225,
49
- "2017-8": 1366664,
50
- "2017-9": 1389113,
51
- "2017-10": 1410738,
52
- "2017-11": 1433039,
53
- "2017-12": 1454639,
54
- "2018-1": 1477201,
55
- "2018-2": 1499599,
56
- "2018-3": 1519796,
57
- "2018-4": 1542067,
58
- "2018-5": 1562861,
59
- "2018-6": 1585135,
60
- "2018-7": 1606715,
61
- "2018-8": 1629017,
62
- "2018-9": 1651347,
63
- "2018-10": 1673031,
64
- "2018-11": 1695128,
65
- "2018-12": 1716687,
66
- "2019-1": 1738923,
67
- "2019-2": 1761435,
68
- "2019-3": 1781681,
69
- "2019-4": 1803081,
70
- "2019-5": 1824671,
71
- "2019-6": 1847005,
72
- "2019-7": 1868590,
73
- "2019-8": 1890552,
74
- "2019-9": 1912212,
75
- "2019-10": 1932200,
76
- "2019-11": 1957040,
77
- "2019-12": 1978090,
78
- "2020-1": 2001290,
79
- "2020-2": 2022688,
80
- "2020-3": 2043987,
81
- "2020-4": 2066536,
82
- "2020-5": 2090797,
83
- "2020-6": 2111633,
84
- "2020-7": 2131433,
85
- "2020-8": 2153983,
86
- "2020-9": 2176466,
87
- "2020-10": 2198453,
88
- "2020-11": 2220000,
89
- "2020-12": 2242240,
90
- "2021-1": 2264584,
91
- "2021-2": 2286892,
92
- "2021-3": 2307079,
93
- "2021-4": 2329385,
94
- "2021-5": 2351004,
95
- "2021-6": 2373306,
96
- "2021-7": 2394882,
97
- "2021-8": 2417162,
98
- "2021-9": 2439490,
99
- "2021-10": 2461020,
100
- "2021-11": 2483377,
101
- "2021-12": 2504932,
102
- "2022-1": 2527316,
103
- "2022-2": 2549605,
104
- "2022-3": 2569711,
105
- "2022-4": 2591995,
106
- "2022-5": 2613603,
107
- "2022-6": 2635840,
108
- "2022-7": 2657395,
109
- "2022-8": 2679705,
110
- "2022-9": 2701991,
111
- "2022-10": 2723607,
112
- "2022-11": 2745899,
113
- "2022-12": 2767427,
114
- "2023-1": 2789763,
115
- "2023-2": 2811996,
116
- "2023-3": 2832118,
117
- "2023-4": 2854365,
118
- "2023-5": 2875972,
119
- "2023-6": 2898234,
120
- "2023-7": 2919771,
121
- "2023-8": 2942045,
122
- "2023-9": 2964280,
123
- "2023-10": 2985937,
124
- "2023-11": 3008178,
125
- "2023-12": 3029759
126
-};
127
-
128
-int getMoneroHeigthByDate({required DateTime date}) {
129
- final raw = '${date.year}' + '-' + '${date.month}';
130
- final lastHeight = dates.values.last;
131
- int startHeight;
132
- int endHeight;
133
- int height = 0;
134
-
135
- try {
136
- if ((dates[raw] == null) || (dates[raw] == lastHeight)) {
137
- startHeight = dates.values.toList()[dates.length - 2];
138
- endHeight = dates.values.toList()[dates.length - 1];
139
- final heightPerDay = (endHeight - startHeight) / 31;
140
- final endDateRaw = dates.keys.toList()[dates.length - 1].split('-');
141
- final endYear = int.parse(endDateRaw[0]);
142
- final endMonth = int.parse(endDateRaw[1]);
143
- final endDate = DateTime(endYear, endMonth);
144
- final differenceInDays = date.difference(endDate).inDays;
145
- final daysHeight = (differenceInDays * heightPerDay).round();
146
- height = endHeight + daysHeight;
147
- } else {
148
- startHeight = dates[raw]!;
149
- final index = dates.values.toList().indexOf(startHeight);
150
- endHeight = dates.values.toList()[index + 1];
151
- final heightPerDay = ((endHeight - startHeight) / 31).round();
152
- final daysHeight = (date.day - 1) * heightPerDay;
153
- height = startHeight + daysHeight - heightPerDay;
154
- }
155
- } catch (e) {
156
- printV(e.toString());
157
- }
158
-
159
- return height;
160
-}
9
+int getMoneroHeigthByDate({required DateTime date}) => MoneroHeight.getBlockHeightByTime(date..subtract(Duration(days: 1)));
10
11
const havenDates = {
12
"2023-05": 1352995,
@@ -223,6 +72,7 @@ const havenDates = {
72
"2018-04": 32000,
73
"2018-03": 8500
74
};
75
+final dateFormat = DateFormat('yyyy-MM');
76
77
DateTime formatMapKey(String key) => dateFormat.parse(key);
78
@@ -234,9 +84,10 @@ int getHavenHeightByDate({required DateTime date}) {
84
}
85
86
Future<int> getHavenCurrentHeight() async {
237
- final req = await ProxyWrapper().getHttpClient()
238
- .getUrl(Uri.parse('https://explorer.havenprotocol.org/api/networkinfo'))
239
- .timeout(Duration(seconds: 15));
87
+ final req = await ProxyWrapper()
88
+ .getHttpClient()
89
+ .getUrl(Uri.parse('https://explorer.havenprotocol.org/api/networkinfo'))
90
+ .timeout(Duration(seconds: 15));
91
final response = await req.close();
92
final stringResponse = await response.transform(utf8.decoder).join();
93
@@ -273,9 +124,11 @@ const bitcoinDates = {
124
};
125
126
Future<int> getBitcoinHeightByDateAPI({required DateTime date}) async {
276
- final req = await ProxyWrapper().getHttpClient()
277
- .getUrl(Uri.parse("https://mempool.cakewallet.com/api/v1/mining/blocks/timestamp/${(date.millisecondsSinceEpoch / 1000).round()}"))
278
- .timeout(Duration(seconds: 15));
127
+ final req = await ProxyWrapper()
128
+ .getHttpClient()
129
+ .getUrl(Uri.parse(
130
+ "https://mempool.cakewallet.com/api/v1/mining/blocks/timestamp/${(date.millisecondsSinceEpoch / 1000).round()}"))
131
+ .timeout(Duration(seconds: 15));
132
final response = await req.close();
133
final stringResponse = await response.transform(utf8.decoder).join();
134
cw_core/lib/get_height_by_date_xmr.dart
new
+422
@@ -0,0 +1,422 @@
1
+
2
+class MoneroHeight {
3
+ // for i in $(seq 1 364); do echo "_Checkpoint(_t($(curl https://xmrchain.net/block/${i}0000 | grep -E '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}' | xargs | sed 's/ /\n/g' | head -5 | tail -1 | tr '()' ' ' | sed 's/ /\n/g' | head -2 | xargs)), ${i}0000),"; done > points.txt
4
+ static final List<_Checkpoint> _points = [
5
+ _Checkpoint(1398386790, 10000),
6
+ _Checkpoint(1398970097, 20000),
7
+ _Checkpoint(1399529049, 30000),
8
+ _Checkpoint(1400107914, 40000),
9
+ _Checkpoint(1400673084, 50000),
10
+ _Checkpoint(1401259431, 60000),
11
+ _Checkpoint(1401861514, 70000),
12
+ _Checkpoint(1402455081, 80000),
13
+ _Checkpoint(1403051337, 90000),
14
+ _Checkpoint(1403639801, 100000),
15
+ _Checkpoint(1404238831, 110000),
16
+ _Checkpoint(1404841666, 120000),
17
+ _Checkpoint(1405444927, 130000),
18
+ _Checkpoint(1406035044, 140000),
19
+ _Checkpoint(1406634825, 150000),
20
+ _Checkpoint(1407238604, 160000),
21
+ _Checkpoint(1407838442, 170000),
22
+ _Checkpoint(1408443936, 180000),
23
+ _Checkpoint(1409041095, 190000),
24
+ _Checkpoint(1409644412, 200000),
25
+ _Checkpoint(1410247699, 210000),
26
+ _Checkpoint(1410851018, 220000),
27
+ _Checkpoint(1411455976, 230000),
28
+ _Checkpoint(1412059180, 240000),
29
+ _Checkpoint(1412661506, 250000),
30
+ _Checkpoint(1413267445, 260000),
31
+ _Checkpoint(1413873271, 270000),
32
+ _Checkpoint(1414480925, 280000),
33
+ _Checkpoint(1415086077, 290000),
34
+ _Checkpoint(1415690591, 300000),
35
+ _Checkpoint(1416296909, 310000),
36
+ _Checkpoint(1416902704, 320000),
37
+ _Checkpoint(1417507901, 330000),
38
+ _Checkpoint(1418109054, 340000),
39
+ _Checkpoint(1418722232, 350000),
40
+ _Checkpoint(1419326271, 360000),
41
+ _Checkpoint(1419928389, 370000),
42
+ _Checkpoint(1420541216, 380000),
43
+ _Checkpoint(1421145579, 390000),
44
+ _Checkpoint(1421749732, 400000),
45
+ _Checkpoint(1422354623, 410000),
46
+ _Checkpoint(1422956207, 420000),
47
+ _Checkpoint(1423562393, 430000),
48
+ _Checkpoint(1424166115, 440000),
49
+ _Checkpoint(1424767351, 450000),
50
+ _Checkpoint(1425371690, 460000),
51
+ _Checkpoint(1425975620, 470000),
52
+ _Checkpoint(1426579077, 480000),
53
+ _Checkpoint(1427182546, 490000),
54
+ _Checkpoint(1427785048, 500000),
55
+ _Checkpoint(1428385900, 510000),
56
+ _Checkpoint(1428990297, 520000),
57
+ _Checkpoint(1429593770, 530000),
58
+ _Checkpoint(1430197340, 540000),
59
+ _Checkpoint(1430803986, 550000),
60
+ _Checkpoint(1431408119, 560000),
61
+ _Checkpoint(1432011390, 570000),
62
+ _Checkpoint(1432613317, 580000),
63
+ _Checkpoint(1433222583, 590000),
64
+ _Checkpoint(1433825715, 600000),
65
+ _Checkpoint(1434431094, 610000),
66
+ _Checkpoint(1435033265, 620000),
67
+ _Checkpoint(1435636924, 630000),
68
+ _Checkpoint(1436243604, 640000),
69
+ _Checkpoint(1436848163, 650000),
70
+ _Checkpoint(1437455928, 660000),
71
+ _Checkpoint(1438056769, 670000),
72
+ _Checkpoint(1438662194, 680000),
73
+ _Checkpoint(1439267688, 690000),
74
+ _Checkpoint(1439872751, 700000),
75
+ _Checkpoint(1440479855, 710000),
76
+ _Checkpoint(1441084930, 720000),
77
+ _Checkpoint(1441690778, 730000),
78
+ _Checkpoint(1442300128, 740000),
79
+ _Checkpoint(1442902966, 750000),
80
+ _Checkpoint(1443510081, 760000),
81
+ _Checkpoint(1444120229, 770000),
82
+ _Checkpoint(1444725863, 780000),
83
+ _Checkpoint(1445334248, 790000),
84
+ _Checkpoint(1445938467, 800000),
85
+ _Checkpoint(1446548650, 810000),
86
+ _Checkpoint(1447157167, 820000),
87
+ _Checkpoint(1447766950, 830000),
88
+ _Checkpoint(1448375042, 840000),
89
+ _Checkpoint(1448982313, 850000),
90
+ _Checkpoint(1449591976, 860000),
91
+ _Checkpoint(1450206082, 870000),
92
+ _Checkpoint(1450817995, 880000),
93
+ _Checkpoint(1451431001, 890000),
94
+ _Checkpoint(1452044620, 900000),
95
+ _Checkpoint(1452654325, 910000),
96
+ _Checkpoint(1453271464, 920000),
97
+ _Checkpoint(1453874045, 930000),
98
+ _Checkpoint(1454490333, 940000),
99
+ _Checkpoint(1455096906, 950000),
100
+ _Checkpoint(1455704830, 960000),
101
+ _Checkpoint(1456315340, 970000),
102
+ _Checkpoint(1456926968, 980000),
103
+ _Checkpoint(1457536684, 990000),
104
+ _Checkpoint(1458145453, 1000000),
105
+ _Checkpoint(1458780543, 1010000),
106
+ _Checkpoint(1459961331, 1020000),
107
+ _Checkpoint(1461174469, 1030000),
108
+ _Checkpoint(1462375809, 1040000),
109
+ _Checkpoint(1463578591, 1050000),
110
+ _Checkpoint(1464785682, 1060000),
111
+ _Checkpoint(1465981307, 1070000),
112
+ _Checkpoint(1467185150, 1080000),
113
+ _Checkpoint(1468365704, 1090000),
114
+ _Checkpoint(1469573151, 1100000),
115
+ _Checkpoint(1470777161, 1110000),
116
+ _Checkpoint(1471975662, 1120000),
117
+ _Checkpoint(1473164186, 1130000),
118
+ _Checkpoint(1474374066, 1140000),
119
+ _Checkpoint(1475577458, 1150000),
120
+ _Checkpoint(1476776898, 1160000),
121
+ _Checkpoint(1477990372, 1170000),
122
+ _Checkpoint(1479187102, 1180000),
123
+ _Checkpoint(1480378008, 1190000),
124
+ _Checkpoint(1481575804, 1200000),
125
+ _Checkpoint(1482772399, 1210000),
126
+ _Checkpoint(1483965031, 1220000),
127
+ _Checkpoint(1485170094, 1230000),
128
+ _Checkpoint(1486369447, 1240000),
129
+ _Checkpoint(1487569956, 1250000),
130
+ _Checkpoint(1488775148, 1260000),
131
+ _Checkpoint(1489970122, 1270000),
132
+ _Checkpoint(1491168799, 1280000),
133
+ _Checkpoint(1492371569, 1290000),
134
+ _Checkpoint(1493568547, 1300000),
135
+ _Checkpoint(1494770503, 1310000),
136
+ _Checkpoint(1495965162, 1320000),
137
+ _Checkpoint(1497168519, 1330000),
138
+ _Checkpoint(1498361038, 1340000),
139
+ _Checkpoint(1499552117, 1350000),
140
+ _Checkpoint(1500747868, 1360000),
141
+ _Checkpoint(1501946180, 1370000),
142
+ _Checkpoint(1503149952, 1380000),
143
+ _Checkpoint(1504330700, 1390000),
144
+ _Checkpoint(1505525706, 1400000),
145
+ _Checkpoint(1506725266, 1410000),
146
+ _Checkpoint(1507924408, 1420000),
147
+ _Checkpoint(1509129536, 1430000),
148
+ _Checkpoint(1510332372, 1440000),
149
+ _Checkpoint(1511529796, 1450000),
150
+ _Checkpoint(1512713363, 1460000),
151
+ _Checkpoint(1513909535, 1470000),
152
+ _Checkpoint(1515100139, 1480000),
153
+ _Checkpoint(1516298977, 1490000),
154
+ _Checkpoint(1517489351, 1500000),
155
+ _Checkpoint(1518688093, 1510000),
156
+ _Checkpoint(1519885580, 1520000),
157
+ _Checkpoint(1521088410, 1530000),
158
+ _Checkpoint(1522289764, 1540000),
159
+ _Checkpoint(1523589333, 1550000),
160
+ _Checkpoint(1524783179, 1560000),
161
+ _Checkpoint(1525991638, 1570000),
162
+ _Checkpoint(1527194575, 1580000),
163
+ _Checkpoint(1528395704, 1590000),
164
+ _Checkpoint(1529603343, 1600000),
165
+ _Checkpoint(1530796888, 1610000),
166
+ _Checkpoint(1531995687, 1620000),
167
+ _Checkpoint(1533197982, 1630000),
168
+ _Checkpoint(1534403578, 1640000),
169
+ _Checkpoint(1535600184, 1650000),
170
+ _Checkpoint(1536793547, 1660000),
171
+ _Checkpoint(1537992755, 1670000),
172
+ _Checkpoint(1539198355, 1680000),
173
+ _Checkpoint(1540414062, 1690000),
174
+ _Checkpoint(1541612717, 1700000),
175
+ _Checkpoint(1542815406, 1710000),
176
+ _Checkpoint(1544019553, 1720000),
177
+ _Checkpoint(1545229810, 1730000),
178
+ _Checkpoint(1546431793, 1740000),
179
+ _Checkpoint(1547615007, 1750000),
180
+ _Checkpoint(1548812515, 1760000),
181
+ _Checkpoint(1549998027, 1770000),
182
+ _Checkpoint(1551198085, 1780000),
183
+ _Checkpoint(1552503513, 1790000),
184
+ _Checkpoint(1553698458, 1800000),
185
+ _Checkpoint(1554900519, 1810000),
186
+ _Checkpoint(1556102453, 1820000),
187
+ _Checkpoint(1557301054, 1830000),
188
+ _Checkpoint(1558508921, 1840000),
189
+ _Checkpoint(1559706132, 1850000),
190
+ _Checkpoint(1560908667, 1860000),
191
+ _Checkpoint(1562106679, 1870000),
192
+ _Checkpoint(1563311957, 1880000),
193
+ _Checkpoint(1564511944, 1890000),
194
+ _Checkpoint(1565709489, 1900000),
195
+ _Checkpoint(1566910782, 1910000),
196
+ _Checkpoint(1568109052, 1920000),
197
+ _Checkpoint(1569319349, 1930000),
198
+ _Checkpoint(1570518236, 1940000),
199
+ _Checkpoint(1571718656, 1950000),
200
+ _Checkpoint(1572919811, 1960000),
201
+ _Checkpoint(1574128184, 1970000),
202
+ _Checkpoint(1575292812, 1980000),
203
+ _Checkpoint(1576479575, 1990000),
204
+ _Checkpoint(1577680194, 2000000),
205
+ _Checkpoint(1578876107, 2010000),
206
+ _Checkpoint(1580075963, 2020000),
207
+ _Checkpoint(1581273916, 2030000),
208
+ _Checkpoint(1582472927, 2040000),
209
+ _Checkpoint(1583679893, 2050000),
210
+ _Checkpoint(1584883948, 2060000),
211
+ _Checkpoint(1586084634, 2070000),
212
+ _Checkpoint(1587287479, 2080000),
213
+ _Checkpoint(1588480325, 2090000),
214
+ _Checkpoint(1589683808, 2100000),
215
+ _Checkpoint(1590881378, 2110000),
216
+ _Checkpoint(1592087857, 2120000),
217
+ _Checkpoint(1593277684, 2130000),
218
+ _Checkpoint(1594490084, 2140000),
219
+ _Checkpoint(1595692597, 2150000),
220
+ _Checkpoint(1596887172, 2160000),
221
+ _Checkpoint(1598105106, 2170000),
222
+ _Checkpoint(1599306018, 2180000),
223
+ _Checkpoint(1600510218, 2190000),
224
+ _Checkpoint(1601703776, 2200000),
225
+ _Checkpoint(1602893696, 2210000),
226
+ _Checkpoint(1604112554, 2220000),
227
+ _Checkpoint(1605313298, 2230000),
228
+ _Checkpoint(1606513918, 2240000),
229
+ _Checkpoint(1607716100, 2250000),
230
+ _Checkpoint(1608912594, 2260000),
231
+ _Checkpoint(1610111416, 2270000),
232
+ _Checkpoint(1611312080, 2280000),
233
+ _Checkpoint(1612512703, 2290000),
234
+ _Checkpoint(1613707976, 2300000),
235
+ _Checkpoint(1614906615, 2310000),
236
+ _Checkpoint(1616110597, 2320000),
237
+ _Checkpoint(1617306552, 2330000),
238
+ _Checkpoint(1618511460, 2340000),
239
+ _Checkpoint(1619709663, 2350000),
240
+ _Checkpoint(1620910784, 2360000),
241
+ _Checkpoint(1622108971, 2370000),
242
+ _Checkpoint(1623312679, 2380000),
243
+ _Checkpoint(1624516914, 2390000),
244
+ _Checkpoint(1625715884, 2400000),
245
+ _Checkpoint(1626915471, 2410000),
246
+ _Checkpoint(1628116823, 2420000),
247
+ _Checkpoint(1629318052, 2430000),
248
+ _Checkpoint(1630517187, 2440000),
249
+ _Checkpoint(1631717800, 2450000),
250
+ _Checkpoint(1632918546, 2460000),
251
+ _Checkpoint(1634124541, 2470000),
252
+ _Checkpoint(1635324499, 2480000),
253
+ _Checkpoint(1636519414, 2490000),
254
+ _Checkpoint(1637720692, 2500000),
255
+ _Checkpoint(1638925683, 2510000),
256
+ _Checkpoint(1640127154, 2520000),
257
+ _Checkpoint(1641321384, 2530000),
258
+ _Checkpoint(1642524155, 2540000),
259
+ _Checkpoint(1643722767, 2550000),
260
+ _Checkpoint(1644923112, 2560000),
261
+ _Checkpoint(1646128603, 2570000),
262
+ _Checkpoint(1647331058, 2580000),
263
+ _Checkpoint(1648530154, 2590000),
264
+ _Checkpoint(1649731449, 2600000),
265
+ _Checkpoint(1650930600, 2610000),
266
+ _Checkpoint(1652137128, 2620000),
267
+ _Checkpoint(1653338800, 2630000),
268
+ _Checkpoint(1654539762, 2640000),
269
+ _Checkpoint(1655747917, 2650000),
270
+ _Checkpoint(1656945266, 2660000),
271
+ _Checkpoint(1658150587, 2670000),
272
+ _Checkpoint(1659349371, 2680000),
273
+ _Checkpoint(1660553735, 2690000),
274
+ _Checkpoint(1661752700, 2700000),
275
+ _Checkpoint(1662945664, 2710000),
276
+ _Checkpoint(1664150159, 2720000),
277
+ _Checkpoint(1665357200, 2730000),
278
+ _Checkpoint(1666557130, 2740000),
279
+ _Checkpoint(1667758004, 2750000),
280
+ _Checkpoint(1668963041, 2760000),
281
+ _Checkpoint(1670159857, 2770000),
282
+ _Checkpoint(1671366967, 2780000),
283
+ _Checkpoint(1672562400, 2790000),
284
+ _Checkpoint(1673769923, 2800000),
285
+ _Checkpoint(1674973607, 2810000),
286
+ _Checkpoint(1676162080, 2820000),
287
+ _Checkpoint(1677371812, 2830000),
288
+ _Checkpoint(1678576821, 2840000),
289
+ _Checkpoint(1679780527, 2850000),
290
+ _Checkpoint(1680978762, 2860000),
291
+ _Checkpoint(1682185252, 2870000),
292
+ _Checkpoint(1683386854, 2880000),
293
+ _Checkpoint(1684586627, 2890000),
294
+ _Checkpoint(1685787011, 2900000),
295
+ _Checkpoint(1686993944, 2910000),
296
+ _Checkpoint(1688196910, 2920000),
297
+ _Checkpoint(1689392833, 2930000),
298
+ _Checkpoint(1690593379, 2940000),
299
+ _Checkpoint(1691812920, 2950000),
300
+ _Checkpoint(1693013768, 2960000),
301
+ _Checkpoint(1694214345, 2970000),
302
+ _Checkpoint(1695411856, 2980000),
303
+ _Checkpoint(1696602209, 2990000),
304
+ _Checkpoint(1697813342, 3000000),
305
+ _Checkpoint(1699012649, 3010000),
306
+ _Checkpoint(1700219506, 3020000),
307
+ _Checkpoint(1701417489, 3030000),
308
+ _Checkpoint(1702620638, 3040000),
309
+ _Checkpoint(1703824734, 3050000),
310
+ _Checkpoint(1705022552, 3060000),
311
+ _Checkpoint(1706223184, 3070000),
312
+ _Checkpoint(1707426775, 3080000),
313
+ _Checkpoint(1708628612, 3090000),
314
+ _Checkpoint(1709832655, 3100000),
315
+ _Checkpoint(1711037724, 3110000),
316
+ _Checkpoint(1712236145, 3120000),
317
+ _Checkpoint(1713439631, 3130000),
318
+ _Checkpoint(1714640176, 3140000),
319
+ _Checkpoint(1715838106, 3150000),
320
+ _Checkpoint(1717027647, 3160000),
321
+ _Checkpoint(1718238665, 3170000),
322
+ _Checkpoint(1719430906, 3180000),
323
+ _Checkpoint(1720643178, 3190000),
324
+ _Checkpoint(1721843329, 3200000),
325
+ _Checkpoint(1723042527, 3210000),
326
+ _Checkpoint(1724242564, 3220000),
327
+ _Checkpoint(1725445200, 3230000),
328
+ _Checkpoint(1726636517, 3240000),
329
+ _Checkpoint(1727845671, 3250000),
330
+ _Checkpoint(1729039416, 3260000),
331
+ _Checkpoint(1730243700, 3270000),
332
+ _Checkpoint(1731448260, 3280000),
333
+ _Checkpoint(1732645674, 3290000),
334
+ _Checkpoint(1733848630, 3300000),
335
+ _Checkpoint(1735045564, 3310000),
336
+ _Checkpoint(1736247165, 3320000),
337
+ _Checkpoint(1737444468, 3330000),
338
+ _Checkpoint(1738643351, 3340000),
339
+ _Checkpoint(1739839603, 3350000),
340
+ _Checkpoint(1741046630, 3360000),
341
+ _Checkpoint(1742243178, 3370000),
342
+ _Checkpoint(1743442732, 3380000),
343
+ _Checkpoint(1744648072, 3390000),
344
+ _Checkpoint(1745849558, 3400000),
345
+ _Checkpoint(1747049310, 3410000),
346
+ _Checkpoint(1748238277, 3420000),
347
+ _Checkpoint(1749449164, 3430000),
348
+ _Checkpoint(1750652323, 3440000),
349
+ _Checkpoint(1751852432, 3450000),
350
+ _Checkpoint(1753046298, 3460000),
351
+ _Checkpoint(1754249974, 3470000),
352
+ _Checkpoint(1755455410, 3480000),
353
+ _Checkpoint(1756666863, 3490000),
354
+ _Checkpoint(1757868614, 3500000),
355
+ _Checkpoint(1759061269, 3510000),
356
+ _Checkpoint(1760271644, 3520000),
357
+ _Checkpoint(1761476806, 3530000),
358
+ _Checkpoint(1762672780, 3540000),
359
+ _Checkpoint(1763878670, 3550000),
360
+ _Checkpoint(1765074231, 3560000),
361
+ _Checkpoint(1766276987, 3570000),
362
+ _Checkpoint(1767477623, 3580000),
363
+ _Checkpoint(1768680288, 3590000),
364
+ _Checkpoint(1769885820, 3600000),
365
+ _Checkpoint(1771090287, 3610000),
366
+ _Checkpoint(1772293937, 3620000),
367
+ _Checkpoint(1773490619, 3630000),
368
+ _Checkpoint(1774693829, 3640000),
369
+ ];
370
+
371
+ static int getBlockHeightByTime(DateTime time) {
372
+ final t = time.toUtc().millisecondsSinceEpoch;
373
+
374
+ if (_points.isEmpty) return 0;
375
+
376
+ if (t <= _points.first.timeMs) {
377
+ return 1;
378
+ }
379
+
380
+ for (int i = 0; i < _points.length - 1; i++) {
381
+ final p0 = _points[i];
382
+ final p1 = _points[i + 1];
383
+
384
+ if (t >= p0.timeMs && t < p1.timeMs) {
385
+ return _interpolate(
386
+ p0.height,
387
+ p1.height,
388
+ p0.timeMs,
389
+ p1.timeMs,
390
+ t,
391
+ );
392
+ }
393
+ }
394
+
395
+ final last = _points[_points.length - 1];
396
+ final prev = _points[_points.length - 2];
397
+
398
+ final avgBlockTimeMs = (last.timeMs - prev.timeMs) / (last.height - prev.height);
399
+
400
+ final blocksSinceLast = ((t - last.timeMs) / avgBlockTimeMs).floor();
401
+
402
+ return last.height + blocksSinceLast;
403
+ }
404
+
405
+ static int _interpolate(
406
+ int h0,
407
+ int h1,
408
+ int t0,
409
+ int t1,
410
+ int t,
411
+ ) {
412
+ final ratio = (t - t0) / (t1 - t0);
413
+ return h0 + ((h1 - h0) * ratio).floor();
414
+ }
415
+}
416
+
417
+class _Checkpoint {
418
+ final int timeMs;
419
+ final int height;
420
+
421
+ _Checkpoint(int timeSec, this.height) : timeMs = timeSec * 1000;
422
+}