drifter_app/lib/pages/create_account_screen/create_account_screen.dart

253 lines
9.7 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:dart_nostr/dart_nostr.dart';
import 'package:drifter/models/models.dart';
import 'package:drifter/pages/home_screen/widgets/message_text_button_widget.dart';
import 'package:drifter/pages/profile_screen/profile_screen.dart';
import 'package:drifter/pages/profile_screen/profile_screen.dart';
import 'package:drifter/pages/profile_screen/widgets/keys_option_modal_bottom_sheet.dart';
import 'package:drifter/pages/profile_screen/widgets/message_snack_bar.dart';
import 'package:drifter/pages/profile_screen/widgets/ok_button_widget.dart';
import 'package:drifter/widgets/btn_continue.dart';
import 'package:drifter/theme/app_colors.dart';
import 'package:drifter/utilities/assets.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_svg/svg.dart';
import 'package:nostr_tools/nostr_tools.dart';
import 'package:sliding_switch/sliding_switch.dart';
import 'package:toggle_switch/toggle_switch.dart';
class CreateAccountScreen extends StatefulWidget {
const CreateAccountScreen({super.key});
@override
State<CreateAccountScreen> createState() => CreateAccountScreenState();
}
class CreateAccountScreenState extends State<CreateAccountScreen> {
final secureStorage = const FlutterSecureStorage();
Future<bool> generateNewKeys() async {
final newPrivateKey = await Nostr.instance.keysService.generatePrivateKey();
// final newPrivateKey = keyGenerator.generatePrivateKey();
final nsec =
Nostr.instance.keysService.encodePrivateKeyToNsec(newPrivateKey);
// final nsecDecoded =
// Nostr.instance.keysService.decodeNsecKeyToPrivateKey(nsec);
// assert(nsecDecoded['type'] == 'nsec');
// assert(nsecDecoded['data'] == newPrivateKey);
final newPublicKey = await Nostr.instance.keysService
.derivePublicKey(privateKey: newPrivateKey);
// final newPublicKey = keyGenerator.getPublicKey(newPrivateKey);
final npub = Nostr.instance.keysService.encodePublicKeyToNpub(newPublicKey);
// final npubDecoded =
// Nostr.instance.keysService.decodeNpubKeyToPublicKey(npub);
// assert(npubDecoded['type'] == 'npub');
// assert(npubDecoded['data'] == newPublicKey);
return await addKeyToStorage(newPrivateKey, newPublicKey, nsec, npub);
}
Future<void> _getKeysFromStorage() async {
// Reading values associated with the " privateKey " and " publicKey " keys from a secure repository
final storedPrivateKey = await secureStorage.read(key: 'privateKey');
final storedPublicKey = await secureStorage.read(key: 'publicKey');
final storedNsecKey = await secureStorage.read(key: 'nsec');
final storedNpubKey = await secureStorage.read(key: 'npub');
// Indicates that both private and public keys are stored in a secure repository, after which, the state variables are updated
if (storedPrivateKey != null &&
storedPublicKey != null &&
storedNsecKey != null &&
storedNpubKey != null) {
setState(() {
Keys.privateKey = storedPrivateKey;
Keys.publicKey = storedPublicKey;
Keys.nsecKey = storedNsecKey;
Keys.npubKey = storedNpubKey;
Keys.keysExist = true;
});
}
}
Future<bool> addKeyToStorage(
String privateKeyHex,
String publicKeyHex,
String nsecKey,
String npubKey,
) async {
// Waiting for both write operations to complete
Future.wait([
secureStorage.write(key: 'privateKey', value: privateKeyHex),
secureStorage.write(key: 'publicKey', value: publicKeyHex),
secureStorage.write(key: 'nsec', value: nsecKey),
secureStorage.write(key: 'npub', value: npubKey),
]);
// Updating status variables and starting widget rebuilding
setState(() {
Keys.privateKey = privateKeyHex;
Keys.publicKey = publicKeyHex;
Keys.nsecKey = nsecKey;
Keys.npubKey = npubKey;
Keys.keysExist = true;
});
// Returns a boolean value indicating whether the keys were successfully added to the repository or not.
return Keys.keysExist;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: AppColors.topNavIconBack,
),
onPressed: () => Navigator.of(context).pop(),
),
actions: <Widget>[
TextButton(
onPressed: () {},
child: Text('Skip'),
)
],
elevation: 0,
backgroundColor: AppColors.mainBackground,
),
backgroundColor: AppColors.mainBackground,
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
const Text(
'Create an account',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600),
),
const SizedBox(height: 13),
const Text(
'You can change this information later in your Profile.',
style: TextStyle(fontSize: 12, fontWeight: FontWeight.w400),
),
const SizedBox(height: 24),
TextField(
decoration: InputDecoration(
filled: true,
fillColor: AppColors.textFieldDefaultBg,
labelText: 'Username',
labelStyle: TextStyle(color: AppColors.textFieldDefaultText),
prefixIcon: const Icon(Icons.alternate_email),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
),
iconColor: AppColors.textFieldDefaultIconTrail),
controller: userNameController,
),
const SizedBox(height: 8),
TextField(
decoration: InputDecoration(
filled: true,
fillColor: AppColors.textFieldDefaultBg,
labelText: 'Name (optional)',
labelStyle: TextStyle(color: AppColors.textFieldDefaultText),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
),
iconColor: AppColors.textFieldDefaultIconTrail),
controller: nameController,
),
const SizedBox(height: 8),
SizedBox(
height: 112,
child: TextField(
minLines: 3,
maxLines: 5,
decoration: InputDecoration(
filled: true,
fillColor: AppColors.textFieldDefaultBg,
labelText: 'Description (optional)',
alignLabelWithHint: true,
labelStyle:
TextStyle(color: AppColors.textFieldDefaultText),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
),
iconColor: AppColors.textFieldDefaultIconTrail),
controller: descriptionController,
),
),
Expanded(child: SizedBox()),
SizedBox(
width: double.infinity,
height: 56,
child: ElevatedButton(
onPressed: () {
final currentContext = context;
generateNewKeys().then(
(keysGenerated) {
if (keysGenerated) {
ScaffoldMessenger.of(currentContext).showSnackBar(
MessageSnackBar(label: 'Keys Generated!'));
}
},
);
Navigator.pushNamedAndRemoveUntil(
context, '/MainScreen', (_) => false);
},
child: Text(
'Continue',
style: TextStyle(fontSize: 16),
),
style: ButtonStyle(
shape: MaterialStatePropertyAll(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100))),
backgroundColor: const MaterialStatePropertyAll(
AppColors.buttonPrimaryDefaultBg),
foregroundColor: const MaterialStatePropertyAll(
AppColors.buttonPrimaryDefaultText)),
)),
],
),
),
);
}
}
abstract class Note {
static final note = Text.rich(
TextSpan(
style: TextStyle(
height: 1.6,
fontSize: 10,
fontWeight: FontWeight.w400,
),
children: <TextSpan>[
TextSpan(
style: TextStyle(color: AppColors.noteText),
text:
"Your private key starts with “nsec” or “hex” and gives your full access to your account. That means, if you log in using your private key, you will be able to make posts and send and receive private messages.\n\n"
"Your public key starts with “npub” and gives your view-only access to account. If you log in using your public key, you wont be able to make posts or access private messages, but you will be able to view your feed. Go to “View only” tab to log in via your public key.")
]),
);
}