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/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/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/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/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;
}