From a347ddffc4b6aeb95a10be711d1404c3ec469cfe Mon Sep 17 00:00:00 2001 From: detherminal <76167420+detherminal@users.noreply.github.com> Date: Sat, 27 May 2023 00:17:09 +0300 Subject: [PATCH] feat: add openalias support for xmr --- lib/pages/send_view/send_view.dart | 25 +++- .../sub_widgets/openalias_sheet.dart | 138 ++++++++++++++++++ pubspec.lock | 12 +- pubspec.yaml | 1 + 4 files changed, 170 insertions(+), 6 deletions(-) create mode 100644 lib/pages/send_view/sub_widgets/openalias_sheet.dart diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart index c466d2aa2..07e8464dc 100644 --- a/lib/pages/send_view/send_view.dart +++ b/lib/pages/send_view/send_view.dart @@ -27,6 +27,7 @@ import 'package:stackwallet/pages/coin_control/coin_control_view.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dialog.dart'; import 'package:stackwallet/pages/send_view/sub_widgets/firo_balance_selection_sheet.dart'; +import 'package:stackwallet/pages/send_view/sub_widgets/openalias_sheet.dart'; import 'package:stackwallet/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/ui/fee_rate_type_state_provider.dart'; @@ -928,10 +929,26 @@ class _SendViewState extends ConsumerState { const SizedBox( height: 16, ), - Text( - isPaynymSend ? "Send to PayNym address" : "Send to", - style: STextStyles.smallMed12(context), - textAlign: TextAlign.left, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + isPaynymSend ? "Send to PayNym address" : "Send to", + style: STextStyles.smallMed12(context), + textAlign: TextAlign.left, + ), + if (coin == Coin.monero) + CustomTextButton( + text: "Use OpenAlias", + onTap: () async { + await showModalBottomSheet(context: context, builder: (context) => OpenAliasBottomSheet( + onSelected: (address) { + sendToController.text = address; + }, + )); + }, + ) + ], ), const SizedBox( height: 8, diff --git a/lib/pages/send_view/sub_widgets/openalias_sheet.dart b/lib/pages/send_view/sub_widgets/openalias_sheet.dart new file mode 100644 index 000000000..04d251a8e --- /dev/null +++ b/lib/pages/send_view/sub_widgets/openalias_sheet.dart @@ -0,0 +1,138 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import '../../../themes/stack_colors.dart'; +import '../../../utilities/constants.dart'; +import '../../../utilities/text_styles.dart'; + +import 'package:basic_utils/basic_utils.dart'; + +class OpenAliasBottomSheet extends ConsumerStatefulWidget { + const OpenAliasBottomSheet({ + Key? key, + required this.onSelected, + }) : super(key: key); + + final Null Function(String) onSelected; + + @override + ConsumerState createState() => + _OpenAliasBottomSheetState(); +} + +class _OpenAliasBottomSheetState extends ConsumerState { + late TextEditingController textEditingController; + + @override + void initState() { + super.initState(); + textEditingController = TextEditingController(); + } + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + child: Container( + decoration: BoxDecoration( + color: Theme.of(context).extension()!.popupBG, + borderRadius: const BorderRadius.vertical( + top: Radius.circular(20), + ), + ), + child: Padding( + padding: const EdgeInsets.only( + top: 20, + left: 20, + right: 20, + bottom: 20, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Container( + decoration: BoxDecoration( + color: Theme.of(context) + .extension()! + .textFieldDefaultBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + width: 60, + height: 4, + ), + ), + const SizedBox( + height: 36, + ), + Text( + 'OpenAlias Address', + style: STextStyles.smallMed12(context), + textAlign: TextAlign.left, + ), + const SizedBox( + height: 8, + ), + TextField( + controller: textEditingController, + decoration: const InputDecoration( + border: OutlineInputBorder(), + ), + ), + const SizedBox( + height: 16, + ), + Align( + alignment: Alignment.bottomCenter, + child: ConstrainedBox( + constraints: const BoxConstraints( + minWidth: 480, + minHeight: 70, + ), + child: TextButton( + style: Theme.of(context) + .extension()! + .getPrimaryEnabledButtonStyle(context), + onPressed: () async { + String text = textEditingController.text.trim().replaceAll("@", "."); + List? result = await DnsUtils.lookupRecord(text, RRecordType.TXT); + String address = ""; + if (result != null && result.isNotEmpty) { + for (RRecord record in result) { + if (record.data.startsWith("oa1:xmr")) { + List datas = record.data.split(" "); + for (String data in datas) { + if (data.startsWith("recipient_address=")) { + address = data.substring("recipient_address=".length).replaceAll(";", ""); + break; + } + } + break; + } + } + } + widget.onSelected(address!); + Navigator.of(context).pop(); + }, + child: Text( + "Enter", + style: STextStyles.button(context), + ), + ), + ), + ) + ], + ), + ), + ), + ), + ); + } +} + + diff --git a/pubspec.lock b/pubspec.lock index 6ff3bb198..5e2a6456a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -81,6 +81,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.2.3" + basic_utils: + dependency: "direct main" + description: + name: basic_utils + sha256: "8815477fcf58499e42326bd858e391442425fa57db9a45e48e15224c62049262" + url: "https://pub.dev" + source: hosted + version: "5.5.4" bech32: dependency: "direct main" description: @@ -1321,10 +1329,10 @@ packages: dependency: "direct main" description: name: pointycastle - sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346 + sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" url: "https://pub.dev" source: hosted - version: "3.6.2" + version: "3.7.3" pool: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 6733e0cbd..ad6943796 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -154,6 +154,7 @@ dependencies: archive: ^3.3.2 desktop_drop: ^0.4.1 nanodart: ^2.0.0 + basic_utils: ^5.5.4 dev_dependencies: flutter_test: