enh: refactor Transacation in progress screen with uuid per transaction
This commit is contained in:
parent
8ca0b00a60
commit
007d62054b
|
@ -1,7 +1,6 @@
|
|||
// ignore_for_file: use_build_context_synchronously, body_might_complete_normally_catch_error
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:fast_base58/fast_base58.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
@ -26,6 +25,7 @@ import 'package:provider/provider.dart';
|
|||
import 'package:truncate/truncate.dart';
|
||||
import 'package:pointycastle/pointycastle.dart' as pc;
|
||||
import "package:hex/hex.dart";
|
||||
import 'package:uuid/uuid.dart' show Uuid;
|
||||
|
||||
class SubstrateSdk with ChangeNotifier {
|
||||
final WalletSDK sdk = WalletSDK();
|
||||
|
@ -37,8 +37,8 @@ class SubstrateSdk with ChangeNotifier {
|
|||
bool importIsLoading = false;
|
||||
int blocNumber = 0;
|
||||
bool isLoadingEndpoint = false;
|
||||
String? transactionStatus;
|
||||
final int initSs58 = 42;
|
||||
Map transactionStatus = {};
|
||||
static const int initSs58 = 42;
|
||||
Map<String, int> currencyParameters = {};
|
||||
final csSalt = TextEditingController();
|
||||
final csPassword = TextEditingController();
|
||||
|
@ -52,18 +52,23 @@ class SubstrateSdk with ChangeNotifier {
|
|||
|
||||
/////////////////////////////////////
|
||||
////////// 1: API METHODS ///////////
|
||||
/////////////////////////////////////3
|
||||
/////////////////////////////////////
|
||||
|
||||
Future<String> _executeCall(TxInfoData txInfo, txOptions, String password,
|
||||
Future<String> _executeCall(String currentTransactionId, TxInfoData txInfo,
|
||||
txOptions, String password,
|
||||
[String? rawParams]) async {
|
||||
final walletOptions =
|
||||
Provider.of<WalletOptionsProvider>(homeContext, listen: false);
|
||||
final walletProfiles =
|
||||
Provider.of<WalletsProfilesProvider>(homeContext, listen: false);
|
||||
transactionStatus.putIfAbsent(currentTransactionId, () => 'sending');
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
final hash = await sdk.api.tx.signAndSend(txInfo, txOptions, password,
|
||||
rawParam: rawParams, onStatusChange: (p0) {
|
||||
transactionStatus = p0;
|
||||
transactionStatus.update(currentTransactionId, (_) => p0,
|
||||
ifAbsent: () => p0);
|
||||
notifyListeners();
|
||||
}).timeout(
|
||||
const Duration(seconds: 18),
|
||||
|
@ -71,20 +76,23 @@ class SubstrateSdk with ChangeNotifier {
|
|||
);
|
||||
log.d(hash);
|
||||
if (hash.isEmpty) {
|
||||
transactionStatus = 'Exception: timeout';
|
||||
transactionStatus.update(
|
||||
currentTransactionId, (_) => 'Exception: timeout');
|
||||
notifyListeners();
|
||||
|
||||
return 'Exception: timeout';
|
||||
} else {
|
||||
// Success !
|
||||
transactionStatus = hash.toString();
|
||||
transactionStatus.update(currentTransactionId, (_) => hash.toString(),
|
||||
ifAbsent: () => hash.toString());
|
||||
notifyListeners();
|
||||
walletOptions.reload();
|
||||
walletProfiles.reload();
|
||||
return hash.toString();
|
||||
}
|
||||
} catch (e) {
|
||||
transactionStatus = e.toString();
|
||||
transactionStatus.update(currentTransactionId, (_) => e.toString(),
|
||||
ifAbsent: () => e.toString());
|
||||
notifyListeners();
|
||||
return e.toString();
|
||||
}
|
||||
|
@ -909,8 +917,6 @@ class SubstrateSdk with ChangeNotifier {
|
|||
required String destAddress,
|
||||
required double amount,
|
||||
required String password}) async {
|
||||
transactionStatus = 'sending';
|
||||
|
||||
final sender = await _setSender(fromAddress);
|
||||
|
||||
final globalBalance = await getBalance(fromAddress);
|
||||
|
@ -956,13 +962,13 @@ class SubstrateSdk with ChangeNotifier {
|
|||
rawParams = '[[$tx1, $tx2]]';
|
||||
}
|
||||
|
||||
return await _executeCall(txInfo, txOptions, password, rawParams);
|
||||
final transactionId = const Uuid().v4();
|
||||
_executeCall(transactionId, txInfo, txOptions, password, rawParams);
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
Future<String> certify(
|
||||
String fromAddress, String destAddress, String password) async {
|
||||
transactionStatus = 'sending';
|
||||
|
||||
final statusList = await idtyStatus([fromAddress, destAddress]);
|
||||
final myIdtyStatus = statusList[0];
|
||||
final toIdtyStatus = statusList[1];
|
||||
|
@ -973,8 +979,6 @@ class SubstrateSdk with ChangeNotifier {
|
|||
final toIndex = idtyIndexList[1];
|
||||
|
||||
if (myIdtyStatus != IdtyStatus.validated) {
|
||||
transactionStatus = 'notMember';
|
||||
notifyListeners();
|
||||
return 'notMember';
|
||||
}
|
||||
|
||||
|
@ -1022,18 +1026,17 @@ class SubstrateSdk with ChangeNotifier {
|
|||
txOptions = [fromIndex, toIndex];
|
||||
}
|
||||
} else {
|
||||
transactionStatus = 'cantBeCert';
|
||||
notifyListeners();
|
||||
return 'cantBeCert';
|
||||
}
|
||||
|
||||
log.d('Cert action: ${txInfo.call!}');
|
||||
return await _executeCall(txInfo, txOptions, password, rawParams);
|
||||
final transactionId = const Uuid().v4();
|
||||
_executeCall(transactionId, txInfo, txOptions, password, rawParams);
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
Future<String> confirmIdentity(
|
||||
String fromAddress, String name, String password) async {
|
||||
transactionStatus = 'sending';
|
||||
final sender = await _setSender(fromAddress);
|
||||
|
||||
final txInfo = TxInfoData(
|
||||
|
@ -1043,7 +1046,11 @@ class SubstrateSdk with ChangeNotifier {
|
|||
);
|
||||
final txOptions = [name];
|
||||
|
||||
return await _executeCall(txInfo, txOptions, password);
|
||||
final transactionId = const Uuid().v4();
|
||||
|
||||
_executeCall(transactionId, txInfo, txOptions, password);
|
||||
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
Future<String> migrateIdentity(
|
||||
|
@ -1053,7 +1060,6 @@ class SubstrateSdk with ChangeNotifier {
|
|||
required String destPassword,
|
||||
required Map fromBalance,
|
||||
bool withBalance = false}) async {
|
||||
transactionStatus = 'sending';
|
||||
final sender = await _setSender(fromAddress);
|
||||
|
||||
TxInfoData txInfo;
|
||||
|
@ -1111,7 +1117,9 @@ newKeySig: $newKeySigType""");
|
|||
txOptions = [destAddress, newKeySigType];
|
||||
}
|
||||
|
||||
return await _executeCall(txInfo, txOptions, fromPassword, rawParams);
|
||||
final transactionId = const Uuid().v4();
|
||||
_executeCall(transactionId, txInfo, txOptions, fromPassword, rawParams);
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
Future revokeIdentity(String address, String password) async {
|
||||
|
@ -1135,10 +1143,12 @@ newKeySig: $newKeySigType""");
|
|||
);
|
||||
|
||||
final txOptions = [idtyIndex, address, revocationSigTyped];
|
||||
return await _executeCall(txInfo, txOptions, password);
|
||||
final transactionId = const Uuid().v4();
|
||||
_executeCall(transactionId, txInfo, txOptions, password);
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
Future migrateCsToV2(String salt, String password, String destAddress,
|
||||
Future<String> migrateCsToV2(String salt, String password, String destAddress,
|
||||
{required destPassword,
|
||||
required Map balance,
|
||||
IdtyStatus idtyStatus = IdtyStatus.none}) async {
|
||||
|
@ -1171,8 +1181,10 @@ newKeySig: $newKeySigType""");
|
|||
password: password,
|
||||
);
|
||||
|
||||
late String transactionId;
|
||||
|
||||
if (idtyStatus != IdtyStatus.none) {
|
||||
await migrateIdentity(
|
||||
transactionId = await migrateIdentity(
|
||||
fromAddress: keypair.address!,
|
||||
destAddress: destAddress,
|
||||
fromPassword: 'password',
|
||||
|
@ -1180,14 +1192,17 @@ newKeySig: $newKeySigType""");
|
|||
withBalance: true,
|
||||
fromBalance: balance);
|
||||
} else if (balance['transferableBalance'] != 0) {
|
||||
await pay(
|
||||
transactionId = await pay(
|
||||
fromAddress: keypair.address!,
|
||||
destAddress: destAddress,
|
||||
amount: -1,
|
||||
password: 'password');
|
||||
} else {
|
||||
transactionId = '';
|
||||
}
|
||||
|
||||
await sdk.api.keyring.deleteAccount(keyring, keypair);
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
Future spawnBlock([int number = 1, int until = 0]) async {
|
||||
|
@ -1204,6 +1219,10 @@ newKeySig: $newKeySigType""");
|
|||
void reload() {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void resetTransactionStatus() {
|
||||
transactionStatus.clear();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
|
|
@ -217,14 +217,17 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
final wallet = myWalletProvider
|
||||
.getWalletDataByAddress(address.text);
|
||||
await sub.setCurrentWallet(wallet!);
|
||||
sub.confirmIdentity(walletOptions.address.text,
|
||||
idtyName.text, myWalletProvider.pinCode);
|
||||
final transactionId = await sub.confirmIdentity(
|
||||
walletOptions.address.text,
|
||||
idtyName.text,
|
||||
myWalletProvider.pinCode);
|
||||
Navigator.pop(context);
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return TransactionInProgress(
|
||||
transactionId: transactionId,
|
||||
transType: 'comfirmIdty',
|
||||
fromAddress:
|
||||
getShortPubkey(wallet.address),
|
||||
|
|
|
@ -39,8 +39,9 @@ class DebugScreen extends StatelessWidget {
|
|||
width: 250,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 4,
|
||||
backgroundColor: orangeC,
|
||||
),
|
||||
onPressed: () async => await sub.spawnBlock(),
|
||||
child: const Text(
|
||||
|
|
|
@ -322,8 +322,9 @@ Widget welcomeHome(context) {
|
|||
child: ElevatedButton(
|
||||
key: keyOnboardingNewChest,
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 4,
|
||||
backgroundColor: orangeC,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
|
|
|
@ -93,8 +93,9 @@ class _ChangePinScreenState extends State<ChangePinScreen> {
|
|||
height: 50,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.black, elevation: 12,
|
||||
backgroundColor: Colors.green[400], // foreground
|
||||
foregroundColor: Colors.black,
|
||||
elevation: 12,
|
||||
backgroundColor: Colors.green[400],
|
||||
),
|
||||
onPressed: () async {
|
||||
WalletData defaultWallet =
|
||||
|
|
|
@ -106,7 +106,7 @@ class _ChooseChestState extends State<ChooseChest> {
|
|||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.black,
|
||||
backgroundColor: orangeC, // foreground
|
||||
backgroundColor: orangeC,
|
||||
),
|
||||
onPressed: () async {
|
||||
await configBox.put('currentChest', currentChest);
|
||||
|
|
|
@ -22,6 +22,7 @@ import 'package:provider/provider.dart';
|
|||
|
||||
class ImportG1v1 extends StatelessWidget {
|
||||
const ImportG1v1({Key? key}) : super(key: key);
|
||||
static const int debouneTime = 600;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -29,7 +30,6 @@ class ImportG1v1 extends StatelessWidget {
|
|||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
|
||||
Timer? debounce;
|
||||
const int debouneTime = 600;
|
||||
WalletData selectedWallet = myWalletProvider.getDefaultWallet();
|
||||
bool canValidate = false;
|
||||
String validationStatus = '';
|
||||
|
@ -297,8 +297,10 @@ class ImportG1v1 extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
sub.migrateCsToV2(sub.csSalt.text,
|
||||
sub.csPassword.text, selectedWallet.address,
|
||||
final transactionId = await sub.migrateCsToV2(
|
||||
sub.csSalt.text,
|
||||
sub.csPassword.text,
|
||||
selectedWallet.address,
|
||||
destPassword:
|
||||
pin ?? myWalletProvider.pinCode,
|
||||
balance: balance,
|
||||
|
@ -308,6 +310,7 @@ class ImportG1v1 extends StatelessWidget {
|
|||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return TransactionInProgress(
|
||||
transactionId: transactionId,
|
||||
transType: 'identityMigration',
|
||||
fromAddress:
|
||||
getShortPubkey(sub.g1V1NewAddress),
|
||||
|
|
|
@ -109,7 +109,7 @@ class ManageMembership extends StatelessWidget {
|
|||
'Êtes-vous certains de vouloir révoquer définitivement cette identité ?') ??
|
||||
false;
|
||||
|
||||
if (answer) {
|
||||
if (!answer) return;
|
||||
final myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
|
@ -126,21 +126,24 @@ class ManageMembership extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
}
|
||||
if (pin != null || myWalletProvider.pinCode != '') {
|
||||
sub.revokeIdentity(address, myWalletProvider.pinCode);
|
||||
}
|
||||
|
||||
if (pin == null || myWalletProvider.pinCode == '') return;
|
||||
|
||||
final transactionId =
|
||||
await sub.revokeIdentity(address, myWalletProvider.pinCode);
|
||||
|
||||
Navigator.pop(context);
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return TransactionInProgress(
|
||||
transactionId: transactionId,
|
||||
transType: 'revokeIdty',
|
||||
fromAddress: getShortPubkey(address),
|
||||
toAddress: getShortPubkey(address));
|
||||
}),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: ScaledSizedBox(
|
||||
height: 55,
|
||||
|
|
|
@ -190,29 +190,26 @@ class MigrateIdentityScreen extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
if (myWalletProvider.pinCode != '') {
|
||||
sub.migrateIdentity(
|
||||
if (myWalletProvider.pinCode == '') return;
|
||||
final transactionId = await sub.migrateIdentity(
|
||||
fromAddress: fromAddress,
|
||||
destAddress: selectedWallet.address,
|
||||
fromPassword:
|
||||
pin ?? myWalletProvider.pinCode,
|
||||
destPassword:
|
||||
pin ?? myWalletProvider.pinCode,
|
||||
fromPassword: pin ?? myWalletProvider.pinCode,
|
||||
destPassword: pin ?? myWalletProvider.pinCode,
|
||||
withBalance: true,
|
||||
fromBalance: balance);
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return TransactionInProgress(
|
||||
transactionId: transactionId,
|
||||
transType: 'identityMigration',
|
||||
fromAddress:
|
||||
getShortPubkey(fromAddress),
|
||||
fromAddress: getShortPubkey(fromAddress),
|
||||
toAddress: getShortPubkey(
|
||||
selectedWallet.address));
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
child: Text(
|
||||
'migrateIdentity'.tr(),
|
||||
|
|
|
@ -84,8 +84,9 @@ class RestoreChest extends StatelessWidget {
|
|||
child: ElevatedButton(
|
||||
key: keyGoNext,
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 4,
|
||||
backgroundColor: orangeC,
|
||||
),
|
||||
onPressed: () async {
|
||||
if (await sub
|
||||
|
@ -125,8 +126,9 @@ class RestoreChest extends StatelessWidget {
|
|||
child: ElevatedButton(
|
||||
key: keyPastMnemonic,
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.black, elevation: 4,
|
||||
backgroundColor: yellowC, // foreground
|
||||
foregroundColor: Colors.black,
|
||||
elevation: 4,
|
||||
backgroundColor: yellowC,
|
||||
),
|
||||
onPressed: () {
|
||||
genW.pasteMnemonic(context);
|
||||
|
|
|
@ -239,9 +239,7 @@ class WalletOptions extends StatelessWidget {
|
|||
if (!walletProvider.isDefaultWallet &&
|
||||
!wallet.isMembre())
|
||||
deleteWallet(
|
||||
context, walletProvider, currentChest)
|
||||
else
|
||||
ScaledSizedBox(),
|
||||
context, walletProvider, currentChest),
|
||||
if (wallet.isMembre())
|
||||
const ManageMembershipButton()
|
||||
])
|
||||
|
@ -327,16 +325,10 @@ class WalletOptions extends StatelessWidget {
|
|||
key: keyConfirmIdentity,
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
backgroundColor: orangeC,
|
||||
),
|
||||
onPressed: () async {
|
||||
onPressed: () {
|
||||
walletProvider.confirmIdentityPopup(context);
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(builder: (context) {
|
||||
// return const SearchResultScreen();
|
||||
// }),
|
||||
// );
|
||||
},
|
||||
child: Text(
|
||||
'confirmMyIdentity'.tr(),
|
||||
|
|
|
@ -221,8 +221,9 @@ Widget nextButton(
|
|||
child: ElevatedButton(
|
||||
key: keyGoNext,
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 4,
|
||||
backgroundColor: orangeC,
|
||||
),
|
||||
onPressed: () {
|
||||
generateWalletProvider.nbrWord = generateWalletProvider.getRandomInt();
|
||||
|
|
|
@ -148,8 +148,9 @@ Widget nextButton(BuildContext context, String text, nextScreen, bool isFast) {
|
|||
child: ElevatedButton(
|
||||
key: keyGoNext,
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 4,
|
||||
backgroundColor: orangeC,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
|
|
|
@ -81,8 +81,7 @@ class OnboardingStepNine extends StatelessWidget {
|
|||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.black,
|
||||
elevation: 4,
|
||||
backgroundColor:
|
||||
const Color(0xffFFD58D), // foreground
|
||||
backgroundColor: const Color(0xffFFD58D),
|
||||
),
|
||||
onPressed: () {
|
||||
generateWalletProvider.changePinCode(
|
||||
|
|
|
@ -141,8 +141,9 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||
child: ElevatedButton(
|
||||
key: keyConfirmSearch,
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 4,
|
||||
backgroundColor: orangeC,
|
||||
),
|
||||
onPressed: canValidate
|
||||
? () {
|
||||
|
|
|
@ -18,11 +18,11 @@ class SearchResultScreen extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final searchProvider = Provider.of<SearchProvider>(context, listen: false);
|
||||
WalletsProfilesProvider walletsProfilesClass =
|
||||
final walletsProfilesClass =
|
||||
Provider.of<WalletsProfilesProvider>(context, listen: false);
|
||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||
|
||||
double avatarSize = scaleSize(37);
|
||||
final avatarSize = scaleSize(37);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: backgroundColor,
|
||||
|
|
|
@ -1,95 +1,87 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/scale_functions.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:gecko/providers/wallets_profiles.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
class TransactionInProgress extends StatelessWidget {
|
||||
const TransactionInProgress(
|
||||
{Key? key,
|
||||
final String transactionId;
|
||||
final String transType;
|
||||
final String? fromAddress, toAddress, toUsername;
|
||||
|
||||
const TransactionInProgress({
|
||||
Key? key,
|
||||
required this.transactionId,
|
||||
this.transType = 'pay',
|
||||
this.fromAddress,
|
||||
this.toAddress,
|
||||
this.toUsername})
|
||||
: super(key: key);
|
||||
final String transType;
|
||||
final String? fromAddress;
|
||||
final String? toAddress;
|
||||
final String? toUsername;
|
||||
this.toUsername,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sub = Provider.of<SubstrateSdk>(context, listen: true);
|
||||
final walletProfiles =
|
||||
Provider.of<WalletsProfilesProvider>(context, listen: false);
|
||||
final myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
var txStatus = TransactionStatus.none;
|
||||
final result = sub.transactionStatus;
|
||||
|
||||
final from = fromAddress ??
|
||||
g1WalletsBox
|
||||
.get(myWalletProvider.getDefaultWallet().address)
|
||||
?.username ??
|
||||
myWalletProvider.getDefaultWallet().name!;
|
||||
final transactionDetails = TransactionDetails(
|
||||
transactionId: transactionId,
|
||||
fromAddress: fromAddress,
|
||||
toAddress: toAddress,
|
||||
toUsername: toUsername,
|
||||
sub: sub,
|
||||
transType: transType,
|
||||
);
|
||||
|
||||
String to = toAddress ?? walletProfiles.address;
|
||||
to =
|
||||
myWalletProvider.getWalletDataByAddress(to)?.name ?? getShortPubkey(to);
|
||||
|
||||
final amount = walletProfiles.payAmount.text;
|
||||
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||
|
||||
final Map<String, String> actionMap = {
|
||||
'pay': 'transaction'.tr(),
|
||||
'cert': 'certification'.tr(),
|
||||
'comfirmIdty': 'identityConfirm'.tr(),
|
||||
'revokeIdty': 'revokeAdhesion'.tr(),
|
||||
'identityMigration': 'identityMigration'.tr(),
|
||||
};
|
||||
|
||||
String resultText = '';
|
||||
final Map<String, String> resultMap = {
|
||||
'sending': 'sending'.tr(),
|
||||
'Ready': 'propagating'.tr(),
|
||||
'Broadcast': 'validating'.tr(),
|
||||
'cert.NotRespectCertPeriod': '24hbetweenCerts'.tr(),
|
||||
'identity.CreatorNotAllowedToCreateIdty': '24hbetweenCerts'.tr(),
|
||||
'cert.CannotCertifySelf': 'canNotCertifySelf'.tr(),
|
||||
'identity.IdtyNameAlreadyExist': 'nameAlreadyExist'.tr(),
|
||||
'balances.KeepAlive': '2GDtoKeepAlive'.tr(),
|
||||
'1010: Invalid Transaction: Inability to pay some fees , e.g. account balance too low':
|
||||
'youHaveToFeedThisAccountBeforeUsing'.tr(),
|
||||
'Token.FundsUnavailable': 'fundsUnavailable'.tr(),
|
||||
'Exception: timeout': 'execTimeoutOver'.tr(),
|
||||
};
|
||||
|
||||
if (result == null) {
|
||||
txStatus = TransactionStatus.none;
|
||||
} else if (result.contains('blockHash: ')) {
|
||||
txStatus = TransactionStatus.success;
|
||||
resultText = 'extrinsicValidated'
|
||||
.tr(args: [actionMap[transType] ?? 'strangeTransaction'.tr()]);
|
||||
} else if (result.contains('Exception: ')) {
|
||||
txStatus = TransactionStatus.failed;
|
||||
resultText = "${"anErrorOccurred".tr()}:\n";
|
||||
final String exception = result.split('Exception: ')[1];
|
||||
resultText = resultMap[exception] ?? "$resultText\n$exception";
|
||||
log.e('Error: $exception');
|
||||
} else {
|
||||
txStatus = TransactionStatus.loading;
|
||||
resultText = resultMap[result] ?? 'unknown status...';
|
||||
Widget getTransactionStatusIcon(TransactionDetails details) {
|
||||
switch (details.txStatus) {
|
||||
case TransactionStatus.loading:
|
||||
return ScaledSizedBox(
|
||||
height: 17,
|
||||
width: 17,
|
||||
child: const CircularProgressIndicator(
|
||||
color: orangeC,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
case TransactionStatus.success:
|
||||
return Icon(
|
||||
Icons.done_all,
|
||||
size: scaleSize(32),
|
||||
color: Colors.greenAccent,
|
||||
);
|
||||
case TransactionStatus.failed:
|
||||
return Icon(
|
||||
Icons.close,
|
||||
size: scaleSize(32),
|
||||
color: Colors.redAccent,
|
||||
);
|
||||
case TransactionStatus.none:
|
||||
default:
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
|
||||
log.d("$transType :: ${actionMap[transType]} :: $result");
|
||||
Widget buildTransactionStatus(TransactionDetails details) {
|
||||
return Column(
|
||||
children: [
|
||||
getTransactionStatusIcon(details),
|
||||
ScaledSizedBox(height: 7),
|
||||
if (details.txStatus != TransactionStatus.none)
|
||||
Text(
|
||||
transactionDetails.resultText,
|
||||
textAlign: TextAlign.center,
|
||||
style: scaledTextStyle(fontSize: 17),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return PopScope(
|
||||
onPopInvoked: (_) {
|
||||
sub.transactionStatus = null;
|
||||
sub.resetTransactionStatus();
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: backgroundColor,
|
||||
|
@ -102,7 +94,8 @@ class TransactionInProgress extends StatelessWidget {
|
|||
children: <Widget>[
|
||||
Text(
|
||||
'extrinsicInProgress'.tr(args: [
|
||||
actionMap[transType] ?? 'strangeTransaction'.tr()
|
||||
transactionDetails.actionMap[transType] ??
|
||||
'strangeTransaction'.tr()
|
||||
]),
|
||||
style: scaledTextStyle(fontSize: 20),
|
||||
)
|
||||
|
@ -126,9 +119,9 @@ class TransactionInProgress extends StatelessWidget {
|
|||
ScaledSizedBox(height: 10),
|
||||
if (transType == 'pay')
|
||||
Text(
|
||||
isUdUnit
|
||||
? 'ud'.tr(args: ['$amount '])
|
||||
: '$amount $currencyName',
|
||||
transactionDetails.isUdUnit
|
||||
? 'ud'.tr(args: ['${transactionDetails.amount} '])
|
||||
: '${transactionDetails.amount} $currencyName',
|
||||
textAlign: TextAlign.center,
|
||||
style: scaledTextStyle(
|
||||
fontSize: 17, fontWeight: FontWeight.w500),
|
||||
|
@ -140,13 +133,14 @@ class TransactionInProgress extends StatelessWidget {
|
|||
style: scaledTextStyle(fontSize: 16),
|
||||
),
|
||||
Text(
|
||||
from,
|
||||
transactionDetails.fromAddress!,
|
||||
textAlign: TextAlign.center,
|
||||
style: scaledTextStyle(
|
||||
fontSize: 17, fontWeight: FontWeight.w500),
|
||||
),
|
||||
Visibility(
|
||||
visible: from != to,
|
||||
visible: transactionDetails.fromAddress !=
|
||||
transactionDetails.toAddress,
|
||||
child: Column(
|
||||
children: [
|
||||
ScaledSizedBox(height: 10),
|
||||
|
@ -156,7 +150,7 @@ class TransactionInProgress extends StatelessWidget {
|
|||
style: scaledTextStyle(fontSize: 16),
|
||||
),
|
||||
Text(
|
||||
toUsername ?? to,
|
||||
transactionDetails.toUsername!,
|
||||
textAlign: TextAlign.center,
|
||||
style: scaledTextStyle(
|
||||
fontSize: 17, fontWeight: FontWeight.w500),
|
||||
|
@ -168,44 +162,7 @@ class TransactionInProgress extends StatelessWidget {
|
|||
]),
|
||||
),
|
||||
const Spacer(),
|
||||
Column(children: [
|
||||
Visibility(
|
||||
visible: txStatus == TransactionStatus.loading,
|
||||
child: ScaledSizedBox(
|
||||
height: 17,
|
||||
width: 17,
|
||||
child: const CircularProgressIndicator(
|
||||
color: orangeC,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: txStatus == TransactionStatus.success,
|
||||
child: Icon(
|
||||
Icons.done_all,
|
||||
size: scaleSize(32),
|
||||
color: Colors.greenAccent,
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: txStatus == TransactionStatus.failed,
|
||||
child: Icon(
|
||||
Icons.close,
|
||||
size: scaleSize(32),
|
||||
color: Colors.redAccent,
|
||||
),
|
||||
),
|
||||
ScaledSizedBox(height: 10),
|
||||
Visibility(
|
||||
visible: txStatus != TransactionStatus.none,
|
||||
child: Text(
|
||||
resultText,
|
||||
textAlign: TextAlign.center,
|
||||
style: scaledTextStyle(fontSize: 17),
|
||||
),
|
||||
),
|
||||
]),
|
||||
buildTransactionStatus(transactionDetails),
|
||||
const Spacer(),
|
||||
Expanded(
|
||||
child: Align(
|
||||
|
@ -216,11 +173,12 @@ class TransactionInProgress extends StatelessWidget {
|
|||
child: ElevatedButton(
|
||||
key: keyCloseTransactionScreen,
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
foregroundColor: Colors.white,
|
||||
elevation: 4,
|
||||
backgroundColor: orangeC,
|
||||
),
|
||||
onPressed: () {
|
||||
sub.transactionStatus = null;
|
||||
sub.resetTransactionStatus();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(
|
||||
|
@ -233,7 +191,8 @@ class TransactionInProgress extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
ScaledSizedBox(height: 80)
|
||||
])),
|
||||
]),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -241,3 +200,82 @@ class TransactionInProgress extends StatelessWidget {
|
|||
}
|
||||
|
||||
enum TransactionStatus { loading, failed, success, none }
|
||||
|
||||
class TransactionDetails {
|
||||
String? fromAddress, toAddress, toUsername, amount;
|
||||
bool isUdUnit = false;
|
||||
String resultText = '';
|
||||
TransactionStatus txStatus = TransactionStatus.none;
|
||||
|
||||
Map<String, String> actionMap = {
|
||||
'pay': 'transaction'.tr(),
|
||||
'cert': 'certification'.tr(),
|
||||
'comfirmIdty': 'identityConfirm'.tr(),
|
||||
'revokeIdty': 'revokeAdhesion'.tr(),
|
||||
'identityMigration': 'identityMigration'.tr(),
|
||||
};
|
||||
|
||||
Map<String, String> resultMap = {
|
||||
'sending': 'sending'.tr(),
|
||||
'Ready': 'propagating'.tr(),
|
||||
'Broadcast': 'validating'.tr(),
|
||||
'cert.NotRespectCertPeriod': '24hbetweenCerts'.tr(),
|
||||
'identity.CreatorNotAllowedToCreateIdty': '24hbetweenCerts'.tr(),
|
||||
'cert.CannotCertifySelf': 'canNotCertifySelf'.tr(),
|
||||
'identity.IdtyNameAlreadyExist': 'nameAlreadyExist'.tr(),
|
||||
'balances.KeepAlive': '2GDtoKeepAlive'.tr(),
|
||||
'1010: Invalid Transaction: Inability to pay some fees , e.g. account balance too low':
|
||||
'youHaveToFeedThisAccountBeforeUsing'.tr(),
|
||||
'Token.FundsUnavailable': 'fundsUnavailable'.tr(),
|
||||
'Exception: timeout': 'execTimeoutOver'.tr(),
|
||||
};
|
||||
|
||||
TransactionDetails({
|
||||
required transactionId,
|
||||
required this.fromAddress,
|
||||
required this.toAddress,
|
||||
required this.toUsername,
|
||||
required SubstrateSdk sub,
|
||||
required String transType,
|
||||
}) {
|
||||
final walletProfiles =
|
||||
Provider.of<WalletsProfilesProvider>(homeContext, listen: false);
|
||||
final myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(homeContext, listen: false);
|
||||
String defaultWalletAddress = myWalletProvider.getDefaultWallet().address;
|
||||
String defaultWalletName = myWalletProvider.getDefaultWallet().name!;
|
||||
String? walletDataName =
|
||||
myWalletProvider.getWalletDataByAddress(toAddress ?? '')?.name;
|
||||
|
||||
fromAddress = fromAddress ??
|
||||
g1WalletsBox.get(defaultWalletAddress)?.username ??
|
||||
defaultWalletName;
|
||||
toAddress = toAddress ?? walletProfiles.address;
|
||||
toUsername = toUsername ?? walletDataName ?? getShortPubkey(toAddress!);
|
||||
|
||||
amount = walletProfiles.payAmount.text;
|
||||
isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||
|
||||
if (sub.transactionStatus.containsKey(transactionId)) {
|
||||
calculateTransactionStatus(
|
||||
sub.transactionStatus[transactionId], transType);
|
||||
}
|
||||
}
|
||||
|
||||
void calculateTransactionStatus(String? result, String transType) {
|
||||
if (result == null) {
|
||||
txStatus = TransactionStatus.none;
|
||||
} else if (result.contains('blockHash: ')) {
|
||||
txStatus = TransactionStatus.success;
|
||||
resultText = 'extrinsicValidated'
|
||||
.tr(args: [actionMap[transType] ?? 'strangeTransaction']);
|
||||
} else if (result.contains('Exception: ')) {
|
||||
txStatus = TransactionStatus.failed;
|
||||
String exception = result.split('Exception: ')[1];
|
||||
resultText = resultMap[exception] ?? exception;
|
||||
} else {
|
||||
txStatus = TransactionStatus.loading;
|
||||
resultText = resultMap[result] ?? 'Unknown status: $result';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ class WalletViewScreen extends StatelessWidget {
|
|||
return FutureBuilder(
|
||||
future: sub.certState(defaultWallet.address, address),
|
||||
builder: (context, AsyncSnapshot<Map<String, int>> snapshot) {
|
||||
if (snapshot.data == null) return ScaledSizedBox();
|
||||
if (snapshot.data == null) return const SizedBox.shrink();
|
||||
String duration = '';
|
||||
|
||||
if (snapshot.data!['certDelay'] != null ||
|
||||
|
@ -209,7 +209,7 @@ class WalletViewScreen extends StatelessWidget {
|
|||
'assets/gecko_certify.png')),
|
||||
),
|
||||
onTap: () async {
|
||||
final bool? result =
|
||||
final result =
|
||||
await confirmPopupCertification(
|
||||
context,
|
||||
'areYouSureYouWantToCertify1'
|
||||
|
@ -220,12 +220,12 @@ class WalletViewScreen extends StatelessWidget {
|
|||
"noIdentity".tr(),
|
||||
'areYouSureYouWantToCertify2'
|
||||
.tr(),
|
||||
getShortPubkey(address));
|
||||
getShortPubkey(address)) ??
|
||||
false;
|
||||
|
||||
if (result ?? false) {
|
||||
String? pin;
|
||||
if (!result) return;
|
||||
if (myWalletProvider.pinCode == '') {
|
||||
pin = await Navigator.push(
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (homeContext) {
|
||||
|
@ -235,29 +235,27 @@ class WalletViewScreen extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
}
|
||||
if (pin != null ||
|
||||
myWalletProvider.pinCode != '') {
|
||||
if (myWalletProvider.pinCode == '') {
|
||||
return;
|
||||
}
|
||||
WalletsProfilesProvider
|
||||
walletViewProvider = Provider
|
||||
.of<WalletsProfilesProvider>(
|
||||
walletViewProvider = Provider.of<
|
||||
WalletsProfilesProvider>(
|
||||
context,
|
||||
listen: false);
|
||||
final acc = sub.getCurrentWallet();
|
||||
sub.certify(
|
||||
final transactionId = await sub.certify(
|
||||
acc.address!,
|
||||
walletViewProvider.address,
|
||||
pin ??
|
||||
myWalletProvider.pinCode);
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const TransactionInProgress(
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return TransactionInProgress(
|
||||
transactionId: transactionId,
|
||||
transType: 'cert');
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -24,8 +24,9 @@ class NextButton extends StatelessWidget {
|
|||
child: ElevatedButton(
|
||||
key: keyGoNext,
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white, backgroundColor: orangeC,
|
||||
elevation: 4, // foreground
|
||||
foregroundColor: Colors.white,
|
||||
backgroundColor: orangeC,
|
||||
elevation: 4,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
|
|
|
@ -33,9 +33,8 @@ void paymentPopup(BuildContext context, String toAddress, String? username) {
|
|||
walletViewProvider.payAmount.text = '';
|
||||
|
||||
Future executeTransfert() async {
|
||||
String? pin;
|
||||
if (myWalletProvider.pinCode == '') {
|
||||
pin = await Navigator.push(
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (homeContext) {
|
||||
|
@ -44,26 +43,27 @@ void paymentPopup(BuildContext context, String toAddress, String? username) {
|
|||
),
|
||||
);
|
||||
}
|
||||
if (pin != null || myWalletProvider.pinCode != '') {
|
||||
if (myWalletProvider.pinCode == '') return;
|
||||
// Payment workflow !
|
||||
final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
final acc = sub.getCurrentWallet();
|
||||
log.d(
|
||||
"fromAddress: ${acc.address!},destAddress: $toAddress, amount: ${double.parse(walletViewProvider.payAmount.text)}");
|
||||
sub.pay(
|
||||
final transactionId = await sub.pay(
|
||||
fromAddress: acc.address!,
|
||||
destAddress: toAddress,
|
||||
amount: double.parse(walletViewProvider.payAmount.text),
|
||||
password: pin ?? myWalletProvider.pinCode);
|
||||
password: myWalletProvider.pinCode);
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return TransactionInProgress(
|
||||
toAddress: toAddress, toUsername: username);
|
||||
transactionId: transactionId,
|
||||
toAddress: toAddress,
|
||||
toUsername: username);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
myWalletProvider.readAllWallets().then((value) => myWalletProvider.listWallets
|
||||
.sort((a, b) => a.derivation!.compareTo(b.derivation!)));
|
||||
|
|
|
@ -1660,7 +1660,7 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.0"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: uuid
|
||||
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
|
||||
|
|
|
@ -61,6 +61,7 @@ dependencies:
|
|||
url_launcher: ^6.1.11
|
||||
crypto: ^3.0.3
|
||||
screen_brightness: ^0.2.2+1
|
||||
uuid: ^3.0.7
|
||||
|
||||
dev_dependencies:
|
||||
# flutter_launcher_icons: ^0.9.2
|
||||
|
|
Loading…
Reference in New Issue