mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-03 17:40:43 +00:00
list of used electrum addresses
This commit is contained in:
parent
2ff81df9e7
commit
d8368172ff
8 changed files with 200 additions and 17 deletions
|
@ -86,6 +86,9 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
return acc;
|
return acc;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
List<BitcoinAddressRecord> get usedAddressList =>
|
||||||
|
addresses.where((element) => element.isUsed).toList();
|
||||||
|
|
||||||
Future<void> discoverAddresses() async {
|
Future<void> discoverAddresses() async {
|
||||||
await _discoverAddresses(mainHd, false);
|
await _discoverAddresses(mainHd, false);
|
||||||
await _discoverAddresses(sideHd, true);
|
await _discoverAddresses(sideHd, true);
|
||||||
|
|
|
@ -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/edit_token_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/dashboard/home_settings_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/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/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_edit_or_create_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/nano_accounts/nano_account_list_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(() => NFTViewModel(appStore, getIt.get<BottomSheetService>()));
|
||||||
getIt.registerFactory<TorPage>(() => TorPage(getIt.get<AppStore>()));
|
getIt.registerFactory<TorPage>(() => TorPage(getIt.get<AppStore>()));
|
||||||
|
|
||||||
|
getIt.registerFactory(() => AddressListPage(wallet: getIt.get<AppStore>().wallet!));
|
||||||
|
|
||||||
_isSetupFinished = true;
|
_isSetupFinished = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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/edit_token_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/dashboard/home_settings_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/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/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_edit_or_create_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/nodes/pow_node_create_or_edit_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:
|
case Routes.torPage:
|
||||||
return MaterialPageRoute<void>(builder: (_) => getIt.get<TorPage>());
|
return MaterialPageRoute<void>(builder: (_) => getIt.get<TorPage>());
|
||||||
|
|
||||||
|
case Routes.addressListPage:
|
||||||
|
return MaterialPageRoute<void>(builder: (_) => getIt.get<AddressListPage>());
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return MaterialPageRoute<void>(
|
return MaterialPageRoute<void>(
|
||||||
builder: (_) => Scaffold(
|
builder: (_) => Scaffold(
|
||||||
|
|
|
@ -105,4 +105,5 @@ class Routes {
|
||||||
static const nftDetailsPage = '/nft_details_page';
|
static const nftDetailsPage = '/nft_details_page';
|
||||||
static const importNFTPage = '/import_nft_page';
|
static const importNFTPage = '/import_nft_page';
|
||||||
static const torPage = '/tor_page';
|
static const torPage = '/tor_page';
|
||||||
|
static const addressListPage = '/address_list_page';
|
||||||
}
|
}
|
||||||
|
|
94
lib/src/screens/dashboard/pages/address_list_page.dart
Normal file
94
lib/src/screens/dashboard/pages/address_list_page.dart
Normal 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();
|
||||||
|
}
|
|
@ -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/utils/show_pop_up.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.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:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||||
|
import 'package:cw_bitcoin/electrum_wallet.dart';
|
||||||
import 'package:flutter/material.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/view_model/wallet_address_list/wallet_address_list_view_model.dart';
|
||||||
import 'package:cake_wallet/src/screens/receive/widgets/qr_widget.dart';
|
import 'package:cake_wallet/src/screens/receive/widgets/qr_widget.dart';
|
||||||
|
@ -104,7 +105,21 @@ class AddressPage extends BasePage {
|
||||||
Widget? trailing(BuildContext context) {
|
Widget? trailing(BuildContext context) {
|
||||||
return Material(
|
return Material(
|
||||||
color: Colors.transparent,
|
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,
|
label: S.of(context).share,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
|
@ -121,6 +136,8 @@ class AddressPage extends BasePage {
|
||||||
icon: Icon(Icons.share, size: 20, color: pageIconColor(context)),
|
icon: Icon(Icons.share, size: 20, color: pageIconColor(context)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
59
lib/src/screens/receive/widgets/address_list_item.dart
Normal file
59
lib/src/screens/receive/widgets/address_list_item.dart
Normal 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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
])),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,11 +7,13 @@ class SearchBarWidget extends StatelessWidget {
|
||||||
required this.searchController,
|
required this.searchController,
|
||||||
this.hintText,
|
this.hintText,
|
||||||
this.borderRadius = 14,
|
this.borderRadius = 14,
|
||||||
|
this.searchIconColor
|
||||||
});
|
});
|
||||||
|
|
||||||
final TextEditingController searchController;
|
final TextEditingController searchController;
|
||||||
final String? hintText;
|
final String? hintText;
|
||||||
final double borderRadius;
|
final double borderRadius;
|
||||||
|
final Color? searchIconColor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -22,7 +24,7 @@ class SearchBarWidget extends StatelessWidget {
|
||||||
hintText: hintText ?? S.of(context).search_currency,
|
hintText: hintText ?? S.of(context).search_currency,
|
||||||
hintStyle: TextStyle(color: Theme.of(context).extension<PickerTheme>()!.searchHintColor),
|
hintStyle: TextStyle(color: Theme.of(context).extension<PickerTheme>()!.searchHintColor),
|
||||||
prefixIcon: Image.asset("assets/images/search_icon.png",
|
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,
|
filled: true,
|
||||||
fillColor: Theme.of(context).extension<PickerTheme>()!.searchBackgroundFillColor,
|
fillColor: Theme.of(context).extension<PickerTheme>()!.searchBackgroundFillColor,
|
||||||
alignLabelWithHint: false,
|
alignLabelWithHint: false,
|
||||||
|
|
Loading…
Reference in a new issue