Implement identity workflow
This commit is contained in:
parent
adcb876203
commit
14f784fdc9
|
@ -7,6 +7,9 @@ import 'package:hive/hive.dart';
|
||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
// Version of box data
|
||||||
|
const int dataVersion = 1;
|
||||||
|
|
||||||
// Files paths
|
// Files paths
|
||||||
Directory? appPath;
|
Directory? appPath;
|
||||||
|
|
||||||
|
|
|
@ -5,28 +5,32 @@ part 'wallet_data.g.dart';
|
||||||
@HiveType(typeId: 0)
|
@HiveType(typeId: 0)
|
||||||
class WalletData extends HiveObject {
|
class WalletData extends HiveObject {
|
||||||
@HiveField(0)
|
@HiveField(0)
|
||||||
int? chest;
|
int? version;
|
||||||
|
|
||||||
@HiveField(1)
|
@HiveField(1)
|
||||||
String? address;
|
int? chest;
|
||||||
|
|
||||||
@HiveField(2)
|
@HiveField(2)
|
||||||
int? number;
|
String? address;
|
||||||
|
|
||||||
@HiveField(3)
|
@HiveField(3)
|
||||||
String? name;
|
int? number;
|
||||||
|
|
||||||
@HiveField(4)
|
@HiveField(4)
|
||||||
int? derivation;
|
String? name;
|
||||||
|
|
||||||
@HiveField(5)
|
@HiveField(5)
|
||||||
String? imageName;
|
int? derivation;
|
||||||
|
|
||||||
@HiveField(6)
|
@HiveField(6)
|
||||||
|
String? imageName;
|
||||||
|
|
||||||
|
@HiveField(7)
|
||||||
File? imageFile;
|
File? imageFile;
|
||||||
|
|
||||||
WalletData(
|
WalletData(
|
||||||
{this.chest,
|
{this.version,
|
||||||
|
this.chest,
|
||||||
this.address,
|
this.address,
|
||||||
this.number,
|
this.number,
|
||||||
this.name,
|
this.name,
|
||||||
|
|
|
@ -17,33 +17,36 @@ class WalletDataAdapter extends TypeAdapter<WalletData> {
|
||||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||||
};
|
};
|
||||||
return WalletData(
|
return WalletData(
|
||||||
chest: fields[0] as int?,
|
version: fields[0] as int?,
|
||||||
address: fields[1] as String?,
|
chest: fields[1] as int?,
|
||||||
number: fields[2] as int?,
|
address: fields[2] as String?,
|
||||||
name: fields[3] as String?,
|
number: fields[3] as int?,
|
||||||
derivation: fields[4] as int?,
|
name: fields[4] as String?,
|
||||||
imageName: fields[5] as String?,
|
derivation: fields[5] as int?,
|
||||||
imageFile: fields[6] as File?,
|
imageName: fields[6] as String?,
|
||||||
|
imageFile: fields[7] as File?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void write(BinaryWriter writer, WalletData obj) {
|
void write(BinaryWriter writer, WalletData obj) {
|
||||||
writer
|
writer
|
||||||
..writeByte(7)
|
..writeByte(8)
|
||||||
..writeByte(0)
|
..writeByte(0)
|
||||||
..write(obj.chest)
|
..write(obj.version)
|
||||||
..writeByte(1)
|
..writeByte(1)
|
||||||
..write(obj.address)
|
..write(obj.chest)
|
||||||
..writeByte(2)
|
..writeByte(2)
|
||||||
..write(obj.number)
|
..write(obj.address)
|
||||||
..writeByte(3)
|
..writeByte(3)
|
||||||
..write(obj.name)
|
..write(obj.number)
|
||||||
..writeByte(4)
|
..writeByte(4)
|
||||||
..write(obj.derivation)
|
..write(obj.name)
|
||||||
..writeByte(5)
|
..writeByte(5)
|
||||||
..write(obj.imageName)
|
..write(obj.derivation)
|
||||||
..writeByte(6)
|
..writeByte(6)
|
||||||
|
..write(obj.imageName)
|
||||||
|
..writeByte(7)
|
||||||
..write(obj.imageFile);
|
..write(obj.imageFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,9 @@ import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gecko/globals.dart';
|
import 'package:gecko/globals.dart';
|
||||||
import 'package:gecko/models/chest_data.dart';
|
import 'package:gecko/models/chest_data.dart';
|
||||||
|
import 'package:gecko/models/wallet_data.dart';
|
||||||
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ChestProvider with ChangeNotifier {
|
class ChestProvider with ChangeNotifier {
|
||||||
void rebuildWidget() {
|
void rebuildWidget() {
|
||||||
|
@ -10,8 +13,9 @@ class ChestProvider with ChangeNotifier {
|
||||||
|
|
||||||
Future deleteChest(context, ChestData _chest) async {
|
Future deleteChest(context, ChestData _chest) async {
|
||||||
final bool? _answer = await (_confirmDeletingChest(context, _chest.name));
|
final bool? _answer = await (_confirmDeletingChest(context, _chest.name));
|
||||||
|
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||||
if (_answer!) {
|
if (_answer!) {
|
||||||
|
await _sub.deleteAccounts(getChestWallets(_chest));
|
||||||
await chestBox.delete(_chest.key);
|
await chestBox.delete(_chest.key);
|
||||||
if (chestBox.isEmpty) {
|
if (chestBox.isEmpty) {
|
||||||
await configBox.put('currentChest', 0);
|
await configBox.put('currentChest', 0);
|
||||||
|
@ -28,6 +32,17 @@ class ChestProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> getChestWallets(ChestData _chest) {
|
||||||
|
List<String> toDelete = [];
|
||||||
|
log.d(_chest.key);
|
||||||
|
walletBox.toMap().forEach((key, WalletData value) {
|
||||||
|
if (value.chest == _chest.key) {
|
||||||
|
toDelete.add(value.address!);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return toDelete;
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool?> _confirmDeletingChest(context, String? _walletName) async {
|
Future<bool?> _confirmDeletingChest(context, String? _walletName) async {
|
||||||
return showDialog<bool>(
|
return showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
|
@ -81,6 +81,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
int? chestKey = chestBox.keys.last;
|
int? chestKey = chestBox.keys.last;
|
||||||
|
|
||||||
WalletData myWallet = WalletData(
|
WalletData myWallet = WalletData(
|
||||||
|
version: dataVersion,
|
||||||
chest: chestKey,
|
chest: chestKey,
|
||||||
address: address,
|
address: address,
|
||||||
number: 0,
|
number: 0,
|
||||||
|
|
|
@ -169,6 +169,7 @@ class MyWalletsProvider with ChangeNotifier {
|
||||||
context, _currentChest.address!, _newDerivationNbr, pinCode);
|
context, _currentChest.address!, _newDerivationNbr, pinCode);
|
||||||
|
|
||||||
WalletData newWallet = WalletData(
|
WalletData newWallet = WalletData(
|
||||||
|
version: dataVersion,
|
||||||
chest: _chest,
|
chest: _chest,
|
||||||
address: address,
|
address: address,
|
||||||
number: _newWalletNbr,
|
number: _newWalletNbr,
|
||||||
|
|
|
@ -232,6 +232,13 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> deleteAccounts(List<String> address) async {
|
||||||
|
for (var a in address) {
|
||||||
|
final account = getKeypair(a);
|
||||||
|
await sdk.api.keyring.deleteAccount(keyring, account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<String> generateMnemonic({String lang = appLang}) async {
|
Future<String> generateMnemonic({String lang = appLang}) async {
|
||||||
final gen = await sdk.api.keyring.generateMnemonic(ss58);
|
final gen = await sdk.api.keyring.generateMnemonic(ss58);
|
||||||
generatedMnemonic = gen.mnemonic!;
|
generatedMnemonic = gen.mnemonic!;
|
||||||
|
@ -294,6 +301,11 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
required String password}) async {
|
required String password}) async {
|
||||||
setCurrentWallet(fromAddress);
|
setCurrentWallet(fromAddress);
|
||||||
|
|
||||||
|
log.d(keyring.current.address);
|
||||||
|
log.d(fromAddress);
|
||||||
|
log.d(password);
|
||||||
|
log.d(await checkPassword(fromAddress, password));
|
||||||
|
|
||||||
final sender = TxSenderData(
|
final sender = TxSenderData(
|
||||||
keyring.current.address,
|
keyring.current.address,
|
||||||
keyring.current.pubKey,
|
keyring.current.pubKey,
|
||||||
|
@ -318,25 +330,76 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String> idtyStatus(String address) async {
|
||||||
|
// var tata = await sdk.webView!
|
||||||
|
// .evalJavascript('api.query.system.account("$address")');
|
||||||
|
|
||||||
|
var idtyIndex = await sdk.webView!
|
||||||
|
.evalJavascript('api.query.identity.identityIndexOf("$address")');
|
||||||
|
|
||||||
|
if (idtyIndex == null) {
|
||||||
|
return 'noid';
|
||||||
|
}
|
||||||
|
|
||||||
|
final idtyStatus = await sdk.webView!
|
||||||
|
.evalJavascript('api.query.identity.identities($idtyIndex)');
|
||||||
|
|
||||||
|
if (idtyStatus != null) {
|
||||||
|
final String _status = idtyStatus['status'];
|
||||||
|
log.d(_status);
|
||||||
|
return (_status);
|
||||||
|
} else {
|
||||||
|
return 'expired';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> confirmIdentity(
|
||||||
|
String address, String name, String password) async {
|
||||||
|
// Confirm identity
|
||||||
|
setCurrentWallet(address);
|
||||||
|
log.d('idty: ' + keyring.current.address!);
|
||||||
|
|
||||||
|
final sender = TxSenderData(
|
||||||
|
keyring.current.address,
|
||||||
|
keyring.current.pubKey,
|
||||||
|
);
|
||||||
|
|
||||||
|
final txInfo = TxInfoData(
|
||||||
|
'identity',
|
||||||
|
'confirmIdentity',
|
||||||
|
sender,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final tata = await sdk.api.tx.signAndSend(
|
||||||
|
txInfo,
|
||||||
|
[name],
|
||||||
|
password,
|
||||||
|
);
|
||||||
|
log.d(tata);
|
||||||
|
return 'confirmed';
|
||||||
|
} on Exception catch (e) {
|
||||||
|
log.e(e);
|
||||||
|
// if (e.toString() == 'Exception: password check failed') {
|
||||||
|
// throw PasswordException('Bad password');
|
||||||
|
// }
|
||||||
|
return e.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<String> derive(
|
Future<String> derive(
|
||||||
BuildContext context, String address, int number, String password) async {
|
BuildContext context, String address, int number, String password) async {
|
||||||
final keypair = getKeypair(address);
|
final keypair = getKeypair(address);
|
||||||
|
|
||||||
final seedMap =
|
final seedMap =
|
||||||
await keyring.store.getDecryptedSeed(keypair.pubKey, password);
|
await keyring.store.getDecryptedSeed(keypair.pubKey, password);
|
||||||
print(seedMap);
|
|
||||||
|
|
||||||
if (seedMap?['type'] != 'mnemonic') return '';
|
if (seedMap?['type'] != 'mnemonic') return '';
|
||||||
final List seedList = seedMap!['seed'].split('//');
|
final List seedList = seedMap!['seed'].split('//');
|
||||||
generatedMnemonic = seedList[0];
|
generatedMnemonic = seedList[0];
|
||||||
int sourceDerivation = -1; // To get derivation number of this account
|
|
||||||
if (seedList.length > 1) {
|
|
||||||
sourceDerivation = int.parse(seedList[1]);
|
|
||||||
}
|
|
||||||
print(generatedMnemonic);
|
|
||||||
print(sourceDerivation);
|
|
||||||
|
|
||||||
return await importAccount(fromMnemonic: true, derivePath: '//$number');
|
return await importAccount(
|
||||||
|
fromMnemonic: true, derivePath: '//$number', password: password);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> isMnemonicValid(String mnemonic) async {
|
Future<bool> isMnemonicValid(String mnemonic) async {
|
||||||
|
@ -392,3 +455,8 @@ String getShortPubkey(String pubkey) {
|
||||||
|
|
||||||
return pubkeyShort;
|
return pubkeyShort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PasswordException implements Exception {
|
||||||
|
String cause;
|
||||||
|
PasswordException(this.cause);
|
||||||
|
}
|
||||||
|
|
|
@ -148,6 +148,124 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget idtyStatus(BuildContext context, String address,
|
||||||
|
{bool isOwner = false}) {
|
||||||
|
return Consumer<SubstrateSdk>(builder: (context, _sub, _) {
|
||||||
|
return FutureBuilder(
|
||||||
|
future: _sub.idtyStatus(address),
|
||||||
|
initialData: '...',
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
switch (snapshot.data.toString()) {
|
||||||
|
case 'noid':
|
||||||
|
{
|
||||||
|
return Column(children: const <Widget>[
|
||||||
|
Text(
|
||||||
|
'Aucune identité',
|
||||||
|
style: TextStyle(fontSize: 18, color: Colors.black),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
case 'Created':
|
||||||
|
{
|
||||||
|
return Column(children: <Widget>[
|
||||||
|
isOwner
|
||||||
|
? InkWell(
|
||||||
|
child: const Text(
|
||||||
|
'Identité créé, cliquez pour la confirmer',
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 18, color: Colors.black),
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
await validateIdentity(context);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: const Text(
|
||||||
|
'Identité créé',
|
||||||
|
style: TextStyle(fontSize: 18, color: Colors.black),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
case 'ConfirmedByOwner':
|
||||||
|
{
|
||||||
|
return Column(children: const <Widget>[
|
||||||
|
Text(
|
||||||
|
'Identité confirmé',
|
||||||
|
style: TextStyle(fontSize: 18, color: Colors.black),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'Validated':
|
||||||
|
{
|
||||||
|
return Column(children: const <Widget>[
|
||||||
|
Text(
|
||||||
|
'Membre validé !',
|
||||||
|
style: TextStyle(fontSize: 18, color: Colors.black),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'expired':
|
||||||
|
{
|
||||||
|
return Column(children: const <Widget>[
|
||||||
|
Text(
|
||||||
|
'Identité expiré',
|
||||||
|
style: TextStyle(fontSize: 18, color: Colors.black),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SizedBox(
|
||||||
|
width: 230,
|
||||||
|
child: Column(children: const <Widget>[
|
||||||
|
Text(
|
||||||
|
'Statut inconnu',
|
||||||
|
style: TextStyle(fontSize: 18, color: Colors.black),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String?> validateIdentity(BuildContext context) async {
|
||||||
|
TextEditingController idtyName = TextEditingController();
|
||||||
|
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||||
|
WalletOptionsProvider _walletOptions =
|
||||||
|
Provider.of<WalletOptionsProvider>(context, listen: false);
|
||||||
|
MyWalletsProvider _myWalletProvider =
|
||||||
|
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||||
|
|
||||||
|
return showDialog<String>(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: true, // user must tap button!
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('Confirmez votre identité'),
|
||||||
|
content: SizedBox(
|
||||||
|
height: 100,
|
||||||
|
child: Column(children: [
|
||||||
|
const Text('Nom:'),
|
||||||
|
TextField(
|
||||||
|
controller: idtyName,
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
child: const Text("Valider"),
|
||||||
|
onPressed: () async {
|
||||||
|
_sub.confirmIdentity(_walletOptions.address.text, idtyName.text,
|
||||||
|
_myWalletProvider.pinCode);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void reloadBuild() {
|
void reloadBuild() {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
@ -167,9 +285,10 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget balance(BuildContext context, String address, double size) {
|
// Map<String, String> balanceCache = {};
|
||||||
String balanceCache = '';
|
String balanceCache = '';
|
||||||
|
|
||||||
|
Widget balance(BuildContext context, String address, double size) {
|
||||||
return Column(children: <Widget>[
|
return Column(children: <Widget>[
|
||||||
Consumer<SubstrateSdk>(builder: (context, _sdk, _) {
|
Consumer<SubstrateSdk>(builder: (context, _sdk, _) {
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
|
|
|
@ -58,7 +58,7 @@ class ChooseWalletScreen extends StatelessWidget {
|
||||||
destAddress: _walletViewProvider.outputPubkey.text,
|
destAddress: _walletViewProvider.outputPubkey.text,
|
||||||
amount:
|
amount:
|
||||||
double.parse(_walletViewProvider.payAmount.text),
|
double.parse(_walletViewProvider.payAmount.text),
|
||||||
password: pin);
|
password: pin.toUpperCase());
|
||||||
await paymentsResult(context, resultPay);
|
await paymentsResult(context, resultPay);
|
||||||
},
|
},
|
||||||
child: const Text(
|
child: const Text(
|
||||||
|
|
|
@ -140,8 +140,9 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
|
||||||
fromMnemonic: true,
|
fromMnemonic: true,
|
||||||
mnemonic: _generateWalletProvider
|
mnemonic: _generateWalletProvider
|
||||||
.generatedMnemonic!,
|
.generatedMnemonic!,
|
||||||
password:
|
password: _generateWalletProvider
|
||||||
_generateWalletProvider.pin.text,
|
.pin.text
|
||||||
|
.toUpperCase(),
|
||||||
derivePath: '//2');
|
derivePath: '//2');
|
||||||
await _generateWalletProvider.storeHDWChest(
|
await _generateWalletProvider.storeHDWChest(
|
||||||
address,
|
address,
|
||||||
|
|
|
@ -26,7 +26,7 @@ class GenerateFastChestScreen extends StatelessWidget {
|
||||||
|
|
||||||
_generateWalletProvider.pin.text = kDebugMode && debugPin
|
_generateWalletProvider.pin.text = kDebugMode && debugPin
|
||||||
? 'AAAAA'
|
? 'AAAAA'
|
||||||
: _generateWalletProvider.changePinCode(reload: false);
|
: _generateWalletProvider.changePinCode(reload: false).toUpperCase();
|
||||||
|
|
||||||
return WillPopScope(
|
return WillPopScope(
|
||||||
onWillPop: () {
|
onWillPop: () {
|
||||||
|
|
|
@ -90,6 +90,10 @@ class WalletOptions extends StatelessWidget {
|
||||||
walletName(walletProvider, _walletOptions),
|
walletName(walletProvider, _walletOptions),
|
||||||
SizedBox(height: isTall ? 5 : 0),
|
SizedBox(height: isTall ? 5 : 0),
|
||||||
balance(context, walletProvider.address.text, 20),
|
balance(context, walletProvider.address.text, 20),
|
||||||
|
SizedBox(height: isTall ? 5 : 0),
|
||||||
|
_walletOptions.idtyStatus(
|
||||||
|
context, _walletOptions.address.text,
|
||||||
|
isOwner: true),
|
||||||
]),
|
]),
|
||||||
const Spacer(flex: 3),
|
const Spacer(flex: 3),
|
||||||
]),
|
]),
|
||||||
|
@ -212,8 +216,8 @@ class WalletOptions extends StatelessWidget {
|
||||||
walletProvider.isEditing
|
walletProvider.isEditing
|
||||||
? 'assets/walletOptions/android-checkmark.png'
|
? 'assets/walletOptions/android-checkmark.png'
|
||||||
: 'assets/walletOptions/edit.png',
|
: 'assets/walletOptions/edit.png',
|
||||||
width: 20,
|
width: 25,
|
||||||
height: 20),
|
height: 25),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -23,7 +23,7 @@ class OnboardingStepThirteen extends StatelessWidget {
|
||||||
|
|
||||||
_generateWalletProvider.pin.text = kDebugMode && debugPin
|
_generateWalletProvider.pin.text = kDebugMode && debugPin
|
||||||
? 'AAAAA'
|
? 'AAAAA'
|
||||||
: _generateWalletProvider.changePinCode(reload: false);
|
: _generateWalletProvider.changePinCode(reload: false).toUpperCase();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
|
|
@ -27,7 +27,6 @@ class WalletViewScreen extends StatelessWidget {
|
||||||
Provider.of<WalletsProfilesProvider>(context, listen: false);
|
Provider.of<WalletsProfilesProvider>(context, listen: false);
|
||||||
CesiumPlusProvider _cesiumPlusProvider =
|
CesiumPlusProvider _cesiumPlusProvider =
|
||||||
Provider.of<CesiumPlusProvider>(context, listen: false);
|
Provider.of<CesiumPlusProvider>(context, listen: false);
|
||||||
|
|
||||||
_historyProvider.pubkey = pubkey!;
|
_historyProvider.pubkey = pubkey!;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -285,21 +284,21 @@ class WalletViewScreen extends StatelessWidget {
|
||||||
primary: orangeC, // background
|
primary: orangeC, // background
|
||||||
onPrimary: Colors.white, // foreground
|
onPrimary: Colors.white, // foreground
|
||||||
),
|
),
|
||||||
onPressed: _walletViewProvider.payAmount.text !=
|
onPressed:
|
||||||
''
|
_walletViewProvider.payAmount.text != ''
|
||||||
? () {
|
? () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return UnlockingWallet(
|
return UnlockingWallet(
|
||||||
wallet: defaultWallet,
|
wallet: defaultWallet,
|
||||||
action: "pay");
|
action: "pay");
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: const Text(
|
child: const Text(
|
||||||
'Effectuer le virement',
|
'Effectuer le virement',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
@ -325,6 +324,9 @@ class WalletViewScreen extends StatelessWidget {
|
||||||
CesiumPlusProvider _cesiumPlusProvider) {
|
CesiumPlusProvider _cesiumPlusProvider) {
|
||||||
const double _avatarSize = 140;
|
const double _avatarSize = 140;
|
||||||
|
|
||||||
|
WalletOptionsProvider _walletOptions =
|
||||||
|
Provider.of<WalletOptionsProvider>(context, listen: false);
|
||||||
|
|
||||||
return Column(children: <Widget>[
|
return Column(children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
height: 10,
|
height: 10,
|
||||||
|
@ -365,9 +367,11 @@ class WalletViewScreen extends StatelessWidget {
|
||||||
const SizedBox(height: 25),
|
const SizedBox(height: 25),
|
||||||
Consumer<WalletOptionsProvider>(
|
Consumer<WalletOptionsProvider>(
|
||||||
builder: (context, walletProvider, _) {
|
builder: (context, walletProvider, _) {
|
||||||
return balance(context, pubkey!, 20);
|
return balance(context, pubkey!, 22);
|
||||||
}),
|
}),
|
||||||
////
|
const SizedBox(height: 10),
|
||||||
|
_walletOptions.idtyStatus(context, pubkey!, isOwner: false),
|
||||||
|
|
||||||
// if (username == null &&
|
// if (username == null &&
|
||||||
// g1WalletsBox.get(pubkey)?.username == null)
|
// g1WalletsBox.get(pubkey)?.username == null)
|
||||||
// Query(
|
// Query(
|
||||||
|
|
Loading…
Reference in New Issue