Update example app on Flutter plugin (#220)

* Update example app on Flutter plugin

* Expose `empty_wallet_cache` through Dart bindings (#224)
This commit is contained in:
Erdem Yerebasmaz
2024-05-24 12:12:29 +03:00
committed by GitHub
parent c7b46314f4
commit 7b1b78a2d9
38 changed files with 1821 additions and 167 deletions

View File

@@ -0,0 +1,108 @@
import 'package:bip39/bip39.dart';
import 'package:flutter/material.dart';
import 'package:flutter_breez_liquid/flutter_breez_liquid.dart';
import 'package:flutter_breez_liquid_example/routes/connect/restore_page.dart';
import 'package:flutter_breez_liquid_example/routes/home/home_page.dart';
import 'package:flutter_breez_liquid_example/services/credentials_manager.dart';
import 'package:path_provider/path_provider.dart';
class ConnectPage extends StatefulWidget {
final CredentialsManager credentialsManager;
const ConnectPage({super.key, required this.credentialsManager});
@override
State<ConnectPage> createState() => _ConnectPageState();
}
class _ConnectPageState extends State<ConnectPage> {
bool connecting = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Breez Liquid SDK Demo'),
foregroundColor: Colors.blue,
),
body: Center(
child: connecting
? const CircularProgressIndicator(color: Colors.blue)
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: SizedBox(
width: 200,
child: ElevatedButton(
child: const Text("Create new wallet"),
onPressed: () async {
await createWallet();
},
),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: SizedBox(
width: 200,
child: ElevatedButton(
child: const Text("Restore from backup"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return RestorePage(
onRestore: (mnemonic) async {
return await createWallet(mnemonic: mnemonic);
},
);
},
),
);
},
),
),
)
],
),
),
),
);
}
Future<Null> createWallet({String? mnemonic}) async {
final walletMnemonic = mnemonic ??= generateMnemonic(strength: 128);
debugPrint("${mnemonic.isEmpty ? "Creating" : "Restoring"} wallet with $walletMnemonic");
return await initializeWallet(mnemonic: walletMnemonic).then(
(liquidSDK) async {
await widget.credentialsManager.storeMnemonic(mnemonic: walletMnemonic).then((_) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (BuildContext context) => HomePage(
liquidSDK: liquidSDK,
credentialsManager: widget.credentialsManager,
),
),
);
});
},
);
}
Future<BindingLiquidSdk> initializeWallet({
required String mnemonic,
Network network = Network.liquid,
}) async {
final dataDir = await getApplicationDocumentsDirectory();
final req = ConnectRequest(
mnemonic: mnemonic,
dataDir: dataDir.path,
network: network,
);
return await connect(req: req);
}
}

View File

@@ -0,0 +1,104 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class RestorePage extends StatefulWidget {
final Future Function(String mnemonic) onRestore;
const RestorePage({super.key, required this.onRestore});
@override
State<RestorePage> createState() => _RestorePageState();
}
class _RestorePageState extends State<RestorePage> {
final _formKey = GlobalKey<FormState>();
List<TextEditingController> textFieldControllers =
List<TextEditingController>.generate(12, (_) => TextEditingController());
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
actions: [
IconButton(
onPressed: () async {
final clipboardData = await Clipboard.getData('text/plain');
final clipboardMnemonics = clipboardData?.text?.split(" ");
if (clipboardMnemonics?.length == 12) {
for (var i = 0; i < clipboardMnemonics!.length; i++) {
textFieldControllers.elementAt(i).text = clipboardMnemonics.elementAt(i);
}
}
},
icon: const Icon(Icons.paste, color: Colors.blue),
),
],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Form(
key: _formKey,
child: GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: MediaQuery.of(context).size.width / 2,
childAspectRatio: 2,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
itemCount: 12,
itemBuilder: (BuildContext context, int index) {
return TextFormField(
decoration: InputDecoration(labelText: "${index + 1}"),
inputFormatters: [FilteringTextInputFormatter.deny(RegExp(r"\s\b|\b\s"))],
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Please enter value';
}
return null;
},
controller: textFieldControllers[index],
);
},
),
),
),
bottomNavigationBar: Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom + 40.0,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
elevation: 0.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
onPressed: () async {
if (_formKey.currentState?.validate() ?? false) {
final mnemonic = textFieldControllers
.map((controller) => controller.text.toLowerCase().trim())
.toList()
.join(" ");
widget.onRestore(mnemonic);
}
},
child: Text(
"RESTORE",
textAlign: TextAlign.center,
style: Theme.of(context).primaryTextTheme.titleMedium,
maxLines: 1,
),
),
],
),
),
),
);
}
}