mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
sign working for a few wallet types
This commit is contained in:
parent
d4e3e505cf
commit
82dc036a18
11 changed files with 355 additions and 131 deletions
|
@ -1221,7 +1221,7 @@ abstract class ElectrumWalletBase
|
||||||
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => _onError = onError;
|
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => _onError = onError;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String signMessage(String message, {String? address = null}) {
|
Future<String> signMessage(String message, {String? address = null}) async {
|
||||||
final index = address != null
|
final index = address != null
|
||||||
? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
|
? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
|
||||||
: null;
|
: null;
|
||||||
|
|
|
@ -166,7 +166,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String signMessage(String message, {String? address = null}) {
|
Future<String> signMessage(String message, {String? address = null}) async {
|
||||||
final index = address != null
|
final index = address != null
|
||||||
? walletAddresses.allAddresses
|
? walletAddresses.allAddresses
|
||||||
.firstWhere((element) => element.address == AddressUtils.toLegacyAddress(address))
|
.firstWhere((element) => element.address == AddressUtils.toLegacyAddress(address))
|
||||||
|
|
|
@ -88,7 +88,7 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
|
||||||
|
|
||||||
Future<void> renameWalletFiles(String newWalletName);
|
Future<void> renameWalletFiles(String newWalletName);
|
||||||
|
|
||||||
String signMessage(String message, {String? address = null}) => throw UnimplementedError();
|
Future<String> signMessage(String message, {String? address = null}) => throw UnimplementedError();
|
||||||
|
|
||||||
bool? isTestnet;
|
bool? isTestnet;
|
||||||
}
|
}
|
||||||
|
|
|
@ -524,7 +524,7 @@ abstract class EVMChainWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String signMessage(String message, {String? address}) =>
|
Future<String> signMessage(String message, {String? address}) async =>
|
||||||
bytesToHex(_evmChainPrivateKey.signPersonalMessageToUint8List(ascii.encode(message)));
|
bytesToHex(_evmChainPrivateKey.signPersonalMessageToUint8List(ascii.encode(message)));
|
||||||
|
|
||||||
Web3Client? getWeb3Client() => _client.getWeb3Client();
|
Web3Client? getWeb3Client() => _client.getWeb3Client();
|
||||||
|
|
|
@ -686,7 +686,7 @@ abstract class MoneroWalletBase
|
||||||
void setExceptionHandler(void Function(FlutterErrorDetails) e) => onError = e;
|
void setExceptionHandler(void Function(FlutterErrorDetails) e) => onError = e;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String signMessage(String message, {String? address}) {
|
Future<String> signMessage(String message, {String? address}) async {
|
||||||
final useAddress = address ?? "";
|
final useAddress = address ?? "";
|
||||||
return monero_wallet.signMessage(message, address: useAddress);
|
return monero_wallet.signMessage(message, address: useAddress);
|
||||||
}
|
}
|
||||||
|
|
|
@ -522,5 +522,10 @@ abstract class SolanaWalletBase
|
||||||
return hex;
|
return hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String> signMessage(String message, {String? address}) async {
|
||||||
|
return signSolanaMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
SolanaClient? get solanaClient => _client.getSolanaClient;
|
SolanaClient? get solanaClient => _client.getSolanaClient;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,79 +1,37 @@
|
||||||
import 'package:cake_wallet/core/execution_state.dart';
|
import 'package:cake_wallet/core/execution_state.dart';
|
||||||
import 'package:cake_wallet/di.dart';
|
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/nano/nano.dart';
|
|
||||||
import 'package:cake_wallet/routes.dart';
|
|
||||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.dart';
|
import 'package:cake_wallet/src/screens/dashboard/widgets/sign_form.dart';
|
||||||
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
|
import 'package:cake_wallet/src/screens/dashboard/widgets/verify_form.dart';
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||||
import 'package:cake_wallet/store/app_store.dart';
|
|
||||||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
|
import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
|
||||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
import 'package:cake_wallet/utils/responsive_layout_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/sign_view_model.dart';
|
import 'package:cake_wallet/view_model/dashboard/sign_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
|
|
||||||
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
|
|
||||||
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
|
|
||||||
import 'package:cw_core/nano_account_info_response.dart';
|
|
||||||
import 'package:cw_core/wallet_info.dart';
|
|
||||||
import 'package:cw_core/wallet_type.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:keyboard_actions/keyboard_actions.dart';
|
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:polyseed/polyseed.dart';
|
|
||||||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||||
|
|
||||||
class SignPage extends BasePage {
|
class SignPage extends BasePage {
|
||||||
SignPage(this.signViewModel)
|
SignPage(this.signViewModel)
|
||||||
: walletRestoreFromSeedFormKey = GlobalKey<WalletRestoreFromSeedFormState>(),
|
: signFormKey = GlobalKey<SignFormState>(),
|
||||||
walletRestoreFromKeysFormKey = GlobalKey<WalletRestoreFromKeysFromState>(),
|
verifyFormKey = GlobalKey<VerifyFormState>(),
|
||||||
_pages = [],
|
_pages = [],
|
||||||
_blockHeightFocusNode = FocusNode(),
|
|
||||||
_controller = PageController(initialPage: 0) {
|
_controller = PageController(initialPage: 0) {
|
||||||
// walletRestoreViewModel.availableModes.forEach((mode) {
|
_pages.add(SignForm(
|
||||||
// switch (mode) {
|
key: signFormKey,
|
||||||
// case WalletRestoreMode.seed:
|
type: signViewModel.wallet.type,
|
||||||
// _pages.add(WalletRestoreFromSeedForm(
|
includeAddress: signViewModel.signIncludesAddress,
|
||||||
// seedTypeViewModel: seedTypeViewModel,
|
));
|
||||||
// displayBlockHeightSelector:
|
_pages.add(VerifyForm(
|
||||||
// walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
|
key: verifyFormKey,
|
||||||
// displayLanguageSelector: walletRestoreViewModel.hasSeedLanguageSelector,
|
type: signViewModel.wallet.type,
|
||||||
// type: walletRestoreViewModel.type,
|
));
|
||||||
// key: walletRestoreFromSeedFormKey,
|
|
||||||
// blockHeightFocusNode: _blockHeightFocusNode,
|
|
||||||
// onHeightOrDateEntered: (value) {
|
|
||||||
// },
|
|
||||||
// onSeedChange: (String seed) {
|
|
||||||
// final isPolyseed =
|
|
||||||
// walletRestoreViewModel.type == WalletType.monero && Polyseed.isValidSeed(seed);
|
|
||||||
// _validateOnChange(isPolyseed: isPolyseed);
|
|
||||||
// },
|
|
||||||
// onLanguageChange: (String language) {
|
|
||||||
// final isPolyseed = language.startsWith("POLYSEED_");
|
|
||||||
// _validateOnChange(isPolyseed: isPolyseed);
|
|
||||||
// }));
|
|
||||||
// break;
|
|
||||||
// case WalletRestoreMode.keys:
|
|
||||||
// _pages.add(WalletRestoreFromKeysFrom(
|
|
||||||
// key: walletRestoreFromKeysFormKey,
|
|
||||||
// walletRestoreViewModel: walletRestoreViewModel,
|
|
||||||
// onPrivateKeyChange: (String seed) {
|
|
||||||
// if (walletRestoreViewModel.type == WalletType.nano ||
|
|
||||||
// walletRestoreViewModel.type == WalletType.banano) {
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// displayPrivateKeyField: walletRestoreViewModel.hasRestoreFromPrivateKey,
|
|
||||||
// onHeightOrDateEntered: (value) => walletRestoreViewModel.isButtonEnabled = value));
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -91,29 +49,45 @@ class SignPage extends BasePage {
|
||||||
final SignViewModel signViewModel;
|
final SignViewModel signViewModel;
|
||||||
final PageController _controller;
|
final PageController _controller;
|
||||||
final List<Widget> _pages;
|
final List<Widget> _pages;
|
||||||
final GlobalKey<WalletRestoreFromSeedFormState> walletRestoreFromSeedFormKey;
|
final GlobalKey<SignFormState> signFormKey;
|
||||||
final GlobalKey<WalletRestoreFromKeysFromState> walletRestoreFromKeysFormKey;
|
final GlobalKey<VerifyFormState> verifyFormKey;
|
||||||
final FocusNode _blockHeightFocusNode;
|
|
||||||
DerivationType derivationType = DerivationType.unknown;
|
|
||||||
String? derivationPath = null;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget body(BuildContext context) {
|
Widget body(BuildContext context) {
|
||||||
// reaction((_) => walletRestoreViewModel.state, (ExecutionState state) {
|
reaction((_) => signViewModel.state, (ExecutionState state) {
|
||||||
// if (state is FailureState) {
|
if (state is FailureState) {
|
||||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
// showPopUp<void>(
|
showPopUp<void>(
|
||||||
// context: context,
|
context: context,
|
||||||
// builder: (_) {
|
builder: (_) {
|
||||||
// return AlertWithOneAction(
|
return AlertWithOneAction(
|
||||||
// alertTitle: S.current.new_wallet,
|
alertTitle: S.current.error,
|
||||||
// alertContent: state.error,
|
alertContent: state.error,
|
||||||
// buttonText: S.of(context).ok,
|
buttonText: S.of(context).ok,
|
||||||
// buttonAction: () => Navigator.of(context).pop());
|
buttonAction: () => Navigator.of(context).pop(),
|
||||||
// });
|
);
|
||||||
// });
|
});
|
||||||
// }
|
});
|
||||||
// });
|
}
|
||||||
|
if (state is ExecutedSuccessfullyState) {
|
||||||
|
if (signViewModel.isSigning) {
|
||||||
|
signFormKey.currentState!.signatureController.text = state.payload as String;
|
||||||
|
} else {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
showPopUp<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (_) {
|
||||||
|
return AlertWithOneAction(
|
||||||
|
alertTitle: S.current.successful,
|
||||||
|
alertContent: "T: The message was successfully verified",
|
||||||
|
buttonText: S.of(context).ok,
|
||||||
|
buttonAction: () => Navigator.of(context).pop(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) {
|
// reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) {
|
||||||
// walletRestoreViewModel.isButtonEnabled = false;
|
// walletRestoreViewModel.isButtonEnabled = false;
|
||||||
|
@ -138,7 +112,7 @@ class SignPage extends BasePage {
|
||||||
nextFocus: false,
|
nextFocus: false,
|
||||||
actions: [
|
actions: [
|
||||||
KeyboardActionsItem(
|
KeyboardActionsItem(
|
||||||
focusNode: _blockHeightFocusNode,
|
focusNode: FocusNode(),
|
||||||
toolbarButtons: [(_) => KeyboardDoneButton()],
|
toolbarButtons: [(_) => KeyboardDoneButton()],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -156,8 +130,7 @@ class SignPage extends BasePage {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: PageView.builder(
|
child: PageView.builder(
|
||||||
onPageChanged: (page) {
|
onPageChanged: (page) {
|
||||||
// walletRestoreViewModel.mode =
|
signViewModel.isSigning = page == 0;
|
||||||
// page == 0 ? WalletRestoreMode.seed : WalletRestoreMode.keys;
|
|
||||||
},
|
},
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
itemCount: _pages.length,
|
itemCount: _pages.length,
|
||||||
|
@ -190,30 +163,30 @@ class SignPage extends BasePage {
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await _confirmForm(context);
|
await _confirmForm(context);
|
||||||
},
|
},
|
||||||
text: S.of(context).restore_recover,
|
text: signViewModel.isSigning ? "T: Sign Message" : "T: Verify Message",
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.extension<WalletListTheme>()!
|
.extension<WalletListTheme>()!
|
||||||
.createNewWalletButtonBackgroundColor,
|
.createNewWalletButtonBackgroundColor,
|
||||||
textColor: Theme.of(context)
|
textColor: Theme.of(context)
|
||||||
.extension<WalletListTheme>()!
|
.extension<WalletListTheme>()!
|
||||||
.restoreWalletButtonTextColor,
|
.restoreWalletButtonTextColor,
|
||||||
// isLoading: walletRestoreViewModel.state is IsExecutingState,
|
isLoading: signViewModel.state is IsExecutingState,
|
||||||
// isDisabled: !walletRestoreViewModel.isButtonEnabled,
|
// isDisabled: !signViewModel.isButtonEnabled,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 25),
|
// const SizedBox(height: 25),
|
||||||
GestureDetector(
|
// GestureDetector(
|
||||||
onTap: () {
|
// onTap: () {
|
||||||
// Navigator.of(context)
|
// // Navigator.of(context)
|
||||||
// .pushNamed(Routes.advancedPrivacySettings, arguments: {
|
// // .pushNamed(Routes.advancedPrivacySettings, arguments: {
|
||||||
// 'type': walletRestoreViewModel.type,
|
// // 'type': walletRestoreViewModel.type,
|
||||||
// 'useTestnet': walletRestoreViewModel.useTestnet,
|
// // 'useTestnet': walletRestoreViewModel.useTestnet,
|
||||||
// 'toggleTestnet': walletRestoreViewModel.toggleUseTestnet
|
// // 'toggleTestnet': walletRestoreViewModel.toggleUseTestnet
|
||||||
// });
|
// // });
|
||||||
},
|
// },
|
||||||
child: Text(S.of(context).advanced_settings),
|
// child: Text(S.of(context).advanced_settings),
|
||||||
),
|
// ),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -225,39 +198,28 @@ class SignPage extends BasePage {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _validateOnChange({bool isPolyseed = false}) {}
|
|
||||||
|
|
||||||
Future<void> _confirmForm(BuildContext context) async {
|
Future<void> _confirmForm(BuildContext context) async {
|
||||||
// // Dismissing all visible keyboard to provide context for navigation
|
FocusManager.instance.primaryFocus?.unfocus();
|
||||||
// FocusManager.instance.primaryFocus?.unfocus();
|
|
||||||
|
|
||||||
// late BuildContext? formContext;
|
|
||||||
// late GlobalKey<FormState>? formKey;
|
|
||||||
// late String name;
|
|
||||||
// if (walletRestoreViewModel.mode == WalletRestoreMode.seed) {
|
|
||||||
// formContext = walletRestoreFromSeedFormKey.currentContext;
|
|
||||||
// formKey = walletRestoreFromSeedFormKey.currentState!.formKey;
|
|
||||||
// name = walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.value.text;
|
|
||||||
// } else if (walletRestoreViewModel.mode == WalletRestoreMode.keys) {
|
|
||||||
// formContext = walletRestoreFromKeysFormKey.currentContext;
|
|
||||||
// formKey = walletRestoreFromKeysFormKey.currentState!.formKey;
|
|
||||||
// name = walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.value.text;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (!formKey!.currentState!.validate()) {
|
// if (!formKey!.currentState!.validate()) {
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> showNameExistsAlert(BuildContext context) {
|
if (signViewModel.isSigning) {
|
||||||
return showPopUp<void>(
|
String message = signFormKey.currentState!.messageController.text;
|
||||||
context: context,
|
String? address;
|
||||||
builder: (_) {
|
if (signViewModel.signIncludesAddress) {
|
||||||
return AlertWithOneAction(
|
address = signFormKey.currentState!.addressController.text;
|
||||||
alertTitle: '',
|
}
|
||||||
alertContent: S.of(context).wallet_name_exists,
|
await signViewModel.sign(message, address: address);
|
||||||
buttonText: S.of(context).ok,
|
} else {
|
||||||
buttonAction: () => Navigator.of(context).pop());
|
String message = verifyFormKey.currentState!.messageController.text;
|
||||||
});
|
String signature = verifyFormKey.currentState!.signatureController.text;
|
||||||
|
String? address;
|
||||||
|
// if (signViewModel.signIncludesAddress) {
|
||||||
|
// address = signFormKey.currentState!.addressController.text;
|
||||||
|
// }
|
||||||
|
await signViewModel.verify(message, signature, address: address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
116
lib/src/screens/dashboard/widgets/sign_form.dart
Normal file
116
lib/src/screens/dashboard/widgets/sign_form.dart
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
import 'package:cake_wallet/core/wallet_name_validator.dart';
|
||||||
|
import 'package:cake_wallet/entities/generate_name.dart';
|
||||||
|
import 'package:cake_wallet/entities/seed_type.dart';
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/address_text_field.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/seed_widget.dart';
|
||||||
|
import 'package:cake_wallet/themes/extensions/address_theme.dart';
|
||||||
|
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||||
|
import 'package:cake_wallet/utils/show_bar.dart';
|
||||||
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
|
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
|
||||||
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
import 'package:polyseed/polyseed.dart';
|
||||||
|
|
||||||
|
class SignForm extends StatefulWidget {
|
||||||
|
SignForm({
|
||||||
|
Key? key,
|
||||||
|
required this.type,
|
||||||
|
required this.includeAddress,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final WalletType type;
|
||||||
|
final bool includeAddress;
|
||||||
|
|
||||||
|
@override
|
||||||
|
SignFormState createState() => SignFormState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class SignFormState extends State<SignForm> {
|
||||||
|
SignFormState()
|
||||||
|
: formKey = GlobalKey<FormState>(),
|
||||||
|
messageController = TextEditingController(),
|
||||||
|
addressController = TextEditingController(),
|
||||||
|
signatureController = TextEditingController();
|
||||||
|
|
||||||
|
final TextEditingController messageController;
|
||||||
|
final TextEditingController addressController;
|
||||||
|
final TextEditingController signatureController;
|
||||||
|
final GlobalKey<FormState> formKey;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.only(left: 24, right: 24),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Form(
|
||||||
|
key: formKey,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
AddressTextField(
|
||||||
|
controller: messageController,
|
||||||
|
placeholder: S.current.message,
|
||||||
|
options: [AddressTextFieldOption.paste],
|
||||||
|
buttonColor: Theme.of(context).hintColor,
|
||||||
|
),
|
||||||
|
if (widget.includeAddress) ...[
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
AddressTextField(
|
||||||
|
controller: addressController,
|
||||||
|
options: [AddressTextFieldOption.paste, AddressTextFieldOption.addressBook],
|
||||||
|
buttonColor: Theme.of(context).hintColor,
|
||||||
|
onSelectedContact: (contact) {
|
||||||
|
addressController.text = contact.address;
|
||||||
|
},
|
||||||
|
selectedCurrency: walletTypeToCryptoCurrency(widget.type),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
final text = signatureController.text;
|
||||||
|
Clipboard.setData(ClipboardData(text: text));
|
||||||
|
showBar<void>(context, S.of(context).transaction_details_copied(text));
|
||||||
|
},
|
||||||
|
child: BaseTextFormField(
|
||||||
|
enabled: false,
|
||||||
|
controller: signatureController,
|
||||||
|
hintText: "T: Signature",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget get expandIcon => Container(
|
||||||
|
padding: EdgeInsets.all(18),
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/arrow_bottom_purple_icon.png',
|
||||||
|
height: 8,
|
||||||
|
color: Theme.of(context).hintColor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
109
lib/src/screens/dashboard/widgets/verify_form.dart
Normal file
109
lib/src/screens/dashboard/widgets/verify_form.dart
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
import 'package:cake_wallet/core/wallet_name_validator.dart';
|
||||||
|
import 'package:cake_wallet/entities/generate_name.dart';
|
||||||
|
import 'package:cake_wallet/entities/seed_type.dart';
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/address_text_field.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/seed_widget.dart';
|
||||||
|
import 'package:cake_wallet/themes/extensions/address_theme.dart';
|
||||||
|
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||||
|
import 'package:cake_wallet/utils/show_bar.dart';
|
||||||
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
|
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
|
||||||
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
import 'package:polyseed/polyseed.dart';
|
||||||
|
|
||||||
|
class VerifyForm extends StatefulWidget {
|
||||||
|
VerifyForm({
|
||||||
|
Key? key,
|
||||||
|
required this.type,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final WalletType type;
|
||||||
|
|
||||||
|
@override
|
||||||
|
VerifyFormState createState() => VerifyFormState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class VerifyFormState extends State<VerifyForm> {
|
||||||
|
VerifyFormState()
|
||||||
|
: formKey = GlobalKey<FormState>(),
|
||||||
|
messageController = TextEditingController(),
|
||||||
|
addressController = TextEditingController(),
|
||||||
|
signatureController = TextEditingController();
|
||||||
|
|
||||||
|
final TextEditingController messageController;
|
||||||
|
final TextEditingController addressController;
|
||||||
|
final TextEditingController signatureController;
|
||||||
|
final GlobalKey<FormState> formKey;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.only(left: 24, right: 24),
|
||||||
|
child: Form(
|
||||||
|
key: formKey,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
AddressTextField(
|
||||||
|
controller: messageController,
|
||||||
|
placeholder: S.current.message,
|
||||||
|
options: [AddressTextFieldOption.paste],
|
||||||
|
buttonColor: Theme.of(context).hintColor,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
AddressTextField(
|
||||||
|
controller: addressController,
|
||||||
|
options: [AddressTextFieldOption.paste, AddressTextFieldOption.addressBook],
|
||||||
|
buttonColor: Theme.of(context).hintColor,
|
||||||
|
onSelectedContact: (contact) {
|
||||||
|
addressController.text = contact.address;
|
||||||
|
},
|
||||||
|
selectedCurrency: walletTypeToCryptoCurrency(widget.type),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
final text = signatureController.text;
|
||||||
|
Clipboard.setData(ClipboardData(text: text));
|
||||||
|
showBar<void>(context, S.of(context).transaction_details_copied(text));
|
||||||
|
},
|
||||||
|
child: BaseTextFormField(
|
||||||
|
enabled: false,
|
||||||
|
controller: signatureController,
|
||||||
|
hintText: "T: Signature",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget get expandIcon => Container(
|
||||||
|
padding: EdgeInsets.all(18),
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/arrow_bottom_purple_icon.png',
|
||||||
|
height: 8,
|
||||||
|
color: Theme.of(context).hintColor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
|
@ -371,7 +371,7 @@ abstract class DashboardViewModelBase with Store {
|
||||||
bool get hasPowNodes => wallet.type == WalletType.nano || wallet.type == WalletType.banano;
|
bool get hasPowNodes => wallet.type == WalletType.nano || wallet.type == WalletType.banano;
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
bool get hasSignMessages => [WalletType.monero].contains(wallet.type);
|
bool get hasSignMessages => [WalletType.monero, WalletType.solana].contains(wallet.type);
|
||||||
|
|
||||||
Future<void> reconnect() async {
|
Future<void> reconnect() async {
|
||||||
final node = appStore.settingsStore.getCurrentNode(wallet.type);
|
final node = appStore.settingsStore.getCurrentNode(wallet.type);
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
import 'package:cake_wallet/core/execution_state.dart';
|
||||||
import 'package:cw_core/receive_page_option.dart';
|
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
@ -9,7 +8,40 @@ part 'sign_view_model.g.dart';
|
||||||
class SignViewModel = SignViewModelBase with _$SignViewModel;
|
class SignViewModel = SignViewModelBase with _$SignViewModel;
|
||||||
|
|
||||||
abstract class SignViewModelBase with Store {
|
abstract class SignViewModelBase with Store {
|
||||||
SignViewModelBase(this._wallet) {}
|
SignViewModelBase(this.wallet) : state = InitialExecutionState();
|
||||||
|
|
||||||
final WalletBase _wallet;
|
final WalletBase wallet;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
ExecutionState state;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
bool isSigning = true;
|
||||||
|
|
||||||
|
bool get signIncludesAddress => [
|
||||||
|
WalletType.monero,
|
||||||
|
WalletType.haven,
|
||||||
|
].contains(wallet.type);
|
||||||
|
|
||||||
|
@action
|
||||||
|
Future<void> sign(String message, {String? address}) async {
|
||||||
|
state = IsExecutingState();
|
||||||
|
try {
|
||||||
|
final signature = await wallet.signMessage(message, address: address);
|
||||||
|
state = ExecutedSuccessfullyState(payload: signature);
|
||||||
|
} catch (e) {
|
||||||
|
state = FailureState(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
Future<void> verify(String message, String signature, {String? address}) async {
|
||||||
|
// state = IsExecutingState();
|
||||||
|
// try {
|
||||||
|
// final signature = await wallet.verifyMessage(message, address: address);
|
||||||
|
// state = ExecutedSuccessfullyState(payload: signature);
|
||||||
|
// } catch (e) {
|
||||||
|
// state = FailureState(e.toString());
|
||||||
|
// }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue