Skip to main content

mnemonic_backup_flow 0.1.0 copy "mnemonic_backup_flow: ^0.1.0" to clipboard
mnemonic_backup_flow: ^0.1.0 copied to clipboard

Recovery-phrase reveal, verification and import screens for Flutter wallets, with a PIN gate, screenshot-protection hooks, random-word checks and clipboard clearing.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:mnemonic_backup_flow/mnemonic_backup_flow.dart';

void main() {
  runApp(const ExampleApp());
}

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'mnemonic_backup_flow example',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _status = 'No phrase yet.';

  // A real app wraps the screenshot plugin it already uses, for example:
  //   ScreenProtection.callbacks(
  //     protect: () => NoScreenshot.instance.screenshotOff(),
  //     release: () => NoScreenshot.instance.screenshotOn(),
  //   )
  // ScreenProtection.none() leaves the phrase visible to screenshots and belongs in a demo only.
  static const _screenProtection = ScreenProtection.none();

  Future<void> _backUpNewPhrase() async {
    final words = MnemonicWords.generate(wordCount: 12);
    final result = await showMnemonicBackupFlow(
      context,
      words: words,
      screenProtection: _screenProtection,
      authenticate: _askDemoPin,
    );
    if (!mounted) {
      return;
    }
    setState(
      () => _status = 'Backup of a ${words.length}-word phrase: ${result.name}',
    );
  }

  Future<void> _importPhrase() async {
    final words = await Navigator.of(context).push<MnemonicWords>(
      MaterialPageRoute<MnemonicWords>(
        fullscreenDialog: true,
        builder: (context) => MnemonicImportScreen(
          screenProtection: _screenProtection,
          onImported: (words) => Navigator.of(context).pop(words),
        ),
      ),
    );
    if (!mounted) {
      return;
    }
    setState(
      () => _status = words == null
          ? 'Import cancelled.'
          : 'Imported a ${words.length}-word phrase.',
    );
  }

  /// Stands in for the app's PIN or biometric check. Any four digits pass here; a real check
  /// compares against a stored hash or calls local_auth.
  Future<bool> _askDemoPin(BuildContext context) async {
    final entered = await showDialog<String>(
      context: context,
      builder: (context) {
        final controller = TextEditingController();
        return AlertDialog(
          title: const Text('Enter your PIN (demo)'),
          content: TextField(
            controller: controller,
            obscureText: true,
            keyboardType: TextInputType.number,
            maxLength: 4,
            autofocus: true,
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(context).pop(),
              child: const Text('Cancel'),
            ),
            FilledButton(
              onPressed: () => Navigator.of(context).pop(controller.text),
              child: const Text('Unlock'),
            ),
          ],
        );
      },
    );
    return entered != null && RegExp(r'^\d{4}$').hasMatch(entered);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('mnemonic_backup_flow')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text(_status),
            const SizedBox(height: 24),
            FilledButton(
              onPressed: _backUpNewPhrase,
              child: const Text('Back up a new phrase'),
            ),
            const SizedBox(height: 8),
            OutlinedButton(
              onPressed: _importPhrase,
              child: const Text('Import a phrase'),
            ),
          ],
        ),
      ),
    );
  }
}
2
likes
160
points
485
downloads

Documentation

API reference

Publisher

verified publisherglobalmpc.tech

Weekly Downloads

Recovery-phrase reveal, verification and import screens for Flutter wallets, with a PIN gate, screenshot-protection hooks, random-word checks and clipboard clearing.

Repository (GitHub)
View/report issues
Contributing

Topics

#wallet #bip39 #mnemonic #security #rwa

License

MIT (license)

Dependencies

bip39_mnemonic, flutter

More

Packages that depend on mnemonic_backup_flow