diff --git a/assets/images/info_icon.svg b/assets/images/info_icon.svg
new file mode 100644
index 000000000..31518cd17
--- /dev/null
+++ b/assets/images/info_icon.svg
@@ -0,0 +1,21 @@
+
+
+
+
\ No newline at end of file
diff --git a/cw_bitcoin/lib/bitcoin_address_record.dart b/cw_bitcoin/lib/bitcoin_address_record.dart
index 400e325be..d6de05051 100644
--- a/cw_bitcoin/lib/bitcoin_address_record.dart
+++ b/cw_bitcoin/lib/bitcoin_address_record.dart
@@ -54,6 +54,8 @@ abstract class BaseBitcoinAddressRecord {
BitcoinAddressType type;
+ String get derivationPath;
+
String toJSON();
}
@@ -118,6 +120,31 @@ class BitcoinAddressRecord extends BaseBitcoinAddressRecord {
String? scriptHash;
+ static int _purposeForType(BitcoinAddressType type) {
+ if (type == P2pkhAddressType.p2pkh) return 44;
+ if (type == P2shAddressType.p2wpkhInP2sh) return 49;
+ if (type == SegwitAddresType.p2wsh) return 48;
+ if (type == SegwitAddresType.p2tr) return 86;
+ return 84;
+ }
+
+ int _coinTypeForNetwork() {
+ if (!(network?.isMainnet ?? true)) return 1;
+
+ switch (network) {
+ case BitcoinNetwork.mainnet:
+ return 0;
+ case LitecoinNetwork.mainnet:
+ return 2;
+ case BitcoinCashNetwork.mainnet:
+ return 145;
+ case DogecoinNetwork.mainnet:
+ return 3;
+ default:
+ return 0;
+ }
+ }
+
String getScriptHash(BasedUtxoNetwork network) {
if (scriptHash != null) return scriptHash!;
try {
@@ -127,6 +154,21 @@ class BitcoinAddressRecord extends BaseBitcoinAddressRecord {
}
return scriptHash!;
}
+ @override
+ String get derivationPath {
+ if (type == SegwitAddresType.mweb) {
+ return "m/1000'/$index";
+ }
+
+ final coinType = _coinTypeForNetwork();
+ final purpose = _purposeForType(type);
+ final accountPath = isLegacyDerivation
+ ? electrum_path
+ : "m/$purpose'/$coinType'/0'";
+
+ final chain = isHidden ? 1 : 0;
+ return "$accountPath/$chain/$index";
+ }
@override
String toJSON() => json.encode({
@@ -186,6 +228,9 @@ class BitcoinSilentPaymentAddressRecord extends BaseBitcoinAddressRecord {
final String? silentPaymentTweak;
final String spendDerivationPath;
+ @override
+ String get derivationPath => spendDerivationPath;
+
@override
String toJSON() => json.encode({
'address': address,
diff --git a/cw_core/lib/get_height_by_date.dart b/cw_core/lib/get_height_by_date.dart
index 4786336af..58155a7fb 100644
--- a/cw_core/lib/get_height_by_date.dart
+++ b/cw_core/lib/get_height_by_date.dart
@@ -1,163 +1,12 @@
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:intl/intl.dart';
+import 'package:cw_core/get_height_by_date_xmr.dart';
import 'dart:convert';
// FIXME: Hardcoded values; Works only for monero
-final dateFormat = DateFormat('yyyy-MM');
-final dates = {
- "2014-5": 18844,
- "2014-6": 65406,
- "2014-7": 108882,
- "2014-8": 153594,
- "2014-9": 198072,
- "2014-10": 241088,
- "2014-11": 285305,
- "2014-12": 328069,
- "2015-1": 372369,
- "2015-2": 416505,
- "2015-3": 456631,
- "2015-4": 501084,
- "2015-5": 543973,
- "2015-6": 588326,
- "2015-7": 631187,
- "2015-8": 675484,
- "2015-9": 719725,
- "2015-10": 762463,
- "2015-11": 806528,
- "2015-12": 849041,
- "2016-1": 892866,
- "2016-2": 936736,
- "2016-3": 977691,
- "2016-4": 1015848,
- "2016-5": 1037417,
- "2016-6": 1059651,
- "2016-7": 1081269,
- "2016-8": 1103630,
- "2016-9": 1125983,
- "2016-10": 1147617,
- "2016-11": 1169779,
- "2016-12": 1191402,
- "2017-1": 1213861,
- "2017-2": 1236197,
- "2017-3": 1256358,
- "2017-4": 1278622,
- "2017-5": 1300239,
- "2017-6": 1322564,
- "2017-7": 1344225,
- "2017-8": 1366664,
- "2017-9": 1389113,
- "2017-10": 1410738,
- "2017-11": 1433039,
- "2017-12": 1454639,
- "2018-1": 1477201,
- "2018-2": 1499599,
- "2018-3": 1519796,
- "2018-4": 1542067,
- "2018-5": 1562861,
- "2018-6": 1585135,
- "2018-7": 1606715,
- "2018-8": 1629017,
- "2018-9": 1651347,
- "2018-10": 1673031,
- "2018-11": 1695128,
- "2018-12": 1716687,
- "2019-1": 1738923,
- "2019-2": 1761435,
- "2019-3": 1781681,
- "2019-4": 1803081,
- "2019-5": 1824671,
- "2019-6": 1847005,
- "2019-7": 1868590,
- "2019-8": 1890552,
- "2019-9": 1912212,
- "2019-10": 1932200,
- "2019-11": 1957040,
- "2019-12": 1978090,
- "2020-1": 2001290,
- "2020-2": 2022688,
- "2020-3": 2043987,
- "2020-4": 2066536,
- "2020-5": 2090797,
- "2020-6": 2111633,
- "2020-7": 2131433,
- "2020-8": 2153983,
- "2020-9": 2176466,
- "2020-10": 2198453,
- "2020-11": 2220000,
- "2020-12": 2242240,
- "2021-1": 2264584,
- "2021-2": 2286892,
- "2021-3": 2307079,
- "2021-4": 2329385,
- "2021-5": 2351004,
- "2021-6": 2373306,
- "2021-7": 2394882,
- "2021-8": 2417162,
- "2021-9": 2439490,
- "2021-10": 2461020,
- "2021-11": 2483377,
- "2021-12": 2504932,
- "2022-1": 2527316,
- "2022-2": 2549605,
- "2022-3": 2569711,
- "2022-4": 2591995,
- "2022-5": 2613603,
- "2022-6": 2635840,
- "2022-7": 2657395,
- "2022-8": 2679705,
- "2022-9": 2701991,
- "2022-10": 2723607,
- "2022-11": 2745899,
- "2022-12": 2767427,
- "2023-1": 2789763,
- "2023-2": 2811996,
- "2023-3": 2832118,
- "2023-4": 2854365,
- "2023-5": 2875972,
- "2023-6": 2898234,
- "2023-7": 2919771,
- "2023-8": 2942045,
- "2023-9": 2964280,
- "2023-10": 2985937,
- "2023-11": 3008178,
- "2023-12": 3029759
-};
-
-int getMoneroHeigthByDate({required DateTime date}) {
- final raw = '${date.year}' + '-' + '${date.month}';
- final lastHeight = dates.values.last;
- int startHeight;
- int endHeight;
- int height = 0;
-
- try {
- if ((dates[raw] == null) || (dates[raw] == lastHeight)) {
- startHeight = dates.values.toList()[dates.length - 2];
- endHeight = dates.values.toList()[dates.length - 1];
- final heightPerDay = (endHeight - startHeight) / 31;
- final endDateRaw = dates.keys.toList()[dates.length - 1].split('-');
- final endYear = int.parse(endDateRaw[0]);
- final endMonth = int.parse(endDateRaw[1]);
- final endDate = DateTime(endYear, endMonth);
- final differenceInDays = date.difference(endDate).inDays;
- final daysHeight = (differenceInDays * heightPerDay).round();
- height = endHeight + daysHeight;
- } else {
- startHeight = dates[raw]!;
- final index = dates.values.toList().indexOf(startHeight);
- endHeight = dates.values.toList()[index + 1];
- final heightPerDay = ((endHeight - startHeight) / 31).round();
- final daysHeight = (date.day - 1) * heightPerDay;
- height = startHeight + daysHeight - heightPerDay;
- }
- } catch (e) {
- printV(e.toString());
- }
-
- return height;
-}
+int getMoneroHeigthByDate({required DateTime date}) => MoneroHeight.getBlockHeightByTime(date..subtract(Duration(days: 1)));
const havenDates = {
"2023-05": 1352995,
@@ -223,6 +72,7 @@ const havenDates = {
"2018-04": 32000,
"2018-03": 8500
};
+final dateFormat = DateFormat('yyyy-MM');
DateTime formatMapKey(String key) => dateFormat.parse(key);
@@ -234,9 +84,10 @@ int getHavenHeightByDate({required DateTime date}) {
}
Future getHavenCurrentHeight() async {
- final req = await ProxyWrapper().getHttpClient()
- .getUrl(Uri.parse('https://explorer.havenprotocol.org/api/networkinfo'))
- .timeout(Duration(seconds: 15));
+ final req = await ProxyWrapper()
+ .getHttpClient()
+ .getUrl(Uri.parse('https://explorer.havenprotocol.org/api/networkinfo'))
+ .timeout(Duration(seconds: 15));
final response = await req.close();
final stringResponse = await response.transform(utf8.decoder).join();
@@ -273,9 +124,11 @@ const bitcoinDates = {
};
Future getBitcoinHeightByDateAPI({required DateTime date}) async {
- final req = await ProxyWrapper().getHttpClient()
- .getUrl(Uri.parse("https://mempool.cakewallet.com/api/v1/mining/blocks/timestamp/${(date.millisecondsSinceEpoch / 1000).round()}"))
- .timeout(Duration(seconds: 15));
+ final req = await ProxyWrapper()
+ .getHttpClient()
+ .getUrl(Uri.parse(
+ "https://mempool.cakewallet.com/api/v1/mining/blocks/timestamp/${(date.millisecondsSinceEpoch / 1000).round()}"))
+ .timeout(Duration(seconds: 15));
final response = await req.close();
final stringResponse = await response.transform(utf8.decoder).join();
diff --git a/cw_core/lib/get_height_by_date_xmr.dart b/cw_core/lib/get_height_by_date_xmr.dart
new file mode 100644
index 000000000..16a1b2002
--- /dev/null
+++ b/cw_core/lib/get_height_by_date_xmr.dart
@@ -0,0 +1,422 @@
+
+class MoneroHeight {
+ // 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
+ static final List<_Checkpoint> _points = [
+ _Checkpoint(1398386790, 10000),
+ _Checkpoint(1398970097, 20000),
+ _Checkpoint(1399529049, 30000),
+ _Checkpoint(1400107914, 40000),
+ _Checkpoint(1400673084, 50000),
+ _Checkpoint(1401259431, 60000),
+ _Checkpoint(1401861514, 70000),
+ _Checkpoint(1402455081, 80000),
+ _Checkpoint(1403051337, 90000),
+ _Checkpoint(1403639801, 100000),
+ _Checkpoint(1404238831, 110000),
+ _Checkpoint(1404841666, 120000),
+ _Checkpoint(1405444927, 130000),
+ _Checkpoint(1406035044, 140000),
+ _Checkpoint(1406634825, 150000),
+ _Checkpoint(1407238604, 160000),
+ _Checkpoint(1407838442, 170000),
+ _Checkpoint(1408443936, 180000),
+ _Checkpoint(1409041095, 190000),
+ _Checkpoint(1409644412, 200000),
+ _Checkpoint(1410247699, 210000),
+ _Checkpoint(1410851018, 220000),
+ _Checkpoint(1411455976, 230000),
+ _Checkpoint(1412059180, 240000),
+ _Checkpoint(1412661506, 250000),
+ _Checkpoint(1413267445, 260000),
+ _Checkpoint(1413873271, 270000),
+ _Checkpoint(1414480925, 280000),
+ _Checkpoint(1415086077, 290000),
+ _Checkpoint(1415690591, 300000),
+ _Checkpoint(1416296909, 310000),
+ _Checkpoint(1416902704, 320000),
+ _Checkpoint(1417507901, 330000),
+ _Checkpoint(1418109054, 340000),
+ _Checkpoint(1418722232, 350000),
+ _Checkpoint(1419326271, 360000),
+ _Checkpoint(1419928389, 370000),
+ _Checkpoint(1420541216, 380000),
+ _Checkpoint(1421145579, 390000),
+ _Checkpoint(1421749732, 400000),
+ _Checkpoint(1422354623, 410000),
+ _Checkpoint(1422956207, 420000),
+ _Checkpoint(1423562393, 430000),
+ _Checkpoint(1424166115, 440000),
+ _Checkpoint(1424767351, 450000),
+ _Checkpoint(1425371690, 460000),
+ _Checkpoint(1425975620, 470000),
+ _Checkpoint(1426579077, 480000),
+ _Checkpoint(1427182546, 490000),
+ _Checkpoint(1427785048, 500000),
+ _Checkpoint(1428385900, 510000),
+ _Checkpoint(1428990297, 520000),
+ _Checkpoint(1429593770, 530000),
+ _Checkpoint(1430197340, 540000),
+ _Checkpoint(1430803986, 550000),
+ _Checkpoint(1431408119, 560000),
+ _Checkpoint(1432011390, 570000),
+ _Checkpoint(1432613317, 580000),
+ _Checkpoint(1433222583, 590000),
+ _Checkpoint(1433825715, 600000),
+ _Checkpoint(1434431094, 610000),
+ _Checkpoint(1435033265, 620000),
+ _Checkpoint(1435636924, 630000),
+ _Checkpoint(1436243604, 640000),
+ _Checkpoint(1436848163, 650000),
+ _Checkpoint(1437455928, 660000),
+ _Checkpoint(1438056769, 670000),
+ _Checkpoint(1438662194, 680000),
+ _Checkpoint(1439267688, 690000),
+ _Checkpoint(1439872751, 700000),
+ _Checkpoint(1440479855, 710000),
+ _Checkpoint(1441084930, 720000),
+ _Checkpoint(1441690778, 730000),
+ _Checkpoint(1442300128, 740000),
+ _Checkpoint(1442902966, 750000),
+ _Checkpoint(1443510081, 760000),
+ _Checkpoint(1444120229, 770000),
+ _Checkpoint(1444725863, 780000),
+ _Checkpoint(1445334248, 790000),
+ _Checkpoint(1445938467, 800000),
+ _Checkpoint(1446548650, 810000),
+ _Checkpoint(1447157167, 820000),
+ _Checkpoint(1447766950, 830000),
+ _Checkpoint(1448375042, 840000),
+ _Checkpoint(1448982313, 850000),
+ _Checkpoint(1449591976, 860000),
+ _Checkpoint(1450206082, 870000),
+ _Checkpoint(1450817995, 880000),
+ _Checkpoint(1451431001, 890000),
+ _Checkpoint(1452044620, 900000),
+ _Checkpoint(1452654325, 910000),
+ _Checkpoint(1453271464, 920000),
+ _Checkpoint(1453874045, 930000),
+ _Checkpoint(1454490333, 940000),
+ _Checkpoint(1455096906, 950000),
+ _Checkpoint(1455704830, 960000),
+ _Checkpoint(1456315340, 970000),
+ _Checkpoint(1456926968, 980000),
+ _Checkpoint(1457536684, 990000),
+ _Checkpoint(1458145453, 1000000),
+ _Checkpoint(1458780543, 1010000),
+ _Checkpoint(1459961331, 1020000),
+ _Checkpoint(1461174469, 1030000),
+ _Checkpoint(1462375809, 1040000),
+ _Checkpoint(1463578591, 1050000),
+ _Checkpoint(1464785682, 1060000),
+ _Checkpoint(1465981307, 1070000),
+ _Checkpoint(1467185150, 1080000),
+ _Checkpoint(1468365704, 1090000),
+ _Checkpoint(1469573151, 1100000),
+ _Checkpoint(1470777161, 1110000),
+ _Checkpoint(1471975662, 1120000),
+ _Checkpoint(1473164186, 1130000),
+ _Checkpoint(1474374066, 1140000),
+ _Checkpoint(1475577458, 1150000),
+ _Checkpoint(1476776898, 1160000),
+ _Checkpoint(1477990372, 1170000),
+ _Checkpoint(1479187102, 1180000),
+ _Checkpoint(1480378008, 1190000),
+ _Checkpoint(1481575804, 1200000),
+ _Checkpoint(1482772399, 1210000),
+ _Checkpoint(1483965031, 1220000),
+ _Checkpoint(1485170094, 1230000),
+ _Checkpoint(1486369447, 1240000),
+ _Checkpoint(1487569956, 1250000),
+ _Checkpoint(1488775148, 1260000),
+ _Checkpoint(1489970122, 1270000),
+ _Checkpoint(1491168799, 1280000),
+ _Checkpoint(1492371569, 1290000),
+ _Checkpoint(1493568547, 1300000),
+ _Checkpoint(1494770503, 1310000),
+ _Checkpoint(1495965162, 1320000),
+ _Checkpoint(1497168519, 1330000),
+ _Checkpoint(1498361038, 1340000),
+ _Checkpoint(1499552117, 1350000),
+ _Checkpoint(1500747868, 1360000),
+ _Checkpoint(1501946180, 1370000),
+ _Checkpoint(1503149952, 1380000),
+ _Checkpoint(1504330700, 1390000),
+ _Checkpoint(1505525706, 1400000),
+ _Checkpoint(1506725266, 1410000),
+ _Checkpoint(1507924408, 1420000),
+ _Checkpoint(1509129536, 1430000),
+ _Checkpoint(1510332372, 1440000),
+ _Checkpoint(1511529796, 1450000),
+ _Checkpoint(1512713363, 1460000),
+ _Checkpoint(1513909535, 1470000),
+ _Checkpoint(1515100139, 1480000),
+ _Checkpoint(1516298977, 1490000),
+ _Checkpoint(1517489351, 1500000),
+ _Checkpoint(1518688093, 1510000),
+ _Checkpoint(1519885580, 1520000),
+ _Checkpoint(1521088410, 1530000),
+ _Checkpoint(1522289764, 1540000),
+ _Checkpoint(1523589333, 1550000),
+ _Checkpoint(1524783179, 1560000),
+ _Checkpoint(1525991638, 1570000),
+ _Checkpoint(1527194575, 1580000),
+ _Checkpoint(1528395704, 1590000),
+ _Checkpoint(1529603343, 1600000),
+ _Checkpoint(1530796888, 1610000),
+ _Checkpoint(1531995687, 1620000),
+ _Checkpoint(1533197982, 1630000),
+ _Checkpoint(1534403578, 1640000),
+ _Checkpoint(1535600184, 1650000),
+ _Checkpoint(1536793547, 1660000),
+ _Checkpoint(1537992755, 1670000),
+ _Checkpoint(1539198355, 1680000),
+ _Checkpoint(1540414062, 1690000),
+ _Checkpoint(1541612717, 1700000),
+ _Checkpoint(1542815406, 1710000),
+ _Checkpoint(1544019553, 1720000),
+ _Checkpoint(1545229810, 1730000),
+ _Checkpoint(1546431793, 1740000),
+ _Checkpoint(1547615007, 1750000),
+ _Checkpoint(1548812515, 1760000),
+ _Checkpoint(1549998027, 1770000),
+ _Checkpoint(1551198085, 1780000),
+ _Checkpoint(1552503513, 1790000),
+ _Checkpoint(1553698458, 1800000),
+ _Checkpoint(1554900519, 1810000),
+ _Checkpoint(1556102453, 1820000),
+ _Checkpoint(1557301054, 1830000),
+ _Checkpoint(1558508921, 1840000),
+ _Checkpoint(1559706132, 1850000),
+ _Checkpoint(1560908667, 1860000),
+ _Checkpoint(1562106679, 1870000),
+ _Checkpoint(1563311957, 1880000),
+ _Checkpoint(1564511944, 1890000),
+ _Checkpoint(1565709489, 1900000),
+ _Checkpoint(1566910782, 1910000),
+ _Checkpoint(1568109052, 1920000),
+ _Checkpoint(1569319349, 1930000),
+ _Checkpoint(1570518236, 1940000),
+ _Checkpoint(1571718656, 1950000),
+ _Checkpoint(1572919811, 1960000),
+ _Checkpoint(1574128184, 1970000),
+ _Checkpoint(1575292812, 1980000),
+ _Checkpoint(1576479575, 1990000),
+ _Checkpoint(1577680194, 2000000),
+ _Checkpoint(1578876107, 2010000),
+ _Checkpoint(1580075963, 2020000),
+ _Checkpoint(1581273916, 2030000),
+ _Checkpoint(1582472927, 2040000),
+ _Checkpoint(1583679893, 2050000),
+ _Checkpoint(1584883948, 2060000),
+ _Checkpoint(1586084634, 2070000),
+ _Checkpoint(1587287479, 2080000),
+ _Checkpoint(1588480325, 2090000),
+ _Checkpoint(1589683808, 2100000),
+ _Checkpoint(1590881378, 2110000),
+ _Checkpoint(1592087857, 2120000),
+ _Checkpoint(1593277684, 2130000),
+ _Checkpoint(1594490084, 2140000),
+ _Checkpoint(1595692597, 2150000),
+ _Checkpoint(1596887172, 2160000),
+ _Checkpoint(1598105106, 2170000),
+ _Checkpoint(1599306018, 2180000),
+ _Checkpoint(1600510218, 2190000),
+ _Checkpoint(1601703776, 2200000),
+ _Checkpoint(1602893696, 2210000),
+ _Checkpoint(1604112554, 2220000),
+ _Checkpoint(1605313298, 2230000),
+ _Checkpoint(1606513918, 2240000),
+ _Checkpoint(1607716100, 2250000),
+ _Checkpoint(1608912594, 2260000),
+ _Checkpoint(1610111416, 2270000),
+ _Checkpoint(1611312080, 2280000),
+ _Checkpoint(1612512703, 2290000),
+ _Checkpoint(1613707976, 2300000),
+ _Checkpoint(1614906615, 2310000),
+ _Checkpoint(1616110597, 2320000),
+ _Checkpoint(1617306552, 2330000),
+ _Checkpoint(1618511460, 2340000),
+ _Checkpoint(1619709663, 2350000),
+ _Checkpoint(1620910784, 2360000),
+ _Checkpoint(1622108971, 2370000),
+ _Checkpoint(1623312679, 2380000),
+ _Checkpoint(1624516914, 2390000),
+ _Checkpoint(1625715884, 2400000),
+ _Checkpoint(1626915471, 2410000),
+ _Checkpoint(1628116823, 2420000),
+ _Checkpoint(1629318052, 2430000),
+ _Checkpoint(1630517187, 2440000),
+ _Checkpoint(1631717800, 2450000),
+ _Checkpoint(1632918546, 2460000),
+ _Checkpoint(1634124541, 2470000),
+ _Checkpoint(1635324499, 2480000),
+ _Checkpoint(1636519414, 2490000),
+ _Checkpoint(1637720692, 2500000),
+ _Checkpoint(1638925683, 2510000),
+ _Checkpoint(1640127154, 2520000),
+ _Checkpoint(1641321384, 2530000),
+ _Checkpoint(1642524155, 2540000),
+ _Checkpoint(1643722767, 2550000),
+ _Checkpoint(1644923112, 2560000),
+ _Checkpoint(1646128603, 2570000),
+ _Checkpoint(1647331058, 2580000),
+ _Checkpoint(1648530154, 2590000),
+ _Checkpoint(1649731449, 2600000),
+ _Checkpoint(1650930600, 2610000),
+ _Checkpoint(1652137128, 2620000),
+ _Checkpoint(1653338800, 2630000),
+ _Checkpoint(1654539762, 2640000),
+ _Checkpoint(1655747917, 2650000),
+ _Checkpoint(1656945266, 2660000),
+ _Checkpoint(1658150587, 2670000),
+ _Checkpoint(1659349371, 2680000),
+ _Checkpoint(1660553735, 2690000),
+ _Checkpoint(1661752700, 2700000),
+ _Checkpoint(1662945664, 2710000),
+ _Checkpoint(1664150159, 2720000),
+ _Checkpoint(1665357200, 2730000),
+ _Checkpoint(1666557130, 2740000),
+ _Checkpoint(1667758004, 2750000),
+ _Checkpoint(1668963041, 2760000),
+ _Checkpoint(1670159857, 2770000),
+ _Checkpoint(1671366967, 2780000),
+ _Checkpoint(1672562400, 2790000),
+ _Checkpoint(1673769923, 2800000),
+ _Checkpoint(1674973607, 2810000),
+ _Checkpoint(1676162080, 2820000),
+ _Checkpoint(1677371812, 2830000),
+ _Checkpoint(1678576821, 2840000),
+ _Checkpoint(1679780527, 2850000),
+ _Checkpoint(1680978762, 2860000),
+ _Checkpoint(1682185252, 2870000),
+ _Checkpoint(1683386854, 2880000),
+ _Checkpoint(1684586627, 2890000),
+ _Checkpoint(1685787011, 2900000),
+ _Checkpoint(1686993944, 2910000),
+ _Checkpoint(1688196910, 2920000),
+ _Checkpoint(1689392833, 2930000),
+ _Checkpoint(1690593379, 2940000),
+ _Checkpoint(1691812920, 2950000),
+ _Checkpoint(1693013768, 2960000),
+ _Checkpoint(1694214345, 2970000),
+ _Checkpoint(1695411856, 2980000),
+ _Checkpoint(1696602209, 2990000),
+ _Checkpoint(1697813342, 3000000),
+ _Checkpoint(1699012649, 3010000),
+ _Checkpoint(1700219506, 3020000),
+ _Checkpoint(1701417489, 3030000),
+ _Checkpoint(1702620638, 3040000),
+ _Checkpoint(1703824734, 3050000),
+ _Checkpoint(1705022552, 3060000),
+ _Checkpoint(1706223184, 3070000),
+ _Checkpoint(1707426775, 3080000),
+ _Checkpoint(1708628612, 3090000),
+ _Checkpoint(1709832655, 3100000),
+ _Checkpoint(1711037724, 3110000),
+ _Checkpoint(1712236145, 3120000),
+ _Checkpoint(1713439631, 3130000),
+ _Checkpoint(1714640176, 3140000),
+ _Checkpoint(1715838106, 3150000),
+ _Checkpoint(1717027647, 3160000),
+ _Checkpoint(1718238665, 3170000),
+ _Checkpoint(1719430906, 3180000),
+ _Checkpoint(1720643178, 3190000),
+ _Checkpoint(1721843329, 3200000),
+ _Checkpoint(1723042527, 3210000),
+ _Checkpoint(1724242564, 3220000),
+ _Checkpoint(1725445200, 3230000),
+ _Checkpoint(1726636517, 3240000),
+ _Checkpoint(1727845671, 3250000),
+ _Checkpoint(1729039416, 3260000),
+ _Checkpoint(1730243700, 3270000),
+ _Checkpoint(1731448260, 3280000),
+ _Checkpoint(1732645674, 3290000),
+ _Checkpoint(1733848630, 3300000),
+ _Checkpoint(1735045564, 3310000),
+ _Checkpoint(1736247165, 3320000),
+ _Checkpoint(1737444468, 3330000),
+ _Checkpoint(1738643351, 3340000),
+ _Checkpoint(1739839603, 3350000),
+ _Checkpoint(1741046630, 3360000),
+ _Checkpoint(1742243178, 3370000),
+ _Checkpoint(1743442732, 3380000),
+ _Checkpoint(1744648072, 3390000),
+ _Checkpoint(1745849558, 3400000),
+ _Checkpoint(1747049310, 3410000),
+ _Checkpoint(1748238277, 3420000),
+ _Checkpoint(1749449164, 3430000),
+ _Checkpoint(1750652323, 3440000),
+ _Checkpoint(1751852432, 3450000),
+ _Checkpoint(1753046298, 3460000),
+ _Checkpoint(1754249974, 3470000),
+ _Checkpoint(1755455410, 3480000),
+ _Checkpoint(1756666863, 3490000),
+ _Checkpoint(1757868614, 3500000),
+ _Checkpoint(1759061269, 3510000),
+ _Checkpoint(1760271644, 3520000),
+ _Checkpoint(1761476806, 3530000),
+ _Checkpoint(1762672780, 3540000),
+ _Checkpoint(1763878670, 3550000),
+ _Checkpoint(1765074231, 3560000),
+ _Checkpoint(1766276987, 3570000),
+ _Checkpoint(1767477623, 3580000),
+ _Checkpoint(1768680288, 3590000),
+ _Checkpoint(1769885820, 3600000),
+ _Checkpoint(1771090287, 3610000),
+ _Checkpoint(1772293937, 3620000),
+ _Checkpoint(1773490619, 3630000),
+ _Checkpoint(1774693829, 3640000),
+ ];
+
+ static int getBlockHeightByTime(DateTime time) {
+ final t = time.toUtc().millisecondsSinceEpoch;
+
+ if (_points.isEmpty) return 0;
+
+ if (t <= _points.first.timeMs) {
+ return 1;
+ }
+
+ for (int i = 0; i < _points.length - 1; i++) {
+ final p0 = _points[i];
+ final p1 = _points[i + 1];
+
+ if (t >= p0.timeMs && t < p1.timeMs) {
+ return _interpolate(
+ p0.height,
+ p1.height,
+ p0.timeMs,
+ p1.timeMs,
+ t,
+ );
+ }
+ }
+
+ final last = _points[_points.length - 1];
+ final prev = _points[_points.length - 2];
+
+ final avgBlockTimeMs = (last.timeMs - prev.timeMs) / (last.height - prev.height);
+
+ final blocksSinceLast = ((t - last.timeMs) / avgBlockTimeMs).floor();
+
+ return last.height + blocksSinceLast;
+ }
+
+ static int _interpolate(
+ int h0,
+ int h1,
+ int t0,
+ int t1,
+ int t,
+ ) {
+ final ratio = (t - t0) / (t1 - t0);
+ return h0 + ((h1 - h0) * ratio).floor();
+ }
+}
+
+class _Checkpoint {
+ final int timeMs;
+ final int height;
+
+ _Checkpoint(int timeSec, this.height) : timeMs = timeSec * 1000;
+}
diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart
index 62db2a63e..6f5b9bfa4 100644
--- a/lib/bitcoin/cw_bitcoin.dart
+++ b/lib/bitcoin/cw_bitcoin.dart
@@ -185,7 +185,8 @@ class CWBitcoin extends Bitcoin {
txCount: addr.txCount,
balance: addr.balance,
isChange: addr.isHidden,
- isLegacyDerivation: addr.isLegacyDerivation))
+ isLegacyDerivation: addr.isLegacyDerivation,
+ derivationPath: addr.derivationPath))
.toList();
}
@@ -574,7 +575,8 @@ class CWBitcoin extends Bitcoin {
address: addr.address,
txCount: addr.txCount,
balance: addr.balance,
- isChange: addr.isHidden))
+ isChange: addr.isHidden,
+ derivationPath: addr.derivationPath))
.toList();
}
@@ -589,7 +591,8 @@ class CWBitcoin extends Bitcoin {
address: addr.address,
txCount: addr.txCount,
balance: addr.balance,
- isChange: addr.isHidden))
+ isChange: addr.isHidden,
+ derivationPath: addr.derivationPath))
.toList();
}
diff --git a/lib/di.dart b/lib/di.dart
index 715c88660..7a8a8185a 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -310,6 +310,7 @@ import 'buy/kryptonim/kryptonim.dart';
import 'buy/meld/meld_buy_provider.dart';
import 'dogecoin/dogecoin.dart';
import 'new-ui/viewmodels/card_customizer/card_customizer_bloc.dart';
+import 'new-ui/widgets/addresses_page/address_info.dart';
import 'src/screens/buy/buy_sell_page.dart';
final getIt = GetIt.instance;
@@ -880,6 +881,11 @@ Future setup({
walletAddressEditOrCreateViewModel:
getIt.get(param1: item)));
+ getIt.registerFactoryParam((dynamic item, _) =>
+ AddressInfoPopup(
+ walletAddressEditOrCreateViewModel:
+ getIt.get(param1: item)));
+
getIt.registerFactoryParam((dynamic item, _) =>
ReceiveLabelModal(
walletAddressEditOrCreateViewModel:
diff --git a/lib/entities/new_ui_entities/list_item/list_item_regular_row.dart b/lib/entities/new_ui_entities/list_item/list_item_regular_row.dart
index a9ef260d0..f6df44a25 100644
--- a/lib/entities/new_ui_entities/list_item/list_item_regular_row.dart
+++ b/lib/entities/new_ui_entities/list_item/list_item_regular_row.dart
@@ -15,13 +15,15 @@ class ListItemRegularRow extends ListItem {
this.trailingWidget,
this.truncateTrailingText = false,
this.foregroundColor,
- this.trailingIconSize
+ this.trailingIconSize,
+ this.copyableText
});
final String? subtitle;
final String? trailingText;
final String? iconPath;
final String? trailingIconPath;
+ final String? copyableText;
final VoidCallback? onTap;
final bool showArrow;
final Widget? bottomWidget;
diff --git a/lib/new-ui/pages/addresses_page.dart b/lib/new-ui/pages/addresses_page.dart
index a7a81d282..9016116d0 100644
--- a/lib/new-ui/pages/addresses_page.dart
+++ b/lib/new-ui/pages/addresses_page.dart
@@ -4,6 +4,7 @@ import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/new-ui/long_press_popup.dart';
+import 'package:cake_wallet/new-ui/widgets/addresses_page/address_info.dart';
import 'package:cake_wallet/new-ui/widgets/addresses_page/address_label_input.dart';
import 'package:cake_wallet/new-ui/widgets/coins_page/cards/balance_card.dart';
import 'package:cake_wallet/new-ui/widgets/long_press_menu.dart';
@@ -355,6 +356,15 @@ class AddressRow extends StatelessWidget {
onAddressHidden();
},
color: Theme.of(context).colorScheme.error),
+ LongPressMenuItem(
+ label: 'Info',
+ iconPath: "assets/images/info_icon.svg",
+ onSelected: () async {
+ Navigator.of(context, rootNavigator: true).pop();
+ await showPopUp(
+ context: context,
+ builder: (context) => getIt.get(param1: item));
+ }),
],
),
child: AnimatedContainer(
diff --git a/lib/new-ui/widgets/addresses_page/address_info.dart b/lib/new-ui/widgets/addresses_page/address_info.dart
new file mode 100644
index 000000000..310b3d4e4
--- /dev/null
+++ b/lib/new-ui/widgets/addresses_page/address_info.dart
@@ -0,0 +1,46 @@
+import 'dart:ui';
+
+import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart';
+import 'package:flutter/material.dart';
+
+class AddressInfoPopup extends StatelessWidget {
+ const AddressInfoPopup({
+ super.key,
+ required this.walletAddressEditOrCreateViewModel,
+ });
+
+ final WalletAddressEditOrCreateViewModel walletAddressEditOrCreateViewModel;
+
+ @override
+ Widget build(BuildContext context) {
+ return BackdropFilter(
+ filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
+ child: Column(
+ mainAxisSize: MainAxisSize.max,
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ children: [
+ Container(
+ decoration: BoxDecoration(
+ color: Theme.of(context).colorScheme.surfaceContainerHigh,
+ borderRadius: BorderRadiusGeometry.lerp(
+ BorderRadius.circular(12),
+ BorderRadius.circular(24),
+ 0.5,
+ ),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Column(
+ children: [
+ Text('Index: ${walletAddressEditOrCreateViewModel.index}'),
+ SizedBox(height: 16),
+ Text(
+ 'Derivation Path: ${walletAddressEditOrCreateViewModel.derivationPath}'),
+ ],
+ ),
+ ),
+ ),
+ ]),
+ );
+ }
+}
diff --git a/lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart b/lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart
index 079b008c8..f7e6c952f 100644
--- a/lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart
+++ b/lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart
@@ -99,10 +99,7 @@ class _TransactionDetailsModalState extends State {
item.value.length > 25;
return ListItemRegularRow(
- onTap: () {
- Clipboard.setData(
- ClipboardData(text: item.value));
- },
+ copyableText: item.value,
showArrow: false,
keyValue:
((item.key as ValueKey?)?.value as String?) ??
@@ -192,21 +189,24 @@ class _TransactionDetailsModalState extends State {
}
Widget _buildTrailingWIdget(TransactionDetailsListItem item) {
- return switch (item.runtimeType) {
- ConfirmationsListItem => Row(
- children: [
- Text((item as ConfirmationsListItem).current.toString(),
- style: TextStyle(color: Theme.of(context).colorScheme.primary)),
- if (item.needed > 0)
- Text("/${item.needed}",
- style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant))
- ],
- ),
- _ => Text(
- item.value,
- style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant),
- )
- };
+ return Padding(
+ padding: const EdgeInsets.symmetric(vertical: 4.0),
+ child: switch (item.runtimeType) {
+ ConfirmationsListItem => Row(
+ children: [
+ Text((item as ConfirmationsListItem).current.toString(),
+ style: TextStyle(color: Theme.of(context).colorScheme.primary)),
+ if (item.needed > 0)
+ Text("/${item.needed}",
+ style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant))
+ ],
+ ),
+ _ => Text(
+ item.value,
+ style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant),
+ )
+ },
+ );
}
Widget _buildBottomWidget(TransactionDetailsListItem item) {
diff --git a/lib/new-ui/widgets/copy_wrapper.dart b/lib/new-ui/widgets/copy_wrapper.dart
new file mode 100644
index 000000000..254d02f5d
--- /dev/null
+++ b/lib/new-ui/widgets/copy_wrapper.dart
@@ -0,0 +1,59 @@
+import 'dart:io';
+
+import 'package:device_info_plus/device_info_plus.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+class CopyWrapper extends StatefulWidget {
+ const CopyWrapper(
+ {super.key,
+ this.data,
+ required this.builder,
+ this.duration = const Duration(milliseconds: 1200)});
+
+ final ClipboardData? data;
+ final Widget Function(BuildContext, bool) builder;
+ final Duration duration;
+
+ @override
+ State createState() => _CopyWrapperState();
+}
+
+class _CopyWrapperState extends State {
+ bool copied = false;
+
+ void handleCopy() async {
+ if (widget.data == null) return;
+ Clipboard.setData(widget.data!);
+ if (await shouldShowCopied()) {
+ setState(() => copied = true);
+ Future.delayed(widget.duration, () {
+ if (mounted) setState(() => copied = false);
+ });
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ behavior: HitTestBehavior.translucent,
+ onTap: handleCopy,
+ child: widget.builder(context, copied),
+ );
+ }
+
+ // android 13 (sdk 33) added a built-in "text was copied to clipboard" ui element
+ Future shouldShowCopied() async {
+ if (!Platform.isAndroid) return true;
+
+ try {
+ final deviceInfo = DeviceInfoPlugin();
+ final androidInfo = await deviceInfo.androidInfo;
+ final sdk = androidInfo.version.sdkInt;
+
+ return sdk < 33;
+ } catch (_) {
+ return true;
+ }
+ }
+}
diff --git a/lib/src/widgets/new_list_row/list_Item_style_wrapper.dart b/lib/src/widgets/new_list_row/list_Item_style_wrapper.dart
index 88ebf59ce..d8a1186c5 100644
--- a/lib/src/widgets/new_list_row/list_Item_style_wrapper.dart
+++ b/lib/src/widgets/new_list_row/list_Item_style_wrapper.dart
@@ -6,6 +6,7 @@ class ListItemStyleWrapper extends StatelessWidget {
required this.isFirstInSection,
required this.isLastInSection,
required this.builder,
+ this.backgroundColor,
this.onTap,
this.iconPath,
this.height,
@@ -16,6 +17,7 @@ class ListItemStyleWrapper extends StatelessWidget {
final bool isLastInSection;
final double? height;
final VoidCallback? onTap;
+ final Color? backgroundColor;
final Widget Function(BuildContext context, TextStyle textStyle, TextStyle labelStyle) builder;
@override
@@ -52,14 +54,14 @@ class ListItemStyleWrapper extends StatelessWidget {
shape: RoundedSuperellipseBorder(
borderRadius: radius,
),
- color: theme.colorScheme.surfaceContainer,
+ color: backgroundColor ?? theme.colorScheme.surfaceContainer,
),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
child: Padding(
- padding: EdgeInsets.symmetric(horizontal: 12, vertical: height == null ? 12 : 0),
+ padding: EdgeInsets.symmetric(horizontal: 12, vertical: height == null ? 11 : 0),
child: builder(context, textStyle, labelStyle))))),
if(iconPath != null && isLastInSection == false) Container(
color: theme.colorScheme.surfaceContainer,
diff --git a/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart b/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart
index e60dcfbaf..47f5cc822 100644
--- a/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart
+++ b/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart
@@ -1,7 +1,9 @@
+import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/new-ui/widgets/copy_wrapper.dart';
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
import 'package:cake_wallet/src/widgets/new_list_row/list_Item_style_wrapper.dart';
import 'package:flutter/material.dart';
-import 'package:flutter_svg/svg.dart';
+import 'package:flutter/services.dart';
class ListItemRegularRowWidget extends StatelessWidget {
const ListItemRegularRowWidget({
@@ -20,7 +22,8 @@ class ListItemRegularRowWidget extends StatelessWidget {
this.foregroundColor,
this.trailingIconSize,
this.bottomWidget,
- this.trailingWidget
+ this.trailingWidget,
+ this.copyableText
});
final String keyValue;
@@ -38,6 +41,7 @@ class ListItemRegularRowWidget extends StatelessWidget {
final bool truncateTrailingText;
final Color? foregroundColor;
final double? trailingIconSize;
+ final String? copyableText;
@override
Widget build(BuildContext context) {
@@ -47,79 +51,102 @@ class ListItemRegularRowWidget extends StatelessWidget {
? "${trailingText!.substring(0, 17)}..."
: trailingText;
- return ListItemStyleWrapper(
- onTap: onTap,
- iconPath: iconPath,
- isFirstInSection: isFirstInSection,
- isLastInSection: isLastInSection,
- builder: (context, textStyle, labelStyle) {
- return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ return CopyWrapper(
+ data: copyableText != null ? ClipboardData(text: copyableText!) : null,
+ builder: (context, copied) => AnimatedSwitcher(
+ duration: Duration(milliseconds: 150),
+ child: ListItemStyleWrapper(
+ key: ValueKey(copied),
+ backgroundColor: copied ? Theme.of(context).colorScheme.surfaceContainerHigh : null,
+ onTap: onTap,
+ iconPath: iconPath,
+ isFirstInSection: isFirstInSection,
+ isLastInSection: isLastInSection,
+ builder: (context, textStyle, labelStyle) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.center,
children: [
- Expanded(
- child: Row(
- children: [
- if (iconPath != null)
- Padding(
- padding: const EdgeInsets.only(right: 12.0),
- child: CakeImageWidget(imageUrl: iconPath!, width: 24,height: 24,)
- ),
- Flexible(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(label,
- style: foregroundColor == null
- ? textStyle
- : textStyle.copyWith(color: foregroundColor)),
- if (subtitle != null)
- Text(
- subtitle!,
- style: labelStyle.copyWith(fontSize: 12),
- ),
- ],
- ),
- ),
- ],
- ),
- ),
Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
- if (trailingTextToShow != null)
- Padding(
- padding: const EdgeInsets.only(right: 8.0),
- child: Text(
- trailingTextToShow,
- style: labelStyle,
- ),
+ Expanded(
+ child: Row(
+ children: [
+ if (iconPath != null)
+ Padding(
+ padding: const EdgeInsets.only(right: 12.0),
+ child: CakeImageWidget(
+ imageUrl: iconPath!,
+ width: 24,
+ height: 24,
+ )),
+ Flexible(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ if (copied)
+ Text(
+ S.of(context).copied,
+ style: textStyle.copyWith(
+ color: Theme.of(context).colorScheme.primary),
+ )
+ else
+ Text(label,
+ style: foregroundColor == null
+ ? textStyle
+ : textStyle.copyWith(color: foregroundColor)),
+ if (subtitle != null)
+ Text(
+ subtitle!,
+ style: labelStyle.copyWith(fontSize: 12),
+ ),
+ ],
+ ),
+ ),
+ ],
),
- if (trailingWidget != null)
- trailingWidget!
- else if (trailingIconPath != null)
- CakeImageWidget(imageUrl:
- trailingIconPath!,
- height: trailingIconSize ?? 18,
- width:trailingIconSize ?? 18,
- colorFilter: ColorFilter.mode(foregroundColor ?? Theme.of(context).colorScheme.onSurfaceVariant,BlendMode.srcIn),
- )
- else if (showArrow)
- CakeImageWidget(imageUrl:
- "assets/new-ui/arrow_forward.svg",
- height: 14,
- color: theme.colorScheme.onSurfaceVariant
- )
+ ),
+ Row(
+ children: [
+ if (trailingTextToShow != null)
+ Padding(
+ padding: const EdgeInsets.only(right: 8.0),
+ child: Text(
+ trailingTextToShow,
+ style: labelStyle,
+ ),
+ ),
+ if (trailingWidget != null)
+ trailingWidget!
+ else if (trailingIconPath != null)
+ CakeImageWidget(
+ imageUrl: trailingIconPath!,
+ height: trailingIconSize ?? 18,
+ width: trailingIconSize ?? 18,
+ colorFilter: ColorFilter.mode(
+ foregroundColor ?? Theme.of(context).colorScheme.onSurfaceVariant,
+ BlendMode.srcIn),
+ )
+ else if (showArrow)
+ Padding(
+ padding: const EdgeInsets.symmetric(vertical: 7.0),
+ child: CakeImageWidget(imageUrl:
+ "assets/new-ui/arrow_forward.svg",
+ height: 14,
+ color: theme.colorScheme.onSurfaceVariant
+ ),
+ )
+ ],
+ ),
],
),
+ if (bottomWidget != null) bottomWidget!
],
- ),
- if (bottomWidget != null) bottomWidget!
- ],
- );
- });
+ );
+ }),
+ ),
+ );
}
}
diff --git a/lib/src/widgets/new_list_row/list_item_selector_widget.dart b/lib/src/widgets/new_list_row/list_item_selector_widget.dart
index cb138906f..c0b9b9809 100644
--- a/lib/src/widgets/new_list_row/list_item_selector_widget.dart
+++ b/lib/src/widgets/new_list_row/list_item_selector_widget.dart
@@ -36,19 +36,22 @@ class ListItemSelectorWidget extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(child: Text(label, style: textStyle)),
- Row(
- spacing: 8,
- children: [
- Text(
- options[selectedIndex],
- style: labelStyle,
- ),
- CakeImageWidget(imageUrl:
- "assets/new-ui/chooser.svg",
- colorFilter:
- ColorFilter.mode(theme.colorScheme.onSurfaceVariant, BlendMode.srcIn),
- ),
- ],
+ Padding(
+ padding: const EdgeInsets.symmetric(vertical: 4.0),
+ child: Row(
+ spacing: 8,
+ children: [
+ Text(
+ options[selectedIndex],
+ style: labelStyle,
+ ),
+ CakeImageWidget(imageUrl:
+ "assets/new-ui/chooser.svg",
+ colorFilter:
+ ColorFilter.mode(theme.colorScheme.onSurfaceVariant, BlendMode.srcIn),
+ ),
+ ],
+ ),
),
],
);
diff --git a/lib/src/widgets/new_list_row/new_list_section.dart b/lib/src/widgets/new_list_row/new_list_section.dart
index 21893d81e..196436124 100644
--- a/lib/src/widgets/new_list_row/new_list_section.dart
+++ b/lib/src/widgets/new_list_row/new_list_section.dart
@@ -103,6 +103,7 @@ class NewListSections extends StatelessWidget {
showArrow: item.showArrow,
truncateTrailingText: item.truncateTrailingText,
foregroundColor: item.foregroundColor,
+ copyableText: item.copyableText,
trailingIconSize: item.trailingIconSize,
trailingWidget: item.trailingWidget,
bottomWidget: item.bottomWidget,
diff --git a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart
index 269b93241..52c5954d8 100644
--- a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart
+++ b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart
@@ -51,6 +51,9 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
_wallet.type == WalletType.litecoin ||
_wallet.type == WalletType.dogecoin;
+ String get derivationPath => _item?.derivationPath ?? '';
+ String get index => _item?.id.toString() ?? '';
+
Future save() async {
try {
state = AddressIsSaving();
diff --git a/lib/view_model/wallet_address_list/wallet_address_list_item.dart b/lib/view_model/wallet_address_list/wallet_address_list_item.dart
index 2c5b0a3d9..97309173d 100644
--- a/lib/view_model/wallet_address_list/wallet_address_list_item.dart
+++ b/lib/view_model/wallet_address_list/wallet_address_list_item.dart
@@ -14,6 +14,7 @@ class WalletAddressListItem extends ListItem {
this.isHidden = false,
this.isManual = false,
this.isLegacyDerivation = false,
+ this.derivationPath
}) : super();
final int? id;
@@ -26,6 +27,7 @@ class WalletAddressListItem extends ListItem {
bool isHidden;
bool isManual;
bool isLegacyDerivation;
+ String? derivationPath;
final bool? isOneTimeReceiveAddress;
@override
diff --git a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
index a517cc24b..4fc003077 100644
--- a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
+++ b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
@@ -258,6 +258,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
balance: _appStore.amountParsingProxy
.getDisplayCryptoString(address.balance, walletTypeToCryptoCurrency(type)),
isChange: address.isChange,
+ derivationPath: address.derivationPath,
);
});
addressList.addAll(addressItems);
@@ -275,6 +276,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
.getDisplayCryptoString(address.balance, walletTypeToCryptoCurrency(type)),
isChange: address.isChange,
isOneTimeReceiveAddress: true,
+ derivationPath: address.derivationPath,
);
});
addressList.addAll(receivedAddressItems);
@@ -291,7 +293,8 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
balance: _appStore.amountParsingProxy
.getDisplayCryptoString(subaddress.balance, walletTypeToCryptoCurrency(type)),
isChange: subaddress.isChange,
- isLegacyDerivation: subaddress.isLegacyDerivation);
+ isLegacyDerivation: subaddress.isLegacyDerivation,
+ derivationPath: subaddress.derivationPath);
});
// don't show all 1000+ mweb addresses:
diff --git a/res/pictures/cake-setting.svg b/res/pictures/cake-setting.svg
new file mode 100644
index 000000000..f3182f83d
--- /dev/null
+++ b/res/pictures/cake-setting.svg
@@ -0,0 +1,13 @@
+
diff --git a/res/pictures/wallet-setting.svg b/res/pictures/wallet-setting.svg
new file mode 100644
index 000000000..aa603df83
--- /dev/null
+++ b/res/pictures/wallet-setting.svg
@@ -0,0 +1,3 @@
+
diff --git a/tool/configure.dart b/tool/configure.dart
index 8e8da7183..c6ee96bc6 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -161,7 +161,7 @@ import "package:breez_sdk_spark_flutter/src/rust/errors.dart";
const bitcoinCwPart = "part 'cw_bitcoin.dart';";
const bitcoinContent = """
- class ElectrumSubAddress {
+class ElectrumSubAddress {
ElectrumSubAddress({
required this.id,
required this.name,
@@ -169,13 +169,16 @@ import "package:breez_sdk_spark_flutter/src/rust/errors.dart";
required this.txCount,
required this.balance,
required this.isChange,
- this.isLegacyDerivation = false});
+ this.derivationPath,
+ this.isLegacyDerivation = false
+ });
final int id;
final String name;
final String address;
final int txCount;
final int balance;
final bool isChange;
+ final String? derivationPath;
final bool isLegacyDerivation;
}