git / moonbite-network / mobile/lib/wallet/secure_clipboard.dart · raw

import 'dart:async';import 'package:flutter/services.dart';/// Copies short-lived secrets (like a recovery phrase) to the clipboard and/// automatically wipes them after a delay.////// A recovery phrase left on the clipboard is readable by every other app and/// survives until overwritten. We clear it after [clearAfter], but only if the/// clipboard STILL holds our secret — if the user copied something else in the/// meantime we must not stomp on their new clipboard contents.////// The [SystemClipboard] read/write functions are injected so the auto-clear/// logic can be unit-tested without a running Flutter engine.class SecureClipboard {  SecureClipboard({    Duration? clearAfter,    Future<void> Function(String text)? write,    Future<String?> Function()? read,  })  : clearAfter = clearAfter ?? const Duration(seconds: 30),        _write = write ?? _defaultWrite,        _read = read ?? _defaultRead;  final Duration clearAfter;  final Future<void> Function(String text) _write;  final Future<String?> Function() _read;  static Future<void> _defaultWrite(String text) =>      Clipboard.setData(ClipboardData(text: text));  static Future<String?> _defaultRead() async =>      (await Clipboard.getData(Clipboard.kTextPlain))?.text;  /// Copies [secret], then schedules a wipe. Returns the pending clear so  /// callers (and tests) can await it. The returned future resolves to `true`  /// if the clipboard was actually cleared, or `false` if it had already  /// changed and was left untouched.  Future<bool> copyEphemeral(String secret) async {    await _write(secret);    return Future<bool>.delayed(clearAfter, () async {      final current = await _read();      if (current == secret) {        await _write('');        return true;      }      return false;    });  }}