From 81772f923a33e9cae502dd1cae6cb8cdb745b268 Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 8 Aug 2022 16:24:40 +0200 Subject: [PATCH 01/13] implement batch for membership validation --- lib/providers/substrate_sdk.dart | 79 +++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 22 deletions(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 575d26e..1a8236c 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -240,9 +240,14 @@ class SubstrateSdk with ChangeNotifier { return result; } + Future getIdentityIndexOf(String address) async { + return await sdk.webView! + .evalJavascript('api.query.identity.identityIndexOf("$address")') ?? + 0; + } + Future> getCerts(String address) async { - final idtyIndex = await sdk.webView! - .evalJavascript('api.query.identity.identityIndexOf("$address")'); + final idtyIndex = await getIdentityIndexOf(address); // log.d('u32: ' + idtyIndex.toString()); final certsReceiver = await sdk.webView! @@ -253,13 +258,11 @@ class SubstrateSdk with ChangeNotifier { } Future getCertData(String from, String to) async { - final idtyIndexFrom = await sdk.webView! - .evalJavascript('api.query.identity.identityIndexOf("$from")'); + final idtyIndexFrom = await getIdentityIndexOf(from); - final idtyIndexTo = await sdk.webView! - .evalJavascript('api.query.identity.identityIndexOf("$to")'); + final idtyIndexTo = await getIdentityIndexOf(to); - if (idtyIndexFrom == null || idtyIndexTo == null) return {}; + if (idtyIndexFrom == 0 || idtyIndexTo == 0) return {}; final certData = await sdk.webView!.evalJavascript( 'api.query.cert.storageCertsByIssuer($idtyIndexFrom, $idtyIndexTo)') ?? @@ -271,6 +274,13 @@ class SubstrateSdk with ChangeNotifier { return certData; } + Future> getParameters() async { + final currencyParameters = await sdk.webView! + .evalJavascript('api.query.parameters.parametersStorage()') ?? + {}; + return currencyParameters; + } + Future hasAccountConsumers(String address) async { final accountInfo = await sdk.webView! .evalJavascript('api.query.system.account("$address")'); @@ -463,6 +473,9 @@ class SubstrateSdk with ChangeNotifier { final myIdtyStatus = await idtyStatus(fromAddress); final toIdtyStatus = await idtyStatus(toAddress); + final fromIndex = await getIdentityIndexOf(fromAddress); + final toIndex = await getIdentityIndexOf(toAddress); + log.d(myIdtyStatus); log.d(toIdtyStatus); @@ -472,6 +485,9 @@ class SubstrateSdk with ChangeNotifier { return 'notMember'; } + final toCerts = await getCerts(toAddress); + final currencyParameters = await getParameters(); + final sender = TxSenderData( keyring.current.address, keyring.current.pubKey, @@ -486,11 +502,21 @@ class SubstrateSdk with ChangeNotifier { ); } else if (toIdtyStatus == 'Validated' || toIdtyStatus == 'ConfirmedByOwner') { - txInfo = TxInfoData( - 'cert', - 'addCert', - sender, - ); + if (toCerts[0] >= currencyParameters['wotMinCertForMembership'] && + toIdtyStatus != 'Validated') { + log.d('Batch cert and membership validation'); + txInfo = TxInfoData( + 'utility', + 'batchAll', + sender, + ); + } else { + txInfo = TxInfoData( + 'cert', + 'addCert', + sender, + ); + } } else { transactionStatus = 'cantBeCert'; notifyListeners(); @@ -500,10 +526,24 @@ class SubstrateSdk with ChangeNotifier { log.d('Cert action: ${txInfo.call!}'); try { + List txOptions = []; + if (txInfo.call == 'batchAll') { + txOptions = [ + 'cert.addCert($fromIndex, $toIndex)', + 'identity.validateIdentity($toIndex)' + ]; + } else if (txInfo.call == 'createIdentity') { + txOptions = [toAddress]; + } else if (txInfo.call == 'addCert') { + txOptions = [fromIndex, toIndex]; + } else { + log.e('TX call is unexpected'); + return 'Ğecko says: TX call is unexpected'; + } final hash = await sdk.api.tx .signAndSend( txInfo, - [toAddress], + txOptions, password, ) .timeout( @@ -532,10 +572,9 @@ class SubstrateSdk with ChangeNotifier { // var tata = await sdk.webView! // .evalJavascript('api.query.system.account("$address")'); - var idtyIndex = await sdk.webView! - .evalJavascript('api.query.identity.identityIndexOf("$address")'); + var idtyIndex = await getIdentityIndexOf(address); - if (idtyIndex == null) { + if (idtyIndex == 0) { return 'noid'; } @@ -648,21 +687,17 @@ class SubstrateSdk with ChangeNotifier { } Future getCertMeta(String address) async { - var idtyIndex = await sdk.webView! - .evalJavascript('api.query.identity.identityIndexOf("$address")'); + var idtyIndex = await getIdentityIndexOf(address); final certMeta = await sdk.webView! .evalJavascript('api.query.cert.storageIdtyCertMeta($idtyIndex)') ?? ''; - // if (_certMeta['nextIssuableOn'] != 0) return {}; - // log.d(_certMeta); return certMeta; } Future revokeIdentity(String address, String password) async { - final idtyIndex = await sdk.webView! - .evalJavascript('api.query.identity.identityIndexOf("$address")'); + final idtyIndex = await getIdentityIndexOf(address); final sender = TxSenderData( keyring.current.address, From a88034b206f36de5b313ccccaa2e4b611636e7da Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 8 Aug 2022 17:03:34 +0200 Subject: [PATCH 02/13] Use certsByReceiver to gets certValidityPeriod instead of obsolete certsByReceiver call --- lib/providers/substrate_sdk.dart | 24 +++++++++++++----------- lib/screens/wallet_view.dart | 3 +++ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 1a8236c..d56efd7 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -257,21 +257,24 @@ class SubstrateSdk with ChangeNotifier { return [certsReceiver['receivedCount'], certsReceiver['issuedCount']]; } - Future getCertData(String from, String to) async { + Future getCertValidityPeriod(String from, String to) async { final idtyIndexFrom = await getIdentityIndexOf(from); - final idtyIndexTo = await getIdentityIndexOf(to); - if (idtyIndexFrom == 0 || idtyIndexTo == 0) return {}; + if (idtyIndexFrom == 0 || idtyIndexTo == 0) return 0; - final certData = await sdk.webView!.evalJavascript( - 'api.query.cert.storageCertsByIssuer($idtyIndexFrom, $idtyIndexTo)') ?? - ''; + final List certData = await sdk.webView! + .evalJavascript('api.query.cert.certsByReceiver($idtyIndexTo)') ?? + []; - if (certData == '') return {}; + if (certData.isEmpty) return 0; + for (List certInfo in certData) { + if (certInfo[0] == idtyIndexFrom) { + return certInfo[1]; + } + } - // log.d(_certData); - return certData; + return 0; } Future> getParameters() async { @@ -666,9 +669,8 @@ class SubstrateSdk with ChangeNotifier { Future> certState(String from, String to) async { Map result = {}; if (from != to && await isMemberGet(from)) { - final certData = await getCertData(from, to); + final removableOn = await getCertValidityPeriod(from, to); final certMeta = await getCertMeta(from); - final int removableOn = certData['removableOn'] ?? 0; final int nextIssuableOn = certMeta['nextIssuableOn'] ?? 0; final certRemovableDuration = (removableOn - blocNumber) * 6; const int renewDelay = 2 * 30 * 24 * 3600; // 2 months diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index 84a0d74..e2cebd9 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -129,6 +129,9 @@ class WalletViewScreen extends StatelessWidget { builder: (context, AsyncSnapshot> snapshot) { if (snapshot.data == null) return const SizedBox(); String duration = ''; + log.d(snapshot.data!['certDelay']); + log.d(snapshot.data!['certRenewable']); + if (snapshot.data!['certDelay'] != null || snapshot.data!['certRenewable'] != null) { final Duration durationSeconds = Duration( From 175334457af88021db3c3974b3c77d1d121de406 Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 8 Aug 2022 18:56:59 +0200 Subject: [PATCH 03/13] Add dead methode to get ss58 prefix from const storage; remove unused comments --- lib/globals.dart | 1 - lib/providers/generate_wallets.dart | 4 +- lib/providers/substrate_sdk.dart | 71 +++++++---------------------- lib/screens/settings.dart | 5 -- pubspec.yaml | 2 +- 5 files changed, 19 insertions(+), 64 deletions(-) diff --git a/lib/globals.dart b/lib/globals.dart index ba6d8d4..991afe7 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -46,7 +46,6 @@ Color floattingYellow = const Color(0xffEFEFBF); Color backgroundColor = const Color(0xFFF5F5F5); // Substrate settings -const int ss58 = 42; String currencyName = 'ĞD'; // Debug diff --git a/lib/providers/generate_wallets.dart b/lib/providers/generate_wallets.dart index 6039e53..65b8982 100644 --- a/lib/providers/generate_wallets.dart +++ b/lib/providers/generate_wallets.dart @@ -385,7 +385,7 @@ class GenerateWalletsProvider with ChangeNotifier { } for (var derivationNbr in [for (var i = 0; i < numberScan; i += 1) i]) { - final addressData = await sub.sdk.api.keyring.addressFromMnemonic(ss58, + final addressData = await sub.sdk.api.keyring.addressFromMnemonic(sub.ss58, cryptoType: CryptoType.sr25519, mnemonic: generatedMnemonic!, derivePath: '//$derivationNbr'); @@ -426,7 +426,7 @@ class GenerateWalletsProvider with ChangeNotifier { } Future scanRootBalance(SubstrateSdk sub, int currentChestNumber) async { - final addressData = await sub.sdk.api.keyring.addressFromMnemonic(ss58, + final addressData = await sub.sdk.api.keyring.addressFromMnemonic(sub.ss58, cryptoType: CryptoType.sr25519, mnemonic: generatedMnemonic!); final balance = await sub.getBalance(addressData.address!).timeout( diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index d56efd7..dccacc4 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -28,6 +28,7 @@ class SubstrateSdk with ChangeNotifier { bool isLoadingEndpoint = false; String debugConnection = ''; String transactionStatus = ''; + int ss58 = 42; TextEditingController jsonKeystore = TextEditingController(); TextEditingController keystorePassword = TextEditingController(); @@ -46,12 +47,6 @@ class SubstrateSdk with ChangeNotifier { Future connectNode(BuildContext ctx) async { HomeProvider homeProvider = Provider.of(ctx, listen: false); - // var connectivityResult = await (Connectivity().checkConnectivity()); - // if (connectivityResult == ConnectivityResult.mobile || - // connectivityResult == ConnectivityResult.wifi) { - // _homeProvider.changeMessage("Vous n'êtes pas connecté à internet", 0); - // return; - // } homeProvider.changeMessage("connectionPending".tr(), 0); // configBox.delete('customEndpoint'); @@ -60,31 +55,8 @@ class SubstrateSdk with ChangeNotifier { ? [getDuniterCustomEndpoint()] : getDuniterBootstrap(); - // final nodes = getDuniterBootstrap(); - int timeout = 10000; - // if (n.endpoint!.startsWith('ws://')) { - // timeout = 5000; - // } - - //// Check websocket conenction - only for wss - // final channel = IOWebSocketChannel.connect( - // Uri.parse('wss://192.168.1.72:9944'), - // ); - - // channel.stream.listen( - // (dynamic message) { - // log.d('message $message'); - // }, - // onDone: () { - // log.d('ws channel closed'); - // }, - // onError: (error) { - // log.d('ws error $error'); - // }, - // ); - if (sdk.api.connectedNode?.endpoint != null) { await sdk.api.setting.unsubscribeBestNumber(); } @@ -99,6 +71,7 @@ class SubstrateSdk with ChangeNotifier { notifyListeners(); if (res != null) { nodeConnected = true; + // await getSs58Prefix(); // Subscribe bloc number sdk.api.setting.subscribeBestNumber((res) { @@ -197,7 +170,7 @@ class SubstrateSdk with ChangeNotifier { notifyListeners(); }); if (json == null) return ''; - log.d(json); + // log.d(json); try { await sdk.api.keyring.addAccount( keyring, @@ -205,7 +178,6 @@ class SubstrateSdk with ChangeNotifier { acc: json, password: password, ); - // Clipboard.setData(ClipboardData(text: jsonEncode(acc.toJson()))); } catch (e) { log.e(e); importIsLoading = false; @@ -225,14 +197,8 @@ class SubstrateSdk with ChangeNotifier { Future> getKeyStoreAddress() async { List result = []; - // sdk.api.account.unsubscribeBalance(); for (var element in keyring.allAccounts) { - // Clipboard.setData(ClipboardData(text: jsonEncode(element))); final account = AddressInfo(address: element.address); - // await sdk.api.account.subscribeBalance(element.address, (p0) { - // account.balance = int.parse(p0.freeBalance) / 100; - // }); - // sdk.api.setting.unsubscribeBestNumber(); account.balance = await getBalance(element.address!); result.add(account); } @@ -248,8 +214,6 @@ class SubstrateSdk with ChangeNotifier { Future> getCerts(String address) async { final idtyIndex = await getIdentityIndexOf(address); - // log.d('u32: ' + idtyIndex.toString()); - final certsReceiver = await sdk.webView! .evalJavascript('api.query.cert.storageIdtyCertMeta($idtyIndex)') ?? []; @@ -288,14 +252,12 @@ class SubstrateSdk with ChangeNotifier { final accountInfo = await sdk.webView! .evalJavascript('api.query.system.account("$address")'); final consumers = accountInfo['consumers']; - // log.d('Consumers: $_consumers'); return consumers == 0 ? false : true; } Future getBalance(String address, {bool isUd = false}) async { double balance = 0.0; - // log.d('nodeConnected: ' + nodeConnected.toString()); if (nodeConnected) { final brutBalance = await sdk.api.account.queryBalance(address); balance = int.parse(brutBalance!.freeBalance) / 100; @@ -324,7 +286,6 @@ class SubstrateSdk with ChangeNotifier { Future checkPassword(String address, String pass) async { final account = getKeypair(address); - // log.d(account.address); return await sdk.api.keyring.checkPassword(account, pass); } @@ -380,8 +341,6 @@ class SubstrateSdk with ChangeNotifier { final gen = await sdk.api.keyring.generateMnemonic(ss58); generatedMnemonic = gen.mnemonic!; - // final res = await importAccount(fromMnemonic: true); - // await Clipboard.setData(ClipboardData(text: generatedMnemonic)); return gen.mnemonic!; } @@ -416,12 +375,9 @@ class SubstrateSdk with ChangeNotifier { required String password}) async { transactionStatus = ''; - // setCurrentWallet(fromAddress); - log.d(keyring.current.address); log.d(fromAddress); log.d(password); - // log.d(await checkPassword(fromAddress, password)); final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]); log.d(fromPubkey!.keys.first); @@ -469,7 +425,6 @@ class SubstrateSdk with ChangeNotifier { String fromAddress, String password, String toAddress) async { transactionStatus = ''; - // setCurrentWallet(fromAddress); log.d('me: $fromAddress'); log.d('to: $toAddress'); @@ -507,7 +462,7 @@ class SubstrateSdk with ChangeNotifier { toIdtyStatus == 'ConfirmedByOwner') { if (toCerts[0] >= currencyParameters['wotMinCertForMembership'] && toIdtyStatus != 'Validated') { - log.d('Batch cert and membership validation'); + log.i('Batch cert and membership validation'); txInfo = TxInfoData( 'utility', 'batchAll', @@ -572,9 +527,6 @@ class SubstrateSdk with ChangeNotifier { } Future idtyStatus(String address, [bool smooth = true]) async { - // var tata = await sdk.webView! - // .evalJavascript('api.query.system.account("$address")'); - var idtyIndex = await getIdentityIndexOf(address); if (idtyIndex == 0) { @@ -586,7 +538,7 @@ class SubstrateSdk with ChangeNotifier { if (idtyStatus != null) { final String status = idtyStatus['status']; - // log.d('Status $address: $_status'); + return (status); } else { return 'expired'; @@ -595,8 +547,6 @@ class SubstrateSdk with ChangeNotifier { Future confirmIdentity( String fromAddress, String name, String password) async { - // Confirm identity - // setCurrentWallet(fromAddress); log.d('me: ${keyring.current.address!}'); final sender = TxSenderData( @@ -788,6 +738,17 @@ class SubstrateSdk with ChangeNotifier { String? getConnectedEndpoint() { return sdk.api.connectedNode?.endpoint; } + + Future getSs58Prefix() async { + final List res = await sdk.webView!.evalJavascript( + 'api.consts.system.ss58Prefix.words', + wrapPromise: false) ?? + [42]; + + ss58 = res[0]; + log.d(ss58); + return ss58; + } } void snack(BuildContext context, String message, {int duration = 2}) { diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index c5611f2..08ef20f 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -77,14 +77,9 @@ class SettingsScreen extends StatelessWidget { sub.getConnectedEndpoint() ?? duniterBootstrapNodes.first.endpoint; final customEndpoint = NetworkParams(); - customEndpoint.name = currencyName; customEndpoint.endpoint = 'Personnalisé'; - customEndpoint.ss58 = ss58; - final automaticEndpoint = NetworkParams(); - automaticEndpoint.name = currencyName; automaticEndpoint.endpoint = 'Auto'; - automaticEndpoint.ss58 = ss58; // duniterBootstrapNodes.add(_sub.getDuniterCustomEndpoint()); duniterBootstrapNodes.insert(0, automaticEndpoint); duniterBootstrapNodes.add(customEndpoint); diff --git a/pubspec.yaml b/pubspec.yaml index 1475c89..1f0d806 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -60,7 +60,7 @@ dependencies: desktop_window: ^0.4.0 durt: ^0.1.6 package_info_plus: ^1.4.2 - polkawallet_sdk: #^0.4.8 + polkawallet_sdk: #^0.4.9 git: url: https://github.com/poka-IT/sdk.git ref: gecko-old From 29754e23b5451ebeca987c55b0053a4de3e9916f Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 8 Aug 2022 19:40:24 +0200 Subject: [PATCH 04/13] prepare to implement unclaimedUd evaluation --- lib/providers/substrate_sdk.dart | 33 +++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index dccacc4..1770abe 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -255,11 +255,12 @@ class SubstrateSdk with ChangeNotifier { return consumers == 0 ? false : true; } - Future getBalance(String address, {bool isUd = false}) async { + Future getBalance(String address) async { double balance = 0.0; if (nodeConnected) { final brutBalance = await sdk.api.account.queryBalance(address); + // log.d(brutBalance?.toJson()); balance = int.parse(brutBalance!.freeBalance) / 100; } else { balance = -1; @@ -267,6 +268,36 @@ class SubstrateSdk with ChangeNotifier { return balance; } + Future getUnclaimedUd(String address) async { +// TODO: Implement unclaimedUd evaluation +// Pour ce faire, il vous faut requêter cinq éléments de storage : + +// system.account(address) +// identity.identityIndexOf(address) +// identity.identities(idtyIndex) +// universalDividend.currentUdIndex() +// universalDividend.pastReevals() + +// const api = await ApiPromise.create(...); +// const { data: balance } = await api.query.system.account(address); +// const idtyIndex = await api.query.identity.identityIndexOf(address); +// const { data: idtyData } = await api.query.identity.identies(idtyIndex); +// const currentUdIndex = await api.query.universalDividend.currentUdIndex(); +// const pastReevals = await api.query.universalDividend.pastReevals(); + +// let newUdsAmount = computeClaimUds(currentUdIndex, idtyData.firstEligibleUd, pastReevals); +// let transferableBalance = balance.free + newUdsAmount; +// let potentialBalance = balance.reserved + transferableBalance; + + double balance = 0.0; + + final brutBalance = await sdk.api.account.queryBalance(address); + // log.d(brutBalance?.toJson()); + balance = int.parse(brutBalance!.freeBalance) / 100; + + return balance; + } + Future subscribeBalance(String address, {bool isUd = false}) async { double balance = 0.0; if (nodeConnected) { From d71261d0eccbd346d6494313d83d5fe5b1f7f1c6 Mon Sep 17 00:00:00 2001 From: poka Date: Tue, 9 Aug 2022 10:19:16 +0200 Subject: [PATCH 05/13] WIP: unclaimed UD are almost calculated --- lib/providers/substrate_sdk.dart | 54 +++++++++++++++++++------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 1770abe..7a2d89f 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -265,37 +265,49 @@ class SubstrateSdk with ChangeNotifier { } else { balance = -1; } + + await getUnclaimedUd(address); return balance; } Future getUnclaimedUd(String address) async { -// TODO: Implement unclaimedUd evaluation -// Pour ce faire, il vous faut requêter cinq éléments de storage : + final balanceGlobal = await sdk.webView! + .evalJavascript('api.query.system.account("$address")'); -// system.account(address) -// identity.identityIndexOf(address) -// identity.identities(idtyIndex) -// universalDividend.currentUdIndex() -// universalDividend.pastReevals() + final idtyIndex = await sdk.webView! + .evalJavascript('api.query.identity.identityIndexOf("$address")'); + final idtyData = await sdk.webView! + .evalJavascript('api.query.identity.identities($idtyIndex)'); -// const api = await ApiPromise.create(...); -// const { data: balance } = await api.query.system.account(address); -// const idtyIndex = await api.query.identity.identityIndexOf(address); -// const { data: idtyData } = await api.query.identity.identies(idtyIndex); -// const currentUdIndex = await api.query.universalDividend.currentUdIndex(); -// const pastReevals = await api.query.universalDividend.pastReevals(); + final int currentUdIndex = int.parse(await sdk.webView! + .evalJavascript('api.query.universalDividend.currentUdIndex()')); -// let newUdsAmount = computeClaimUds(currentUdIndex, idtyData.firstEligibleUd, pastReevals); -// let transferableBalance = balance.free + newUdsAmount; -// let potentialBalance = balance.reserved + transferableBalance; + final List pastReevals = await sdk.webView! + .evalJavascript('api.query.universalDividend.pastReevals()'); - double balance = 0.0; + log.d( + 'DEBUGG ${getShortPubkey(address)} : $balanceGlobal |---| $idtyIndex |---| $idtyData |---| $currentUdIndex |---| $pastReevals'); - final brutBalance = await sdk.api.account.queryBalance(address); - // log.d(brutBalance?.toJson()); - balance = int.parse(brutBalance!.freeBalance) / 100; + final int newUdsAmount = _computeClaimUds(currentUdIndex, + idtyData?['data']?['firstEligibleUd'] ?? 0, pastReevals); - return balance; + final double transferableBalance = + (balanceGlobal['data']['free'] + newUdsAmount) / 100; + final double potentialBalance = + (balanceGlobal['data']['reserved'] + transferableBalance) / 100; + + log.i( + 'transferableBalance: $transferableBalance --- potentialBalance: $potentialBalance'); + + return transferableBalance; + } + + int _computeClaimUds( + int currentUdIndex, int firstEligibleUd, List pastReevals) { + // TODO: Implement _computeClaimUds + + log.d('DEBUGGG: $currentUdIndex - $firstEligibleUd - $pastReevals'); + return 0; } Future subscribeBalance(String address, {bool isUd = false}) async { From 2677cb8eb8a4a5ebd44315ab7365620f835def57 Mon Sep 17 00:00:00 2001 From: poka Date: Tue, 9 Aug 2022 11:26:45 +0200 Subject: [PATCH 06/13] displayed balances are now transferabledBalances with unclaimed UDs --- lib/providers/substrate_sdk.dart | 120 ++++++++++++++++--------------- 1 file changed, 63 insertions(+), 57 deletions(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 7a2d89f..c006cc3 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -33,6 +33,10 @@ class SubstrateSdk with ChangeNotifier { TextEditingController jsonKeystore = TextEditingController(); TextEditingController keystorePassword = TextEditingController(); + Future getStorage(String call) async { + return await sdk.webView!.evalJavascript('api.query.$call'); + } + Future initApi() async { sdkLoading = true; await keyring.init([ss58]); @@ -207,16 +211,13 @@ class SubstrateSdk with ChangeNotifier { } Future getIdentityIndexOf(String address) async { - return await sdk.webView! - .evalJavascript('api.query.identity.identityIndexOf("$address")') ?? - 0; + return await getStorage('identity.identityIndexOf("$address")') ?? 0; } Future> getCerts(String address) async { final idtyIndex = await getIdentityIndexOf(address); - final certsReceiver = await sdk.webView! - .evalJavascript('api.query.cert.storageIdtyCertMeta($idtyIndex)') ?? - []; + final certsReceiver = + await getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? []; return [certsReceiver['receivedCount'], certsReceiver['issuedCount']]; } @@ -227,9 +228,8 @@ class SubstrateSdk with ChangeNotifier { if (idtyIndexFrom == 0 || idtyIndexTo == 0) return 0; - final List certData = await sdk.webView! - .evalJavascript('api.query.cert.certsByReceiver($idtyIndexTo)') ?? - []; + final List certData = + await getStorage('cert.certsByReceiver($idtyIndexTo)') ?? []; if (certData.isEmpty) return 0; for (List certInfo in certData) { @@ -242,72 +242,80 @@ class SubstrateSdk with ChangeNotifier { } Future> getParameters() async { - final currencyParameters = await sdk.webView! - .evalJavascript('api.query.parameters.parametersStorage()') ?? - {}; + final currencyParameters = + await getStorage('parameters.parametersStorage()') ?? {}; return currencyParameters; } Future hasAccountConsumers(String address) async { - final accountInfo = await sdk.webView! - .evalJavascript('api.query.system.account("$address")'); + final accountInfo = await getStorage('system.account("$address")'); final consumers = accountInfo['consumers']; return consumers == 0 ? false : true; } + // Future getBalance(String address) async { + // double balance = 0.0; + + // if (nodeConnected) { + // final brutBalance = await sdk.api.account.queryBalance(address); + // // log.d(brutBalance?.toJson()); + // balance = int.parse(brutBalance!.freeBalance) / 100; + // } else { + // balance = -1; + // } + + // await getUnclaimedUd(address); + // return balance; + // } + Future getBalance(String address) async { - double balance = 0.0; + final balanceGlobal = await getStorage('system.account("$address")'); - if (nodeConnected) { - final brutBalance = await sdk.api.account.queryBalance(address); - // log.d(brutBalance?.toJson()); - balance = int.parse(brutBalance!.freeBalance) / 100; - } else { - balance = -1; - } - - await getUnclaimedUd(address); - return balance; - } - - Future getUnclaimedUd(String address) async { - final balanceGlobal = await sdk.webView! - .evalJavascript('api.query.system.account("$address")'); - - final idtyIndex = await sdk.webView! - .evalJavascript('api.query.identity.identityIndexOf("$address")'); - final idtyData = await sdk.webView! - .evalJavascript('api.query.identity.identities($idtyIndex)'); - - final int currentUdIndex = int.parse(await sdk.webView! - .evalJavascript('api.query.universalDividend.currentUdIndex()')); - - final List pastReevals = await sdk.webView! - .evalJavascript('api.query.universalDividend.pastReevals()'); - - log.d( - 'DEBUGG ${getShortPubkey(address)} : $balanceGlobal |---| $idtyIndex |---| $idtyData |---| $currentUdIndex |---| $pastReevals'); + // Get onchain storage values + final idtyIndex = await getStorage('identity.identityIndexOf("$address")'); + final idtyData = await getStorage('identity.identities($idtyIndex)'); + final int currentUdIndex = + int.parse(await getStorage('universalDividend.currentUdIndex()')); + final List pastReevals = + await getStorage('universalDividend.pastReevals()'); + // Compute amount of claimable UDs final int newUdsAmount = _computeClaimUds(currentUdIndex, idtyData?['data']?['firstEligibleUd'] ?? 0, pastReevals); - final double transferableBalance = - (balanceGlobal['data']['free'] + newUdsAmount) / 100; - final double potentialBalance = - (balanceGlobal['data']['reserved'] + transferableBalance) / 100; + // Calculate transferable and potential balance + final int transferableBalance = + (balanceGlobal['data']['free'] + newUdsAmount); + final int potentialBalance = + (balanceGlobal['data']['reserved'] + transferableBalance); log.i( 'transferableBalance: $transferableBalance --- potentialBalance: $potentialBalance'); - return transferableBalance; + return transferableBalance / 100; } int _computeClaimUds( int currentUdIndex, int firstEligibleUd, List pastReevals) { - // TODO: Implement _computeClaimUds + int totalAmount = 0; - log.d('DEBUGGG: $currentUdIndex - $firstEligibleUd - $pastReevals'); - return 0; + for (var reval in pastReevals.reversed) { + final int revalNbr = reval[0]; + final int revalValue = reval[1]; + + // Loop each UDs revaluations and sum unclaimed balance + if (revalNbr <= firstEligibleUd) { + final count = currentUdIndex - firstEligibleUd; + totalAmount += count * revalValue; + break; + } else { + final count = currentUdIndex - revalNbr; + totalAmount += count * revalValue; + currentUdIndex = revalNbr; + } + } + + return totalAmount; } Future subscribeBalance(String address, {bool isUd = false}) async { @@ -576,8 +584,7 @@ class SubstrateSdk with ChangeNotifier { return 'noid'; } - final idtyStatus = await sdk.webView! - .evalJavascript('api.query.identity.identities($idtyIndex)'); + final idtyStatus = await getStorage('identity.identities($idtyIndex)'); if (idtyStatus != null) { final String status = idtyStatus['status']; @@ -684,9 +691,8 @@ class SubstrateSdk with ChangeNotifier { Future getCertMeta(String address) async { var idtyIndex = await getIdentityIndexOf(address); - final certMeta = await sdk.webView! - .evalJavascript('api.query.cert.storageIdtyCertMeta($idtyIndex)') ?? - ''; + final certMeta = + await getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? ''; return certMeta; } From 2526f382f1bbd383f9fd814060018e54f1b56720 Mon Sep 17 00:00:00 2001 From: poka Date: Tue, 9 Aug 2022 11:59:08 +0200 Subject: [PATCH 07/13] type and lock balance computing --- lib/providers/substrate_sdk.dart | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index c006cc3..0f2f9ad 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -269,11 +269,13 @@ class SubstrateSdk with ChangeNotifier { // } Future getBalance(String address) async { - final balanceGlobal = await getStorage('system.account("$address")'); - // Get onchain storage values - final idtyIndex = await getStorage('identity.identityIndexOf("$address")'); - final idtyData = await getStorage('identity.identities($idtyIndex)'); + final Map balanceGlobal = await getStorage('system.account("$address")'); + final int? idtyIndex = + await getStorage('identity.identityIndexOf("$address")'); + final Map? idtyData = idtyIndex == null + ? null + : await getStorage('identity.identities($idtyIndex)'); final int currentUdIndex = int.parse(await getStorage('universalDividend.currentUdIndex()')); final List pastReevals = @@ -299,7 +301,9 @@ class SubstrateSdk with ChangeNotifier { int currentUdIndex, int firstEligibleUd, List pastReevals) { int totalAmount = 0; - for (var reval in pastReevals.reversed) { + if (firstEligibleUd == 0) return 0; + + for (final List reval in pastReevals.reversed) { final int revalNbr = reval[0]; final int revalValue = reval[1]; From c487749f52a54e06c0ae2518a764cfe646ac3dd4 Mon Sep 17 00:00:00 2001 From: poka Date: Wed, 10 Aug 2022 07:18:04 +0200 Subject: [PATCH 08/13] improve batch meca --- lib/providers/substrate_sdk.dart | 21 +++++++-------------- pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 0f2f9ad..a6c6be5 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -506,6 +506,7 @@ class SubstrateSdk with ChangeNotifier { keyring.current.pubKey, ); TxInfoData txInfo; + List txOptions = []; if (toIdtyStatus == 'noid') { txInfo = TxInfoData( @@ -513,6 +514,7 @@ class SubstrateSdk with ChangeNotifier { 'createIdentity', sender, ); + txOptions = [toAddress]; } else if (toIdtyStatus == 'Validated' || toIdtyStatus == 'ConfirmedByOwner') { if (toCerts[0] >= currencyParameters['wotMinCertForMembership'] && @@ -523,12 +525,17 @@ class SubstrateSdk with ChangeNotifier { 'batchAll', sender, ); + txOptions = [ + 'cert.addCert($fromIndex, $toIndex)', + 'identity.validateIdentity($toIndex)' + ]; } else { txInfo = TxInfoData( 'cert', 'addCert', sender, ); + txOptions = [fromIndex, toIndex]; } } else { transactionStatus = 'cantBeCert'; @@ -539,20 +546,6 @@ class SubstrateSdk with ChangeNotifier { log.d('Cert action: ${txInfo.call!}'); try { - List txOptions = []; - if (txInfo.call == 'batchAll') { - txOptions = [ - 'cert.addCert($fromIndex, $toIndex)', - 'identity.validateIdentity($toIndex)' - ]; - } else if (txInfo.call == 'createIdentity') { - txOptions = [toAddress]; - } else if (txInfo.call == 'addCert') { - txOptions = [fromIndex, toIndex]; - } else { - log.e('TX call is unexpected'); - return 'Ğecko says: TX call is unexpected'; - } final hash = await sdk.api.tx .signAndSend( txInfo, diff --git a/pubspec.yaml b/pubspec.yaml index 1f0d806..fad4eda 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ description: Pay with G1. # pub.dev using `pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 0.0.9+16 +version: 0.0.9+17 environment: sdk: '>=2.12.0 <3.0.0' From cd91ea838b03485094ed49d22a8f617e7e71a0bd Mon Sep 17 00:00:00 2001 From: poka Date: Thu, 11 Aug 2022 15:47:08 +0200 Subject: [PATCH 09/13] refactor substrate_sdk.dart provider file; Add local node entry in settings --- lib/providers/substrate_sdk.dart | 888 +++++++++++++++---------------- lib/screens/settings.dart | 3 + 2 files changed, 423 insertions(+), 468 deletions(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index a6c6be5..f60a1fb 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -33,10 +33,280 @@ class SubstrateSdk with ChangeNotifier { TextEditingController jsonKeystore = TextEditingController(); TextEditingController keystorePassword = TextEditingController(); + ///////////////////////////////////// + ////////// 1: API METHODS /////////// + ///////////////////////////////////// + + Future executeCall( + TxInfoData txInfo, txOptions, String password) async { + try { + final hash = await sdk.api.tx + .signAndSend( + txInfo, + txOptions, + password, + ) + .timeout( + const Duration(seconds: 12), + onTimeout: () => {}, + ); + log.d(hash); + if (hash.isEmpty) { + transactionStatus = 'timeout'; + notifyListeners(); + + return 'timeout'; + } else { + transactionStatus = hash.toString(); + notifyListeners(); + return hash.toString(); + } + } catch (e) { + transactionStatus = e.toString(); + notifyListeners(); + return e.toString(); + } + } + Future getStorage(String call) async { return await sdk.webView!.evalJavascript('api.query.$call'); } + List batchCall(TxSenderData sender, List calls) { + TxInfoData txInfo = TxInfoData( + 'utility', + 'batchAll', + sender, + ); + List txOptions = calls; + + return [txInfo, txOptions]; + } + + TxSenderData _setSender() { + return TxSenderData( + keyring.current.address, + keyring.current.pubKey, + ); + } + + //////////////////////////////////////////// + ////////// 2: GET ONCHAIN STORAGE ////////// + //////////////////////////////////////////// + + Future> getKeyStoreAddress() async { + List result = []; + + for (var element in keyring.allAccounts) { + final account = AddressInfo(address: element.address); + account.balance = await getBalance(element.address!); + result.add(account); + } + + return result; + } + + Future getIdentityIndexOf(String address) async { + return await getStorage('identity.identityIndexOf("$address")') ?? 0; + } + + Future> getCerts(String address) async { + final idtyIndex = await getIdentityIndexOf(address); + final certsReceiver = + await getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? []; + + return [certsReceiver['receivedCount'], certsReceiver['issuedCount']]; + } + + Future getCertValidityPeriod(String from, String to) async { + final idtyIndexFrom = await getIdentityIndexOf(from); + final idtyIndexTo = await getIdentityIndexOf(to); + + if (idtyIndexFrom == 0 || idtyIndexTo == 0) return 0; + + final List certData = + await getStorage('cert.certsByReceiver($idtyIndexTo)') ?? []; + + if (certData.isEmpty) return 0; + for (List certInfo in certData) { + if (certInfo[0] == idtyIndexFrom) { + return certInfo[1]; + } + } + + return 0; + } + + Future> getParameters() async { + final currencyParameters = + await getStorage('parameters.parametersStorage()') ?? {}; + return currencyParameters; + } + + Future hasAccountConsumers(String address) async { + final accountInfo = await getStorage('system.account("$address")'); + final consumers = accountInfo['consumers']; + return consumers == 0 ? false : true; + } + + // Future getBalance(String address) async { + // double balance = 0.0; + + // if (nodeConnected) { + // final brutBalance = await sdk.api.account.queryBalance(address); + // // log.d(brutBalance?.toJson()); + // balance = int.parse(brutBalance!.freeBalance) / 100; + // } else { + // balance = -1; + // } + + // await getUnclaimedUd(address); + // return balance; + // } + + Future getBalance(String address) async { + // Get onchain storage values + final Map balanceGlobal = await getStorage('system.account("$address")'); + final int? idtyIndex = + await getStorage('identity.identityIndexOf("$address")'); + final Map? idtyData = idtyIndex == null + ? null + : await getStorage('identity.identities($idtyIndex)'); + final int currentUdIndex = + int.parse(await getStorage('universalDividend.currentUdIndex()')); + final List pastReevals = + await getStorage('universalDividend.pastReevals()'); + + // Compute amount of claimable UDs + final int newUdsAmount = _computeClaimUds(currentUdIndex, + idtyData?['data']?['firstEligibleUd'] ?? 0, pastReevals); + + // Calculate transferable and potential balance + final int transferableBalance = + (balanceGlobal['data']['free'] + newUdsAmount); + final int potentialBalance = + (balanceGlobal['data']['reserved'] + transferableBalance); + + log.i( + 'transferableBalance: $transferableBalance --- potentialBalance: $potentialBalance'); + + return transferableBalance / 100; + } + + int _computeClaimUds( + int currentUdIndex, int firstEligibleUd, List pastReevals) { + int totalAmount = 0; + + if (firstEligibleUd == 0) return 0; + + for (final List reval in pastReevals.reversed) { + final int revalNbr = reval[0]; + final int revalValue = reval[1]; + + // Loop each UDs revaluations and sum unclaimed balance + if (revalNbr <= firstEligibleUd) { + final count = currentUdIndex - firstEligibleUd; + totalAmount += count * revalValue; + break; + } else { + final count = currentUdIndex - revalNbr; + totalAmount += count * revalValue; + currentUdIndex = revalNbr; + } + } + + return totalAmount; + } + + Future getSs58Prefix() async { + final List res = await sdk.webView!.evalJavascript( + 'api.consts.system.ss58Prefix.words', + wrapPromise: false) ?? + [42]; + + ss58 = res[0]; + log.d(ss58); + return ss58; + } + + Future isMemberGet(String address) async { + return await idtyStatus(address) == 'Validated'; + } + + Future getMemberAddress() async { + // TODOO: Continue digging memberAddress detection + String memberAddress = ''; + walletBox.toMap().forEach((key, value) async { + final bool isMember = await isMemberGet(value.address!); + log.d(isMember); + if (isMember) { + final currentChestNumber = configBox.get('currentChest'); + ChestData newChestData = chestBox.get(currentChestNumber)!; + newChestData.memberWallet = value.number; + await chestBox.put(currentChestNumber, newChestData); + memberAddress = value.address!; + return; + } + }); + log.d(memberAddress); + return memberAddress; + } + + Future> certState(String from, String to) async { + Map result = {}; + if (from != to && await isMemberGet(from)) { + final removableOn = await getCertValidityPeriod(from, to); + final certMeta = await getCertMeta(from); + final int nextIssuableOn = certMeta['nextIssuableOn'] ?? 0; + final certRemovableDuration = (removableOn - blocNumber) * 6; + const int renewDelay = 2 * 30 * 24 * 3600; // 2 months + + if (certRemovableDuration >= renewDelay) { + final certRenewDuration = certRemovableDuration - renewDelay; + result.putIfAbsent('certRenewable', () => certRenewDuration); + } else if (nextIssuableOn > blocNumber) { + final certDelayDuration = (nextIssuableOn - blocNumber) * 6; + result.putIfAbsent('certDelay', () => certDelayDuration); + } else { + result.putIfAbsent('canCert', () => 0); + } + } + return result; + } + + Future getCertMeta(String address) async { + var idtyIndex = await getIdentityIndexOf(address); + + final certMeta = + await getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? ''; + + return certMeta; + } + + Future idtyStatus(String address, [bool smooth = true]) async { + var idtyIndex = await getIdentityIndexOf(address); + + if (idtyIndex == 0) { + return 'noid'; + } + + final idtyStatus = await getStorage('identity.identities($idtyIndex)'); + + if (idtyStatus != null) { + final String status = idtyStatus['status']; + + return (status); + } else { + return 'expired'; + } + } + + Future getCurencyName() async {} + + ///////////////////////////////////// + ////// 3: SUBSTRATE CONNECTION ////// + ///////////////////////////////////// + Future initApi() async { sdkLoading = true; await keyring.init([ss58]); @@ -48,6 +318,10 @@ class SubstrateSdk with ChangeNotifier { notifyListeners(); } + String? getConnectedEndpoint() { + return sdk.api.connectedNode?.endpoint; + } + Future connectNode(BuildContext ctx) async { HomeProvider homeProvider = Provider.of(ctx, listen: false); @@ -194,145 +468,9 @@ class SubstrateSdk with ChangeNotifier { return keyring.allAccounts.last.address!; } - void reload() { - notifyListeners(); - } - - Future> getKeyStoreAddress() async { - List result = []; - - for (var element in keyring.allAccounts) { - final account = AddressInfo(address: element.address); - account.balance = await getBalance(element.address!); - result.add(account); - } - - return result; - } - - Future getIdentityIndexOf(String address) async { - return await getStorage('identity.identityIndexOf("$address")') ?? 0; - } - - Future> getCerts(String address) async { - final idtyIndex = await getIdentityIndexOf(address); - final certsReceiver = - await getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? []; - - return [certsReceiver['receivedCount'], certsReceiver['issuedCount']]; - } - - Future getCertValidityPeriod(String from, String to) async { - final idtyIndexFrom = await getIdentityIndexOf(from); - final idtyIndexTo = await getIdentityIndexOf(to); - - if (idtyIndexFrom == 0 || idtyIndexTo == 0) return 0; - - final List certData = - await getStorage('cert.certsByReceiver($idtyIndexTo)') ?? []; - - if (certData.isEmpty) return 0; - for (List certInfo in certData) { - if (certInfo[0] == idtyIndexFrom) { - return certInfo[1]; - } - } - - return 0; - } - - Future> getParameters() async { - final currencyParameters = - await getStorage('parameters.parametersStorage()') ?? {}; - return currencyParameters; - } - - Future hasAccountConsumers(String address) async { - final accountInfo = await getStorage('system.account("$address")'); - final consumers = accountInfo['consumers']; - return consumers == 0 ? false : true; - } - - // Future getBalance(String address) async { - // double balance = 0.0; - - // if (nodeConnected) { - // final brutBalance = await sdk.api.account.queryBalance(address); - // // log.d(brutBalance?.toJson()); - // balance = int.parse(brutBalance!.freeBalance) / 100; - // } else { - // balance = -1; - // } - - // await getUnclaimedUd(address); - // return balance; - // } - - Future getBalance(String address) async { - // Get onchain storage values - final Map balanceGlobal = await getStorage('system.account("$address")'); - final int? idtyIndex = - await getStorage('identity.identityIndexOf("$address")'); - final Map? idtyData = idtyIndex == null - ? null - : await getStorage('identity.identities($idtyIndex)'); - final int currentUdIndex = - int.parse(await getStorage('universalDividend.currentUdIndex()')); - final List pastReevals = - await getStorage('universalDividend.pastReevals()'); - - // Compute amount of claimable UDs - final int newUdsAmount = _computeClaimUds(currentUdIndex, - idtyData?['data']?['firstEligibleUd'] ?? 0, pastReevals); - - // Calculate transferable and potential balance - final int transferableBalance = - (balanceGlobal['data']['free'] + newUdsAmount); - final int potentialBalance = - (balanceGlobal['data']['reserved'] + transferableBalance); - - log.i( - 'transferableBalance: $transferableBalance --- potentialBalance: $potentialBalance'); - - return transferableBalance / 100; - } - - int _computeClaimUds( - int currentUdIndex, int firstEligibleUd, List pastReevals) { - int totalAmount = 0; - - if (firstEligibleUd == 0) return 0; - - for (final List reval in pastReevals.reversed) { - final int revalNbr = reval[0]; - final int revalValue = reval[1]; - - // Loop each UDs revaluations and sum unclaimed balance - if (revalNbr <= firstEligibleUd) { - final count = currentUdIndex - firstEligibleUd; - totalAmount += count * revalValue; - break; - } else { - final count = currentUdIndex - revalNbr; - totalAmount += count * revalValue; - currentUdIndex = revalNbr; - } - } - - return totalAmount; - } - - Future subscribeBalance(String address, {bool isUd = false}) async { - double balance = 0.0; - if (nodeConnected) { - await sdk.api.account.subscribeBalance(address, (balanceData) { - balance = int.parse(balanceData.freeBalance) / 100; - notifyListeners(); - }); - } - - return balance; - } + ////////////////////////////////// + /////// 4: CRYPTOGRAPHY ////////// + ////////////////////////////////// KeyPairData getKeypair(String address) { return keyring.keyPairs.firstWhere((kp) => kp.address == address, @@ -423,325 +561,6 @@ class SubstrateSdk with ChangeNotifier { } } - Future pay( - {required String fromAddress, - required String destAddress, - required double amount, - required String password}) async { - transactionStatus = ''; - - log.d(keyring.current.address); - log.d(fromAddress); - log.d(password); - - final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]); - log.d(fromPubkey!.keys.first); - final sender = TxSenderData( - fromAddress, - fromPubkey.keys.first, - ); - final txInfo = TxInfoData( - 'balances', amount == -1 ? 'transferAll' : 'transferKeepAlive', sender); - - final int amountUnit = (amount * 100).toInt(); - try { - final hash = await sdk.api.tx.signAndSend( - txInfo, - [destAddress, amount == -1 ? false : amountUnit], - password, - onStatusChange: (status) { - log.d('Transaction status: $status'); - transactionStatus = status; - notifyListeners(); - }, - ).timeout( - const Duration(seconds: 12), - onTimeout: () => {}, - ); - log.d(hash.toString()); - if (hash.isEmpty) { - transactionStatus = 'timeout'; - notifyListeners(); - - return 'timeout'; - } else { - transactionStatus = hash.toString(); - notifyListeners(); - return hash.toString(); - } - } catch (e) { - transactionStatus = e.toString(); - notifyListeners(); - return e.toString(); - } - } - - Future certify( - String fromAddress, String password, String toAddress) async { - transactionStatus = ''; - - log.d('me: $fromAddress'); - log.d('to: $toAddress'); - - final myIdtyStatus = await idtyStatus(fromAddress); - final toIdtyStatus = await idtyStatus(toAddress); - - final fromIndex = await getIdentityIndexOf(fromAddress); - final toIndex = await getIdentityIndexOf(toAddress); - - log.d(myIdtyStatus); - log.d(toIdtyStatus); - - if (myIdtyStatus != 'Validated') { - transactionStatus = 'notMember'; - notifyListeners(); - return 'notMember'; - } - - final toCerts = await getCerts(toAddress); - final currencyParameters = await getParameters(); - - final sender = TxSenderData( - keyring.current.address, - keyring.current.pubKey, - ); - TxInfoData txInfo; - List txOptions = []; - - if (toIdtyStatus == 'noid') { - txInfo = TxInfoData( - 'identity', - 'createIdentity', - sender, - ); - txOptions = [toAddress]; - } else if (toIdtyStatus == 'Validated' || - toIdtyStatus == 'ConfirmedByOwner') { - if (toCerts[0] >= currencyParameters['wotMinCertForMembership'] && - toIdtyStatus != 'Validated') { - log.i('Batch cert and membership validation'); - txInfo = TxInfoData( - 'utility', - 'batchAll', - sender, - ); - txOptions = [ - 'cert.addCert($fromIndex, $toIndex)', - 'identity.validateIdentity($toIndex)' - ]; - } else { - txInfo = TxInfoData( - 'cert', - 'addCert', - sender, - ); - txOptions = [fromIndex, toIndex]; - } - } else { - transactionStatus = 'cantBeCert'; - notifyListeners(); - return 'cantBeCert'; - } - - log.d('Cert action: ${txInfo.call!}'); - - try { - final hash = await sdk.api.tx - .signAndSend( - txInfo, - txOptions, - password, - ) - .timeout( - const Duration(seconds: 12), - onTimeout: () => {}, - ); - log.d(hash); - if (hash.isEmpty) { - transactionStatus = 'timeout'; - notifyListeners(); - - return 'timeout'; - } else { - transactionStatus = hash.toString(); - notifyListeners(); - return hash.toString(); - } - } catch (e) { - transactionStatus = e.toString(); - notifyListeners(); - return e.toString(); - } - } - - Future idtyStatus(String address, [bool smooth = true]) async { - var idtyIndex = await getIdentityIndexOf(address); - - if (idtyIndex == 0) { - return 'noid'; - } - - final idtyStatus = await getStorage('identity.identities($idtyIndex)'); - - if (idtyStatus != null) { - final String status = idtyStatus['status']; - - return (status); - } else { - return 'expired'; - } - } - - Future confirmIdentity( - String fromAddress, String name, String password) async { - log.d('me: ${keyring.current.address!}'); - - final sender = TxSenderData( - keyring.current.address, - keyring.current.pubKey, - ); - - final txInfo = TxInfoData( - 'identity', - 'confirmIdentity', - sender, - ); - - try { - final hash = await sdk.api.tx.signAndSend( - txInfo, - [name], - password, - onStatusChange: (status) { - log.d('Transaction status: $status'); - transactionStatus = status; - notifyListeners(); - }, - ).timeout( - const Duration(seconds: 12), - onTimeout: () => {}, - ); - log.d(hash); - if (hash.isEmpty) { - transactionStatus = 'timeout'; - notifyListeners(); - - return 'timeout'; - } else { - transactionStatus = hash.toString(); - notifyListeners(); - return hash.toString(); - } - } on Exception catch (e) { - log.e(e); - transactionStatus = e.toString(); - notifyListeners(); - return e.toString(); - } - } - - Future isMemberGet(String address) async { - return await idtyStatus(address) == 'Validated'; - } - - Future getMemberAddress() async { - // TODOO: Continue digging memberAddress detection - String memberAddress = ''; - walletBox.toMap().forEach((key, value) async { - final bool isMember = await isMemberGet(value.address!); - log.d(isMember); - if (isMember) { - final currentChestNumber = configBox.get('currentChest'); - ChestData newChestData = chestBox.get(currentChestNumber)!; - newChestData.memberWallet = value.number; - await chestBox.put(currentChestNumber, newChestData); - memberAddress = value.address!; - return; - } - }); - log.d(memberAddress); - return memberAddress; - } - - Future> certState(String from, String to) async { - Map result = {}; - if (from != to && await isMemberGet(from)) { - final removableOn = await getCertValidityPeriod(from, to); - final certMeta = await getCertMeta(from); - final int nextIssuableOn = certMeta['nextIssuableOn'] ?? 0; - final certRemovableDuration = (removableOn - blocNumber) * 6; - const int renewDelay = 2 * 30 * 24 * 3600; // 2 months - - if (certRemovableDuration >= renewDelay) { - final certRenewDuration = certRemovableDuration - renewDelay; - result.putIfAbsent('certRenewable', () => certRenewDuration); - } else if (nextIssuableOn > blocNumber) { - final certDelayDuration = (nextIssuableOn - blocNumber) * 6; - result.putIfAbsent('certDelay', () => certDelayDuration); - } else { - result.putIfAbsent('canCert', () => 0); - } - } - return result; - } - - Future getCertMeta(String address) async { - var idtyIndex = await getIdentityIndexOf(address); - - final certMeta = - await getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? ''; - - return certMeta; - } - - Future revokeIdentity(String address, String password) async { - final idtyIndex = await getIdentityIndexOf(address); - - final sender = TxSenderData( - keyring.current.address, - keyring.current.pubKey, - ); - - log.d(sender.address); - TxInfoData txInfo; - - txInfo = TxInfoData( - 'membership', - 'revokeMembership', - sender, - ); - - try { - final hash = await sdk.api.tx - .signAndSend( - txInfo, - [idtyIndex], - password, - ) - .timeout( - const Duration(seconds: 12), - onTimeout: () => {}, - ); - log.d(hash); - if (hash.isEmpty) { - transactionStatus = 'timeout'; - notifyListeners(); - - return 'timeout'; - } else { - transactionStatus = hash.toString(); - notifyListeners(); - return hash.toString(); - } - } catch (e) { - transactionStatus = e.toString(); - notifyListeners(); - return e.toString(); - } - } - - Future getCurencyName() async {} - Future derive( BuildContext context, String address, int number, String password) async { final keypair = getKeypair(address); @@ -781,22 +600,155 @@ class SubstrateSdk with ChangeNotifier { return await sdk.api.keyring.checkMnemonicValid(mnemonic); } - String? getConnectedEndpoint() { - return sdk.api.connectedNode?.endpoint; + ////////////////////////////////////// + ///////// 5: CALLS EXECUTION ///////// + ////////////////////////////////////// + + Future pay( + {required String fromAddress, + required String destAddress, + required double amount, + required String password}) async { + transactionStatus = ''; + final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]); + final int amountUnit = (amount * 100).toInt(); + + final sender = TxSenderData( + fromAddress, + fromPubkey!.keys.first, + ); + + final txInfo = TxInfoData( + 'balances', amount == -1 ? 'transferAll' : 'transferKeepAlive', sender); + final txOptions = [destAddress, amount == -1 ? false : amountUnit]; + + return await executeCall(txInfo, txOptions, password); } - Future getSs58Prefix() async { - final List res = await sdk.webView!.evalJavascript( - 'api.consts.system.ss58Prefix.words', - wrapPromise: false) ?? - [42]; + Future certify( + String fromAddress, String password, String toAddress) async { + transactionStatus = ''; - ss58 = res[0]; - log.d(ss58); - return ss58; + final myIdtyStatus = await idtyStatus(fromAddress); + final toIdtyStatus = await idtyStatus(toAddress); + + final fromIndex = await getIdentityIndexOf(fromAddress); + final toIndex = await getIdentityIndexOf(toAddress); + + if (myIdtyStatus != 'Validated') { + transactionStatus = 'notMember'; + notifyListeners(); + return 'notMember'; + } + + final sender = _setSender(); + TxInfoData txInfo; + List txOptions = []; + + final toCerts = await getCerts(toAddress); + final currencyParameters = await getParameters(); + + if (toIdtyStatus == 'noid') { + txInfo = TxInfoData( + 'identity', + 'createIdentity', + sender, + ); + txOptions = [toAddress]; + } else if (toIdtyStatus == 'Validated' || + toIdtyStatus == 'ConfirmedByOwner') { + if (toCerts[0] >= currencyParameters['wotMinCertForMembership'] && + toIdtyStatus != 'Validated') { + log.i('Batch cert and membership validation'); + List batch = batchCall(sender, [ + 'cert.addCert($fromIndex, $toIndex)', + 'identity.validateIdentity($toIndex)' + ]); + txInfo = batch[0]; + txOptions = batch[1]; + } else { + txInfo = TxInfoData( + 'cert', + 'addCert', + sender, + ); + txOptions = [fromIndex, toIndex]; + } + } else { + transactionStatus = 'cantBeCert'; + notifyListeners(); + return 'cantBeCert'; + } + + log.d('Cert action: ${txInfo.call!}'); + return await executeCall(txInfo, txOptions, password); + } + + Future claimUDs(String password) async { + final sender = TxSenderData( + keyring.current.address, + keyring.current.pubKey, + ); + + final txInfo = TxInfoData( + 'universalDividend', + 'claimUds', + sender, + ); + + return await executeCall(txInfo, [], password); + } + + Future confirmIdentity( + String fromAddress, String name, String password) async { + log.d('me: ${keyring.current.address!}'); + + final sender = TxSenderData( + keyring.current.address, + keyring.current.pubKey, + ); + + final txInfo = TxInfoData( + 'identity', + 'confirmIdentity', + sender, + ); + final txOptions = [name]; + + return await executeCall(txInfo, txOptions, password); + } + + Future revokeIdentity(String address, String password) async { + final idtyIndex = await getIdentityIndexOf(address); + + final sender = TxSenderData( + keyring.current.address, + keyring.current.pubKey, + ); + + log.d(sender.address); + TxInfoData txInfo; + + txInfo = TxInfoData( + 'membership', + 'revokeMembership', + sender, + ); + + final txOptions = [idtyIndex]; + + return await executeCall(txInfo, txOptions, password); + } + + void reload() { + notifyListeners(); } } +//////////////////////////////////////////// +/////// 6: UI ELEMENTS (off class) ///////// +//////////////////////////////////////////// + void snack(BuildContext context, String message, {int duration = 2}) { final snackBar = SnackBar(content: Text(message), duration: Duration(seconds: duration)); diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 08ef20f..b3e8715 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -78,10 +78,13 @@ class SettingsScreen extends StatelessWidget { final customEndpoint = NetworkParams(); customEndpoint.endpoint = 'Personnalisé'; + final localEndpoint = NetworkParams(); + localEndpoint.endpoint = 'ws://127.0.0.1:9944'; final automaticEndpoint = NetworkParams(); automaticEndpoint.endpoint = 'Auto'; // duniterBootstrapNodes.add(_sub.getDuniterCustomEndpoint()); duniterBootstrapNodes.insert(0, automaticEndpoint); + duniterBootstrapNodes.add(localEndpoint); duniterBootstrapNodes.add(customEndpoint); if (configBox.get('autoEndpoint') == true) { From 99c559d38c5ed3e479c444441ba8e93fdb019e91 Mon Sep 17 00:00:00 2001 From: poka Date: Thu, 11 Aug 2022 19:19:50 +0200 Subject: [PATCH 10/13] improve balance results; workaround batch (wip) --- lib/providers/generate_wallets.dart | 11 +++-- lib/providers/substrate_sdk.dart | 76 +++++++++++++++++++++++------ lib/providers/wallet_options.dart | 11 +++-- lib/screens/wallet_view.dart | 8 +-- 4 files changed, 77 insertions(+), 29 deletions(-) diff --git a/lib/providers/generate_wallets.dart b/lib/providers/generate_wallets.dart index 65b8982..871c177 100644 --- a/lib/providers/generate_wallets.dart +++ b/lib/providers/generate_wallets.dart @@ -385,19 +385,20 @@ class GenerateWalletsProvider with ChangeNotifier { } for (var derivationNbr in [for (var i = 0; i < numberScan; i += 1) i]) { - final addressData = await sub.sdk.api.keyring.addressFromMnemonic(sub.ss58, + final addressData = await sub.sdk.api.keyring.addressFromMnemonic( + sub.ss58, cryptoType: CryptoType.sr25519, mnemonic: generatedMnemonic!, derivePath: '//$derivationNbr'); final balance = await sub.getBalance(addressData.address!).timeout( const Duration(seconds: 1), - onTimeout: () => 0, + onTimeout: () => {}, ); // const balance = 0; log.d(balance); - if (balance != 0) { + if (balance != {}) { isAlive = true; String walletName = scanedWalletNumber == 0 ? 'currentWallet'.tr() @@ -431,11 +432,11 @@ class GenerateWalletsProvider with ChangeNotifier { final balance = await sub.getBalance(addressData.address!).timeout( const Duration(seconds: 1), - onTimeout: () => 0, + onTimeout: () => {}, ); log.d(balance); - if (balance != 0) { + if (balance != {}) { String walletName = 'myRootWallet'.tr(); await sub.importAccount( mnemonic: '', fromMnemonic: true, password: pin.text); diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index f60a1fb..a60f322 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -78,9 +78,8 @@ class SubstrateSdk with ChangeNotifier { 'batchAll', sender, ); - List txOptions = calls; - return [txInfo, txOptions]; + return [txInfo, calls]; } TxSenderData _setSender() { @@ -99,7 +98,9 @@ class SubstrateSdk with ChangeNotifier { for (var element in keyring.allAccounts) { final account = AddressInfo(address: element.address); - account.balance = await getBalance(element.address!); + final globalBalance = await getBalance(element.address!); + account.balance = globalBalance['transferableBalance']!; + result.add(account); } @@ -164,7 +165,7 @@ class SubstrateSdk with ChangeNotifier { // return balance; // } - Future getBalance(String address) async { + Future> getBalance(String address) async { // Get onchain storage values final Map balanceGlobal = await getStorage('system.account("$address")'); final int? idtyIndex = @@ -178,22 +179,26 @@ class SubstrateSdk with ChangeNotifier { await getStorage('universalDividend.pastReevals()'); // Compute amount of claimable UDs - final int newUdsAmount = _computeClaimUds(currentUdIndex, + final int unclaimedUds = _computeUnclaimUds(currentUdIndex, idtyData?['data']?['firstEligibleUd'] ?? 0, pastReevals); // Calculate transferable and potential balance final int transferableBalance = - (balanceGlobal['data']['free'] + newUdsAmount); - final int potentialBalance = - (balanceGlobal['data']['reserved'] + transferableBalance); + (balanceGlobal['data']['free'] + unclaimedUds); - log.i( - 'transferableBalance: $transferableBalance --- potentialBalance: $potentialBalance'); + Map finalBalances = { + 'transferableBalance': transferableBalance / 100, + 'free': balanceGlobal['data']['free'] / 100, + 'unclaimedUds': unclaimedUds / 100, + 'reserved': balanceGlobal['data']['reserved'] / 100, + }; - return transferableBalance / 100; + // log.i(finalBalances); + + return finalBalances; } - int _computeClaimUds( + int _computeUnclaimUds( int currentUdIndex, int firstEligibleUd, List pastReevals) { int totalAmount = 0; @@ -618,9 +623,50 @@ class SubstrateSdk with ChangeNotifier { fromPubkey!.keys.first, ); - final txInfo = TxInfoData( - 'balances', amount == -1 ? 'transferAll' : 'transferKeepAlive', sender); - final txOptions = [destAddress, amount == -1 ? false : amountUnit]; + final globalBalance = await getBalance(fromAddress); + TxInfoData txInfo; + List txOptions; + + log.d(globalBalance); + + // if (globalBalance['unclaimedUds'] != 0) { + // claimUDs(password); + // } + + // txInfo = TxInfoData( + // 'balances', amount == -1 ? 'transferAll' : 'transferKeepAlive', sender); + // txOptions = [destAddress, amount == -1 ? false : amountUnit]; + + if (globalBalance['unclaimedUds'] == 0) { + txInfo = TxInfoData('balances', + amount == -1 ? 'transferAll' : 'transferKeepAlive', sender); + txOptions = [destAddress, amount == -1 ? false : amountUnit]; + } else { + txInfo = TxInfoData( + 'utility', + 'batchAll', + sender, + ); + + txOptions = [ + ['api.tx.universalDividend.claimUds()'] + ]; + // 'balances.transferKeepAlive($destAddress, $amountUnit)' + // amount == -1 + // ? 'balances.transferAll(false)' + // : 'balances.transferKeepAlive([$destAddress, $amountUnit])' + } + + log.d('yooooo: ${txInfo.module}, ${txInfo.call}, $txOptions'); + // Map tata = await sdk.webView! + // .evalJavascript('api.tx.universalDividend.claimUds()', + // wrapPromise: false) + // .timeout( + // const Duration(seconds: 12), + // onTimeout: () => {}, + // ); + + // return tata.toString(); return await executeCall(txInfo, txOptions, password); } diff --git a/lib/providers/wallet_options.dart b/lib/providers/wallet_options.dart index 3aa3bb9..fa0c421 100644 --- a/lib/providers/wallet_options.dart +++ b/lib/providers/wallet_options.dart @@ -56,7 +56,7 @@ class WalletOptionsProvider with ChangeNotifier { if (answer ?? false) { //Check if balance is null final balance = await sub.getBalance(wallet.address!); - if (balance != 0) { + if (balance != {}) { MyWalletsProvider myWalletProvider = Provider.of(context, listen: false); final defaultWallet = myWalletProvider.getDefaultWallet(); @@ -531,9 +531,10 @@ Widget balance(BuildContext context, String address, double size, Consumer(builder: (context, sdk, _) { return FutureBuilder( future: sdk.getBalance(address), - builder: (BuildContext context, AsyncSnapshot balance) { - if (balance.connectionState != ConnectionState.done || - balance.hasError) { + builder: (BuildContext context, + AsyncSnapshot> globalBalance) { + if (globalBalance.connectionState != ConnectionState.done || + globalBalance.hasError) { if (balanceCache[address] != null && balanceCache[address] != -1) { return Text( @@ -551,7 +552,7 @@ Widget balance(BuildContext context, String address, double size, ); } } - balanceCache[address] = balance.data!; + balanceCache[address] = globalBalance.data!['transferableBalance']!; if (balanceCache[address] != -1) { return Text( "${balanceCache[address]!.toString()} $currencyName", diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index e2cebd9..36f5478 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -518,10 +518,10 @@ class WalletViewScreen extends StatelessWidget { future: sub.getBalance(defaultWallet.address!), builder: (BuildContext context, - AsyncSnapshot balance) { - if (balance.connectionState != + AsyncSnapshot> globalBalance) { + if (globalBalance.connectionState != ConnectionState.done || - balance.hasError) { + globalBalance.hasError) { if (balanceCache[ defaultWallet.address!] != null) { @@ -542,7 +542,7 @@ class WalletViewScreen extends StatelessWidget { } } balanceCache[defaultWallet.address!] = - balance.data!; + globalBalance.data!['transferableBalance']!; return Text( "${balanceCache[defaultWallet.address!]} $currencyName", style: const TextStyle( From 2d1b3731bb32c8d3aeec2d42e60a1efdc6b83f43 Mon Sep 17 00:00:00 2001 From: poka Date: Fri, 12 Aug 2022 10:04:55 +0200 Subject: [PATCH 11/13] batch call is working for claimUd --- lib/providers/substrate_sdk.dart | 101 +++++++++++-------------------- lib/screens/wallet_view.dart | 10 +-- 2 files changed, 41 insertions(+), 70 deletions(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index a60f322..0bc57d1 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -37,15 +37,11 @@ class SubstrateSdk with ChangeNotifier { ////////// 1: API METHODS /////////// ///////////////////////////////////// - Future executeCall( - TxInfoData txInfo, txOptions, String password) async { + Future executeCall(TxInfoData txInfo, txOptions, String password, + [String? rawParams]) async { try { final hash = await sdk.api.tx - .signAndSend( - txInfo, - txOptions, - password, - ) + .signAndSend(txInfo, txOptions, password, rawParam: rawParams) .timeout( const Duration(seconds: 12), onTimeout: () => {}, @@ -72,16 +68,6 @@ class SubstrateSdk with ChangeNotifier { return await sdk.webView!.evalJavascript('api.query.$call'); } - List batchCall(TxSenderData sender, List calls) { - TxInfoData txInfo = TxInfoData( - 'utility', - 'batchAll', - sender, - ); - - return [txInfo, calls]; - } - TxSenderData _setSender() { return TxSenderData( keyring.current.address, @@ -625,17 +611,8 @@ class SubstrateSdk with ChangeNotifier { final globalBalance = await getBalance(fromAddress); TxInfoData txInfo; - List txOptions; - - log.d(globalBalance); - - // if (globalBalance['unclaimedUds'] != 0) { - // claimUDs(password); - // } - - // txInfo = TxInfoData( - // 'balances', amount == -1 ? 'transferAll' : 'transferKeepAlive', sender); - // txOptions = [destAddress, amount == -1 ? false : amountUnit]; + List txOptions = []; + String? rawParams; if (globalBalance['unclaimedUds'] == 0) { txInfo = TxInfoData('balances', @@ -647,28 +624,16 @@ class SubstrateSdk with ChangeNotifier { 'batchAll', sender, ); + const tx1 = 'api.tx.universalDividend.claimUds()'; + final tx2 = amount == -1 + ? 'api.tx.balances.transferAll(false)' + : 'api.tx.balances.transferKeepAlive("$destAddress", $amountUnit)'; - txOptions = [ - ['api.tx.universalDividend.claimUds()'] - ]; - // 'balances.transferKeepAlive($destAddress, $amountUnit)' - // amount == -1 - // ? 'balances.transferAll(false)' - // : 'balances.transferKeepAlive([$destAddress, $amountUnit])' + rawParams = '[[$tx1, $tx2]]'; } - log.d('yooooo: ${txInfo.module}, ${txInfo.call}, $txOptions'); - // Map tata = await sdk.webView! - // .evalJavascript('api.tx.universalDividend.claimUds()', - // wrapPromise: false) - // .timeout( - // const Duration(seconds: 12), - // onTimeout: () => {}, - // ); - - // return tata.toString(); - - return await executeCall(txInfo, txOptions, password); + // log.d('yooooo: ${txInfo.module}, ${txInfo.call}, $txOptions, $rawParams'); + return await executeCall(txInfo, txOptions, password, rawParams); } Future certify( @@ -690,6 +655,7 @@ class SubstrateSdk with ChangeNotifier { final sender = _setSender(); TxInfoData txInfo; List txOptions = []; + String? rawParams; final toCerts = await getCerts(toAddress); final currencyParameters = await getParameters(); @@ -706,12 +672,15 @@ class SubstrateSdk with ChangeNotifier { if (toCerts[0] >= currencyParameters['wotMinCertForMembership'] && toIdtyStatus != 'Validated') { log.i('Batch cert and membership validation'); - List batch = batchCall(sender, [ - 'cert.addCert($fromIndex, $toIndex)', - 'identity.validateIdentity($toIndex)' - ]); - txInfo = batch[0]; - txOptions = batch[1]; + txInfo = TxInfoData( + 'utility', + 'batchAll', + sender, + ); + final tx1 = 'cert.addCert($fromIndex, $toIndex)'; + final tx2 = 'identity.validateIdentity($toIndex)'; + + rawParams = '[[$tx1, $tx2]]'; } else { txInfo = TxInfoData( 'cert', @@ -727,23 +696,23 @@ class SubstrateSdk with ChangeNotifier { } log.d('Cert action: ${txInfo.call!}'); - return await executeCall(txInfo, txOptions, password); + return await executeCall(txInfo, txOptions, password, rawParams); } - Future claimUDs(String password) async { - final sender = TxSenderData( - keyring.current.address, - keyring.current.pubKey, - ); + // Future claimUDs(String password) async { + // final sender = TxSenderData( + // keyring.current.address, + // keyring.current.pubKey, + // ); - final txInfo = TxInfoData( - 'universalDividend', - 'claimUds', - sender, - ); + // final txInfo = TxInfoData( + // 'universalDividend', + // 'claimUds', + // sender, + // ); - return await executeCall(txInfo, [], password); - } + // return await executeCall(txInfo, [], password); + // } Future confirmIdentity( String fromAddress, String name, String password) async { diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index 36f5478..7d2c5cb 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -129,8 +129,8 @@ class WalletViewScreen extends StatelessWidget { builder: (context, AsyncSnapshot> snapshot) { if (snapshot.data == null) return const SizedBox(); String duration = ''; - log.d(snapshot.data!['certDelay']); - log.d(snapshot.data!['certRenewable']); + log.d('certDelay ${snapshot.data!['certDelay']}'); + log.d('certRenewable ${snapshot.data!['certRenewable']}'); if (snapshot.data!['certDelay'] != null || snapshot.data!['certRenewable'] != null) { @@ -518,7 +518,8 @@ class WalletViewScreen extends StatelessWidget { future: sub.getBalance(defaultWallet.address!), builder: (BuildContext context, - AsyncSnapshot> globalBalance) { + AsyncSnapshot> + globalBalance) { if (globalBalance.connectionState != ConnectionState.done || globalBalance.hasError) { @@ -542,7 +543,8 @@ class WalletViewScreen extends StatelessWidget { } } balanceCache[defaultWallet.address!] = - globalBalance.data!['transferableBalance']!; + globalBalance + .data!['transferableBalance']!; return Text( "${balanceCache[defaultWallet.address!]} $currencyName", style: const TextStyle( From c603d2b2017522385e203f90e459e51ba4dbbb68 Mon Sep 17 00:00:00 2001 From: poka Date: Sat, 13 Aug 2022 13:45:43 +0200 Subject: [PATCH 12/13] fix: can delete wallet just after set it to default --- lib/providers/substrate_sdk.dart | 4 +++- lib/screens/myWallets/wallet_options.dart | 3 +++ pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 0bc57d1..91f8b15 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -261,7 +261,9 @@ class SubstrateSdk with ChangeNotifier { } else { result.putIfAbsent('canCert', () => 0); } + log.d('tatatatata: ${nextIssuableOn - blocNumber}'); } + return result; } @@ -632,7 +634,7 @@ class SubstrateSdk with ChangeNotifier { rawParams = '[[$tx1, $tx2]]'; } - // log.d('yooooo: ${txInfo.module}, ${txInfo.call}, $txOptions, $rawParams'); + // log.d('pay args: ${txInfo.module}, ${txInfo.call}, $txOptions, $rawParams'); return await executeCall(txInfo, txOptions, password, rawParams); } diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index c038376..8c6b784 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -457,12 +457,15 @@ class WalletOptions extends StatelessWidget { SubstrateSdk sub = Provider.of(context, listen: false); MyWalletsProvider myWalletProvider = Provider.of(context, listen: false); + WalletOptionsProvider walletOptions = + Provider.of(context, listen: false); // WalletData defaultWallet = _myWalletProvider.getDefaultWallet()!; // defaultWallet = wallet; await sub.setCurrentWallet(wallet); myWalletProvider.readAllWallets(currentChest); myWalletProvider.rebuildWidget(); + walletOptions.reloadBuild(); } Widget deleteWallet(BuildContext context, diff --git a/pubspec.yaml b/pubspec.yaml index fad4eda..e238544 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ description: Pay with G1. # pub.dev using `pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 0.0.9+17 +version: 0.0.9+18 environment: sdk: '>=2.12.0 <3.0.0' From 7b778a74b1fec82b2dfa5e6279ae6ad1f7aed3c3 Mon Sep 17 00:00:00 2001 From: poka Date: Sun, 14 Aug 2022 16:34:24 +0200 Subject: [PATCH 13/13] check if node is connected before check balances --- lib/providers/substrate_sdk.dart | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 91f8b15..bf516d4 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -152,6 +152,15 @@ class SubstrateSdk with ChangeNotifier { // } Future> getBalance(String address) async { + if (!nodeConnected) { + return { + 'transferableBalance': 0, + 'free': 0, + 'unclaimedUds': 0, + 'reserved': 0, + }; + } + // Get onchain storage values final Map balanceGlobal = await getStorage('system.account("$address")'); final int? idtyIndex =