list of used electrum addresses

This commit is contained in:
Serhii 2023-12-15 15:31:03 +02:00
parent 2ff81df9e7
commit d8368172ff
8 changed files with 200 additions and 17 deletions

View file

@ -86,6 +86,9 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
return acc;
});
List<BitcoinAddressRecord> get usedAddressList =>
addresses.where((element) => element.isUsed).toList();
Future<void> discoverAddresses() async {
await _discoverAddresses(mainHd, false);
await _discoverAddresses(sideHd, true);

View file

@ -29,6 +29,7 @@ import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet
import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart';
import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/address_list_page.dart';
import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart';
import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart';
import 'package:cake_wallet/src/screens/nano_accounts/nano_account_list_page.dart';
@ -1183,5 +1184,7 @@ Future<void> setup({
getIt.registerFactory(() => NFTViewModel(appStore, getIt.get<BottomSheetService>()));
getIt.registerFactory<TorPage>(() => TorPage(getIt.get<AppStore>()));
getIt.registerFactory(() => AddressListPage(wallet: getIt.get<AppStore>().wallet!));
_isSetupFinished = true;
}

View file

@ -15,6 +15,7 @@ import 'package:cake_wallet/src/screens/buy/webview_page.dart';
import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart';
import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/address_list_page.dart';
import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart';
import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart';
import 'package:cake_wallet/src/screens/nodes/pow_node_create_or_edit_page.dart';
@ -630,6 +631,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.torPage:
return MaterialPageRoute<void>(builder: (_) => getIt.get<TorPage>());
case Routes.addressListPage:
return MaterialPageRoute<void>(builder: (_) => getIt.get<AddressListPage>());
default:
return MaterialPageRoute<void>(
builder: (_) => Scaffold(

View file

@ -105,4 +105,5 @@ class Routes {
static const nftDetailsPage = '/nft_details_page';
static const importNFTPage = '/import_nft_page';
static const torPage = '/tor_page';
static const addressListPage = '/address_list_page';
}

View file

@ -0,0 +1,94 @@
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/receive/widgets/address_list_item.dart';
import 'package:cake_wallet/src/widgets/search_bar_widget.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/electrum_wallet.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:flutter/material.dart';
class AddressListPage extends BasePage {
AddressListPage({required WalletBase wallet}) : this._wallet = wallet;
@override
String get title => 'Address list';
final WalletBase _wallet;
Widget body(BuildContext context) => AddressListBody(wallet: _wallet);
}
class AddressListBody extends StatefulWidget {
const AddressListBody({required this.wallet});
final WalletBase wallet;
@override
State<AddressListBody> createState() => _AddressListBodyState(wallet: wallet);
}
class _AddressListBodyState extends State<AddressListBody> {
_AddressListBodyState({required this.wallet});
final WalletBase wallet;
late TextEditingController searchController;
late List<BitcoinAddressRecord> filteredAddresses;
@override
void initState() {
super.initState();
searchController = TextEditingController();
filteredAddresses = getAddresses();
searchController.addListener(() {
filterAddresses();
});
}
List<BitcoinAddressRecord> getAddresses() {
return (widget.wallet as ElectrumWallet).walletAddresses.usedAddressList;
}
void filterAddresses() {
String searchText = searchController.text.toLowerCase();
setState(() {
filteredAddresses = getAddresses().where((address) {
return address.address.toLowerCase().contains(searchText);
}).toList();
});
}
@override
void dispose() {
searchController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) => (wallet is ElectrumWallet)
? Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: SearchBarWidget(
searchController: searchController,
borderRadius: 12,
searchIconColor: Theme.of(context).primaryColor,
hintText: 'Search address'),
),
Expanded(
child: Padding(
padding: EdgeInsets.fromLTRB(24, 12, 24, 24),
child: ListView.separated(
itemCount: filteredAddresses.length,
separatorBuilder: (_, __) => SizedBox(height: 15),
itemBuilder: (_, int index) {
final item = filteredAddresses[index];
return AddressListItem(
address: item.address, isChange: item.isHidden);
},
),
),
),
],
)
: Container();
}

View file

@ -15,6 +15,7 @@ import 'package:cake_wallet/utils/share_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_bitcoin/electrum_wallet.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
import 'package:cake_wallet/src/screens/receive/widgets/qr_widget.dart';
@ -104,7 +105,21 @@ class AddressPage extends BasePage {
Widget? trailing(BuildContext context) {
return Material(
color: Colors.transparent,
child: Semantics(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if(dashboardViewModel.wallet is ElectrumWallet)
TextButton(
onPressed: () => Navigator.of(context).pushNamed(Routes.addressListPage),
child: Text(
'address list',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: titleColor(context)),
),
),
Semantics(
label: S.of(context).share,
child: IconButton(
padding: EdgeInsets.zero,
@ -121,6 +136,8 @@ class AddressPage extends BasePage {
icon: Icon(Icons.share, size: 20, color: pageIconColor(context)),
),
),
],
),
);
}

View file

@ -0,0 +1,59 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter/material.dart';
class AddressListItem extends StatelessWidget {
AddressListItem({required this.address, required this.isChange});
final String address;
final bool isChange;
@override
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: BoxConstraints(maxHeight: 70, minHeight: 50),
child: Container(
padding: EdgeInsets.symmetric(vertical: 6, horizontal: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12)),
color: Theme.of(context).primaryColor),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
AutoSizeText(
address,
style: TextStyle(
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.w600),
maxLines: 1,
),
if (isChange)
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
height: 17,
padding: EdgeInsets.only(left: 6, right: 6),
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(8.5)),
color: Colors.white),
alignment: Alignment.center,
child: Text(
S.of(context).unspent_change,
style: TextStyle(
color: Theme.of(context).primaryColor,
fontSize: 7,
fontWeight: FontWeight.w600,
),
),
),
],
),
])),
);
}
}

View file

@ -7,11 +7,13 @@ class SearchBarWidget extends StatelessWidget {
required this.searchController,
this.hintText,
this.borderRadius = 14,
this.searchIconColor
});
final TextEditingController searchController;
final String? hintText;
final double borderRadius;
final Color? searchIconColor;
@override
Widget build(BuildContext context) {
@ -22,7 +24,7 @@ class SearchBarWidget extends StatelessWidget {
hintText: hintText ?? S.of(context).search_currency,
hintStyle: TextStyle(color: Theme.of(context).extension<PickerTheme>()!.searchHintColor),
prefixIcon: Image.asset("assets/images/search_icon.png",
color: Theme.of(context).extension<PickerTheme>()!.searchIconColor),
color: searchIconColor ?? Theme.of(context).extension<PickerTheme>()!.searchIconColor),
filled: true,
fillColor: Theme.of(context).extension<PickerTheme>()!.searchBackgroundFillColor,
alignLabelWithHint: false,