From 77223efe19e6795f125807003a344826030f4901 Mon Sep 17 00:00:00 2001 From: shawn Date: Tue, 24 Mar 2020 15:37:38 +0800 Subject: [PATCH] update polkadot-js/api to v1.9.0-beta.0 & refactored referendum vote --- CHANGELOG.md | 3 + ios/Runner.xcodeproj/project.pbxproj | 2 - lib/app.dart | 2 + lib/page/account/txConfirmPage.dart | 3 +- lib/page/governance/democracy/democracy.dart | 6 +- .../governance/democracy/referendumPanel.dart | 41 ++-- .../democracy/referendumVotePage.dart | 202 ++++++++++++++++++ lib/page/staking/validators/overview.dart | 6 +- lib/polkadot_js_service/package.json | 2 +- .../src/service/account.js | 2 +- lib/polkadot_js_service/src/service/gov.js | 61 +++--- lib/polkadot_js_service/yarn.lock | 110 +++++----- lib/service/substrateApi/api.dart | 2 + lib/service/substrateApi/apiGov.dart | 14 +- lib/store/account.dart | 8 + lib/store/account.g.dart | 27 +++ lib/store/governance.dart | 43 +--- lib/store/governance.g.dart | 35 +-- lib/utils/i18n/home.dart | 10 + pubspec.yaml | 2 +- 20 files changed, 388 insertions(+), 193 deletions(-) create mode 100644 lib/page/governance/democracy/referendumVotePage.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index a1d2461f..d7756204 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 0.6.2 +- Update polkadot-js/api to 1.9.0-beta.0 + # 0.6.1 - fix nominator list bug - Refactor pending payouts query diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 6038b597..14b17cd2 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 29E32FB92428BC47006F05B2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2E5C930B0B11FFACB230966 /* Pods_Runner.framework */; }; - 29E32FBA2428BC47006F05B2 /* Pods_Runner.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E2E5C930B0B11FFACB230966 /* Pods_Runner.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -30,7 +29,6 @@ files = ( 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, - 29E32FBA2428BC47006F05B2 /* Pods_Runner.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; diff --git a/lib/app.dart b/lib/app.dart index c57dc473..43644bd6 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -12,6 +12,7 @@ import 'package:polka_wallet/page/assets/transfer/transferPage.dart'; import 'package:polka_wallet/page/governance/council/candidateDetailPage.dart'; import 'package:polka_wallet/page/governance/council/candidateListPage.dart'; import 'package:polka_wallet/page/governance/council/councilVotePage.dart'; +import 'package:polka_wallet/page/governance/democracy/referendumVotePage.dart'; import 'package:polka_wallet/page/profile/aboutPage.dart'; import 'package:polka_wallet/page/profile/account/accountManagePage.dart'; import 'package:polka_wallet/page/profile/account/changeNamePage.dart'; @@ -164,6 +165,7 @@ class _WalletAppState extends State { CandidateDetailPage.route: (_) => CandidateDetailPage(_appStore), CouncilVotePage.route: (_) => CouncilVotePage(_appStore), CandidateListPage.route: (_) => CandidateListPage(_appStore), + ReferendumVotePage.route: (_) => ReferendumVotePage(_appStore), // profile AccountManagePage.route: (_) => AccountManagePage(_appStore), ContactsPage.route: (_) => ContactsPage(_appStore.settings), diff --git a/lib/page/account/txConfirmPage.dart b/lib/page/account/txConfirmPage.dart index 616fba92..eeb21b17 100644 --- a/lib/page/account/txConfirmPage.dart +++ b/lib/page/account/txConfirmPage.dart @@ -89,12 +89,13 @@ class _TxConfirmPageState extends State { } store.assets.setSubmitting(true); + store.account.setTxStatus('queued'); state.showSnackBar(SnackBar( backgroundColor: Theme.of(context).cardColor, content: ListTile( leading: CupertinoActivityIndicator(), title: Text( - dic['submit.tx'], + dic['tx.${store.account.txStatus}'] ?? dic['tx.queued'], style: TextStyle(color: Colors.black54), ), ), diff --git a/lib/page/governance/democracy/democracy.dart b/lib/page/governance/democracy/democracy.dart index 8755bf67..40ebd43e 100644 --- a/lib/page/governance/democracy/democracy.dart +++ b/lib/page/governance/democracy/democracy.dart @@ -141,14 +141,12 @@ class _DemocracyState extends State { : ListView.builder( itemCount: list.length, itemBuilder: (BuildContext context, int i) { - int voted = store.gov.votedMap[list[i].index]; return ReferendumPanel( data: list[i], bestNumber: bestNumber, - votes: store.gov.referendumVotes[list[i].index], + votes: list[i].votes, symbol: symbol, - onVote: _onVote, - voted: voted, + voted: store.gov.votedMap[list[i].index], ); }, ), diff --git a/lib/page/governance/democracy/referendumPanel.dart b/lib/page/governance/democracy/referendumPanel.dart index eec4d3f9..778dce08 100644 --- a/lib/page/governance/democracy/referendumPanel.dart +++ b/lib/page/governance/democracy/referendumPanel.dart @@ -2,25 +2,25 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:polka_wallet/common/components/roundedButton.dart'; import 'package:polka_wallet/common/components/roundedCard.dart'; +import 'package:polka_wallet/page/governance/democracy/referendumVotePage.dart'; import 'package:polka_wallet/store/governance.dart'; import 'package:polka_wallet/utils/format.dart'; import 'package:polka_wallet/utils/i18n/index.dart'; class ReferendumPanel extends StatelessWidget { - ReferendumPanel( - {this.symbol, - this.data, - this.bestNumber, - this.votes, - this.voted, - this.onVote}); + ReferendumPanel({ + this.symbol, + this.data, + this.bestNumber, + this.votes, + this.voted, + }); final String symbol; final ReferendumInfo data; final int bestNumber; - final ReferendumVotes votes; + final Map votes; final int voted; - final Function(int, bool) onVote; @override Widget build(BuildContext context) { @@ -46,7 +46,7 @@ class ReferendumPanel extends StatelessWidget { child: Image.asset('assets/images/gov/time.png'), ), Text( - '${data.info['end'] + data.info['delay'] - bestNumber} blocks ${dic['end']}', + '${data.status['end'] + data.status['delay'] - bestNumber} blocks ${dic['end']}', style: TextStyle(color: Colors.lightGreen), ) ], @@ -111,8 +111,11 @@ class ReferendumPanel extends StatelessWidget { if (votes != null) { double widthFull = MediaQuery.of(context).size.width - 72; - double yes = votes.votedAye / votes.votedTotal; - double widthYes = votes.votedTotal > 0 ? yes * widthFull : widthFull / 2; + int votedTotal = int.parse(votes['votedTotal'].toString()); + int votedAye = int.parse(votes['votedAye'].toString()); + int votedNay = int.parse(votes['votedNay'].toString()); + double yes = int.parse(votes['votedAye'].toString()) / votedTotal; + double widthYes = votedTotal > 0 ? yes * widthFull : widthFull / 2; double widthMin = 6; list.add(Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -143,13 +146,13 @@ class ReferendumPanel extends StatelessWidget { list.add(Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text('${Fmt.token(votes.votedNay)} $symbol'), - Text('${Fmt.token(votes.votedAye)} $symbol') + Text('${Fmt.token(votedNay)} $symbol'), + Text('${Fmt.token(votedAye)} $symbol') ], )); } - bool votedYes = voted ?? 0 > 6; + bool votedYes = (voted ?? 0) > 6; list.add(Container( margin: EdgeInsets.only(top: 16), child: Row( @@ -160,7 +163,9 @@ class ReferendumPanel extends StatelessWidget { text: '${voted != null && !votedYes ? dic['voted'] : ''} ${dic['no']}', onPressed: voted == null || votedYes - ? () => onVote(data.index, false) + ? () => Navigator.of(context).pushNamed( + ReferendumVotePage.route, + arguments: {'referenda': data, 'voteYes': false}) : null, ), ), @@ -170,7 +175,9 @@ class ReferendumPanel extends StatelessWidget { text: '${voted != null && votedYes ? dic['voted'] : ''} ${dic['yes']}', onPressed: voted == null || !votedYes - ? () => onVote(data.index, true) + ? () => Navigator.of(context).pushNamed( + ReferendumVotePage.route, + arguments: {'referenda': data, 'voteYes': true}) : null, ), ) diff --git a/lib/page/governance/democracy/referendumVotePage.dart b/lib/page/governance/democracy/referendumVotePage.dart new file mode 100644 index 00000000..df7eac49 --- /dev/null +++ b/lib/page/governance/democracy/referendumVotePage.dart @@ -0,0 +1,202 @@ +import 'dart:convert'; +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:polka_wallet/common/components/roundedButton.dart'; +import 'package:polka_wallet/common/regInputFormatter.dart'; +import 'package:polka_wallet/page/account/txConfirmPage.dart'; +import 'package:polka_wallet/store/app.dart'; +import 'package:polka_wallet/store/governance.dart'; +import 'package:polka_wallet/utils/UI.dart'; +import 'package:polka_wallet/utils/format.dart'; +import 'package:polka_wallet/utils/i18n/index.dart'; + +class ReferendumVotePage extends StatefulWidget { + ReferendumVotePage(this.store); + static final String route = '/gov/referenda'; + final AppStore store; + @override + _ReferendumVoteState createState() => _ReferendumVoteState(store); +} + +class _ReferendumVoteState extends State { + _ReferendumVoteState(this.store); + final AppStore store; + + final _formKey = GlobalKey(); + + final TextEditingController _amountCtrl = new TextEditingController(); + + final List _voteConvictionOptions = [0, 1, 2, 3, 4, 5, 6]; + + int _voteConviction = 0; + + void _onSubmit(int id, bool voteYes) { + if (_formKey.currentState.validate()) { + var govDic = I18n.of(context).gov; + int decimals = store.settings.networkState.tokenDecimals; + String amt = _amountCtrl.text.trim(); + Map vote = { + 'balance': (double.parse(amt) * pow(10, decimals)).toInt(), + 'vote': {'aye': voteYes, 'conviction': _voteConviction}, + }; + var args = { + "title": govDic['vote.proposal'], + "txInfo": { + "module": 'democracy', + "call": 'vote', + }, + "detail": jsonEncode({ + "id": id, + "balance": amt, + "vote": vote['vote'], + }), + "params": [ + // "id" + id, + // "options" + {"Standard": vote}, + ], + 'onFinish': (BuildContext txPageContext) { + Navigator.popUntil(txPageContext, ModalRoute.withName('/')); + globalDemocracyRefreshKey.currentState.show(); + } + }; + Navigator.of(context).pushNamed(TxConfirmPage.route, arguments: args); + } + } + + List _calcTimes(int value) { + double amountX = 0.1; + int timeX = 0; + if (value > 0) { + amountX = value * 1.0; + timeX = pow(2, value - 1); + } + return [amountX, timeX]; + } + + String _getConvictionLabel(int value) { + var dicGov = I18n.of(context).gov; + List times = _calcTimes(value); + return value == 0 + ? dicGov['locked.no'] + : '${dicGov['locked']} ${times[1] * 8} ${dicGov['day']} (${times[1]}x)'; + } + + void _showConvictionSelect() { + showCupertinoModalPopup( + context: context, + builder: (_) => Container( + height: MediaQuery.of(context).copyWith().size.height / 3, + child: WillPopScope( + child: CupertinoPicker( + backgroundColor: Colors.white, + itemExtent: 58, + scrollController: + FixedExtentScrollController(initialItem: _voteConviction), + children: _voteConvictionOptions.map((i) { + return Padding( + padding: EdgeInsets.all(16), + child: Text(_getConvictionLabel(i))); + }).toList(), + onSelectedItemChanged: (v) { + setState(() { + _voteConviction = v; + }); + }, + ), + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + var govDic = I18n.of(context).gov; + return Scaffold( + appBar: AppBar( + title: Text(govDic['vote.proposal']), + centerTitle: true, + ), + body: Observer( + builder: (_) { + final Map dic = I18n.of(context).assets; + final Map dicGov = I18n.of(context).gov; + int decimals = store.settings.networkState.tokenDecimals; + + int balance = Fmt.balanceInt(store.assets.balance); + + Map args = ModalRoute.of(context).settings.arguments; + ReferendumInfo info = args['referenda']; + bool voteYes = args['voteYes']; + return SafeArea( + child: Column( + children: [ + Expanded( + child: Form( + key: _formKey, + child: ListView( + children: [ + Padding( + padding: EdgeInsets.all(16), + child: Text( + dicGov[voteYes ? 'yes.text' : 'no.text'], + style: Theme.of(context).textTheme.display4, + ), + ), + Padding( + padding: + EdgeInsets.only(left: 16, right: 16, bottom: 16), + child: TextFormField( + decoration: InputDecoration( + hintText: dic['amount'], + labelText: + '${dic['amount']} (${dic['balance']}: ${Fmt.token(balance)})', + ), + inputFormatters: [ + RegExInputFormatter.withRegex( + '^[0-9]{0,6}(\\.[0-9]{0,$decimals})?\$') + ], + controller: _amountCtrl, + keyboardType: + TextInputType.numberWithOptions(decimal: true), + validator: (v) { + if (v.isEmpty) { + return dic['amount.error']; + } + if (double.parse(v.trim()) >= + balance / pow(10, decimals)) { + return dic['amount.low']; + } + return null; + }, + ), + ), + ListTile( + title: Text(dicGov['locked']), + subtitle: Text(_getConvictionLabel(_voteConviction)), + trailing: Icon(Icons.arrow_forward_ios, size: 18), + onTap: _showConvictionSelect, + ), + ], + ), + ), + ), + Container( + padding: EdgeInsets.all(16), + child: RoundedButton( + text: I18n.of(context).home['submit.tx'], + onPressed: () => _onSubmit(info.index, voteYes), + ), + ) + ], + ), + ); + }, + ), + ); + } +} diff --git a/lib/page/staking/validators/overview.dart b/lib/page/staking/validators/overview.dart index ff5af5dd..d9adea15 100644 --- a/lib/page/staking/validators/overview.dart +++ b/lib/page/staking/validators/overview.dart @@ -174,8 +174,7 @@ class _StakingOverviewPageState extends State { return Container(); } String symbol = store.settings.networkState.tokenSymbol; - String address = store.account.currentAddress; - + String stashAddress = store.staking.ledger['stakingLedger']['stash']; List nominators = store.staking.ledger['nominators']; return Container( @@ -202,10 +201,11 @@ class _StakingOverviewPageState extends State { int meStaked; int meIndex = - validator.nominators.indexWhere((i) => i['who'] == address); + validator.nominators.indexWhere((i) => i['who'] == stashAddress); if (meIndex >= 0) { meStaked = validator.nominators[meIndex]['value']; } + Map accInfo = store.account.accountIndexMap[id]; return Expanded( child: ListTile( diff --git a/lib/polkadot_js_service/package.json b/lib/polkadot_js_service/package.json index 95d6e456..9bb52684 100644 --- a/lib/polkadot_js_service/package.json +++ b/lib/polkadot_js_service/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@babel/polyfill": "^7.8.3", - "@polkadot/api": "1.8.0-beta.1", + "@polkadot/api": "1.9.0-beta.0", "@polkadot/ui-shared": "^0.51.1", "bn.js": "^5.1.1", "store": "^2.0.12" diff --git a/lib/polkadot_js_service/src/service/account.js b/lib/polkadot_js_service/src/service/account.js index 7679726b..561694af 100644 --- a/lib/polkadot_js_service/src/service/account.js +++ b/lib/polkadot_js_service/src/service/account.js @@ -178,7 +178,7 @@ function sendTx(txInfo, paramList) { resolve({ hash: result.status.asInBlock.toHex() }); unsub(); } else { - window.send("log", result.status.type); + window.send("txStatusChange", result.status.type); } }; const tx = api.tx[txInfo.module][txInfo.call](...paramList); diff --git a/lib/polkadot_js_service/src/service/gov.js b/lib/polkadot_js_service/src/service/gov.js index ab4a0850..0190fb11 100644 --- a/lib/polkadot_js_service/src/service/gov.js +++ b/lib/polkadot_js_service/src/service/gov.js @@ -4,39 +4,30 @@ import { GenericCall, getTypeDef } from "@polkadot/types"; import registry from "../utils/registry"; -async function getReferendumVotes(index) { - return api.derive.democracy.referendumVotesFor(index).then(votesFor => { - const newState = votesFor.reduce( - (state, { balance, vote }) => { - const isDefault = vote.conviction.index === 0; - const counted = balance - .muln(isDefault ? 1 : vote.conviction.index) - .divn(isDefault ? 10 : 1); +async function _getReferendumVotes(tally, index) { + const votes = await api.derive.democracy.referendumVotes(index); - if (vote.isAye) { - state.voteCountAye++; - state.votedAye = state.votedAye.add(counted); - } else { - state.voteCountNay++; - state.votedNay = state.votedNay.add(counted); - } + const allAye = []; + const allNay = []; - state.voteCount++; - state.votedTotal = state.votedTotal.add(counted); - - return state; - }, - { - voteCount: 0, - voteCountAye: 0, - voteCountNay: 0, - votedAye: new BN(0), - votedNay: new BN(0), - votedTotal: new BN(0) - } - ); - return newState; + votes.forEach(derived => { + if (derived.vote.isAye) { + allAye.push(derived); + } else { + allNay.push(derived); + } }); + + return { + allAye, + allNay, + voteCount: allAye.length + allNay.length, + voteCountAye: allAye.length, + voteCountNay: allNay.length, + votedAye: tally.ayes, + votedNay: tally.nays, + votedTotal: tally.turnout + }; } function _extractMetaData(value) { @@ -54,6 +45,9 @@ function _extractMetaData(value) { async function fetchReferendums() { const referendums = await api.derive.democracy.referendums(); + const votes = await Promise.all( + referendums.map(i => _getReferendumVotes(i.status.tally, i.index)) + ); const details = referendums.map(i => { if (!i.proposal) { return {}; @@ -67,7 +61,7 @@ async function fetchReferendums() { ...parsedMeta }; }); - return { referendums, details }; + return { referendums, details, votes }; } async function subBestNumber() { @@ -84,4 +78,7 @@ async function subBestNumber() { }); } -export default { getReferendumVotes, fetchReferendums, subBestNumber }; +export default { + fetchReferendums, + subBestNumber +}; diff --git a/lib/polkadot_js_service/yarn.lock b/lib/polkadot_js_service/yarn.lock index f7519ec1..ec49b5c1 100644 --- a/lib/polkadot_js_service/yarn.lock +++ b/lib/polkadot_js_service/yarn.lock @@ -775,6 +775,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.9.2": + version "7.9.2" + resolved "https://registry.npm.taobao.org/@babel/runtime/download/@babel/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha1-2Q3wWDo6JS8JqqYZZlNnuuUY2wY= + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.4.0", "@babel/template@^7.8.3": version "7.8.3" resolved "https://registry.npm.taobao.org/@babel/template/download/@babel/template-7.8.3.tgz?cache=0&sync_timestamp=1578980712423&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftemplate%2Fdownload%2F%40babel%2Ftemplate-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8" @@ -977,49 +984,40 @@ resolved "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs= -"@polkadot/api-derive@1.8.0-beta.1": - version "1.8.0-beta.1" - resolved "https://registry.npm.taobao.org/@polkadot/api-derive/download/@polkadot/api-derive-1.8.0-beta.1.tgz#f3d4a34c50d213fa385a4f9355752cd2435e5fa3" - integrity sha1-89SjTFDSE/o4Wk+TVXUs0kNeX6M= +"@polkadot/api-derive@1.9.0-beta.0": + version "1.9.0-beta.0" + resolved "https://registry.npm.taobao.org/@polkadot/api-derive/download/@polkadot/api-derive-1.9.0-beta.0.tgz#2b3ebb79a69393adeb1d9a5095ca46061a379dfa" + integrity sha1-Kz67eaaTk63rHZpQlcpGBho3nfo= dependencies: - "@babel/runtime" "^7.8.7" - "@polkadot/api" "1.8.0-beta.1" - "@polkadot/rpc-core" "1.8.0-beta.1" - "@polkadot/rpc-provider" "1.8.0-beta.1" - "@polkadot/types" "1.8.0-beta.1" + "@babel/runtime" "^7.9.2" + "@polkadot/api" "1.9.0-beta.0" + "@polkadot/rpc-core" "1.9.0-beta.0" + "@polkadot/rpc-provider" "1.9.0-beta.0" + "@polkadot/types" "1.9.0-beta.0" "@polkadot/util" "^2.6.2" "@polkadot/util-crypto" "^2.6.2" bn.js "^5.1.1" memoizee "^0.4.14" rxjs "^6.5.4" -"@polkadot/api@1.8.0-beta.1": - version "1.8.0-beta.1" - resolved "https://registry.npm.taobao.org/@polkadot/api/download/@polkadot/api-1.8.0-beta.1.tgz#50337edc2f7ec8c373428d05515f91b821512c62" - integrity sha1-UDN+3C9+yMNzQo0FUV+RuCFRLGI= +"@polkadot/api@1.9.0-beta.0": + version "1.9.0-beta.0" + resolved "https://registry.npm.taobao.org/@polkadot/api/download/@polkadot/api-1.9.0-beta.0.tgz#2177125f7759cd9684b8560cbf475a5ed5a9fb16" + integrity sha1-IXcSX3dZzZaEuFYMv0daXtWp+xY= dependencies: - "@babel/runtime" "^7.8.7" - "@polkadot/api-derive" "1.8.0-beta.1" + "@babel/runtime" "^7.9.2" + "@polkadot/api-derive" "1.9.0-beta.0" "@polkadot/keyring" "^2.6.2" - "@polkadot/metadata" "1.8.0-beta.1" - "@polkadot/rpc-core" "1.8.0-beta.1" - "@polkadot/rpc-provider" "1.8.0-beta.1" - "@polkadot/types" "1.8.0-beta.1" + "@polkadot/metadata" "1.9.0-beta.0" + "@polkadot/rpc-core" "1.9.0-beta.0" + "@polkadot/rpc-provider" "1.9.0-beta.0" + "@polkadot/types" "1.9.0-beta.0" "@polkadot/util" "^2.6.2" "@polkadot/util-crypto" "^2.6.2" bn.js "^5.1.1" eventemitter3 "^4.0.0" rxjs "^6.5.4" -"@polkadot/jsonrpc@1.8.0-beta.1": - version "1.8.0-beta.1" - resolved "https://registry.npm.taobao.org/@polkadot/jsonrpc/download/@polkadot/jsonrpc-1.8.0-beta.1.tgz#c5fa8a2d235d1b594eaf50f65742eb3bdb5ad63b" - integrity sha1-xfqKLSNdG1lOr1D2V0LrO9ta1js= - dependencies: - "@babel/runtime" "^7.8.7" - "@polkadot/types" "1.8.0-beta.1" - "@polkadot/util" "^2.6.2" - "@polkadot/keyring@^2.6.2": version "2.6.2" resolved "https://registry.npm.taobao.org/@polkadot/keyring/download/@polkadot/keyring-2.6.2.tgz#a0fc5b12e6b2bba738384fbc1cd93a0c61f30bac" @@ -1029,40 +1027,38 @@ "@polkadot/util" "2.6.2" "@polkadot/util-crypto" "2.6.2" -"@polkadot/metadata@1.8.0-beta.1": - version "1.8.0-beta.1" - resolved "https://registry.npm.taobao.org/@polkadot/metadata/download/@polkadot/metadata-1.8.0-beta.1.tgz#5c430da2da618722fab7083e7225c1a910c346fb" - integrity sha1-XEMNotphhyL6twg+ciXBqRDDRvs= +"@polkadot/metadata@1.9.0-beta.0": + version "1.9.0-beta.0" + resolved "https://registry.npm.taobao.org/@polkadot/metadata/download/@polkadot/metadata-1.9.0-beta.0.tgz#79292a198da5f6f50756bce0b16cb512862fe88a" + integrity sha1-eSkqGY2l9vUHVrzgsWy1EoYv6Io= dependencies: - "@babel/runtime" "^7.8.7" - "@polkadot/types" "1.8.0-beta.1" + "@babel/runtime" "^7.9.2" + "@polkadot/types" "1.9.0-beta.0" "@polkadot/util" "^2.6.2" "@polkadot/util-crypto" "^2.6.2" bn.js "^5.1.1" -"@polkadot/rpc-core@1.8.0-beta.1": - version "1.8.0-beta.1" - resolved "https://registry.npm.taobao.org/@polkadot/rpc-core/download/@polkadot/rpc-core-1.8.0-beta.1.tgz#1fe7922a57fb303f0248b7ab6280eae14cd94896" - integrity sha1-H+eSKlf7MD8CSLerYoDq4UzZSJY= +"@polkadot/rpc-core@1.9.0-beta.0": + version "1.9.0-beta.0" + resolved "https://registry.npm.taobao.org/@polkadot/rpc-core/download/@polkadot/rpc-core-1.9.0-beta.0.tgz#c8f53d517090264150b7f3c574666d743bd1381a" + integrity sha1-yPU9UXCQJkFQt/PFdGZtdDvROBo= dependencies: - "@babel/runtime" "^7.8.7" - "@polkadot/jsonrpc" "1.8.0-beta.1" - "@polkadot/metadata" "1.8.0-beta.1" - "@polkadot/rpc-provider" "1.8.0-beta.1" - "@polkadot/types" "1.8.0-beta.1" + "@babel/runtime" "^7.9.2" + "@polkadot/metadata" "1.9.0-beta.0" + "@polkadot/rpc-provider" "1.9.0-beta.0" + "@polkadot/types" "1.9.0-beta.0" "@polkadot/util" "^2.6.2" memoizee "^0.4.14" rxjs "^6.5.4" -"@polkadot/rpc-provider@1.8.0-beta.1": - version "1.8.0-beta.1" - resolved "https://registry.npm.taobao.org/@polkadot/rpc-provider/download/@polkadot/rpc-provider-1.8.0-beta.1.tgz#075c14b09c233d2220ad9adf2310a02f0fdfc0a8" - integrity sha1-B1wUsJwjPSIgrZrfIxCgLw/fwKg= +"@polkadot/rpc-provider@1.9.0-beta.0": + version "1.9.0-beta.0" + resolved "https://registry.npm.taobao.org/@polkadot/rpc-provider/download/@polkadot/rpc-provider-1.9.0-beta.0.tgz#959cd712bdc6e2f514d5d4c4e21fee480601fbce" + integrity sha1-lZzXEr3G4vUU1dTE4h/uSAYB+84= dependencies: - "@babel/runtime" "^7.8.7" - "@polkadot/jsonrpc" "1.8.0-beta.1" - "@polkadot/metadata" "1.8.0-beta.1" - "@polkadot/types" "1.8.0-beta.1" + "@babel/runtime" "^7.9.2" + "@polkadot/metadata" "1.9.0-beta.0" + "@polkadot/types" "1.9.0-beta.0" "@polkadot/util" "^2.6.2" "@polkadot/util-crypto" "^2.6.2" bn.js "^5.1.1" @@ -1070,13 +1066,13 @@ isomorphic-fetch "^2.2.1" websocket "^1.0.31" -"@polkadot/types@1.8.0-beta.1": - version "1.8.0-beta.1" - resolved "https://registry.npm.taobao.org/@polkadot/types/download/@polkadot/types-1.8.0-beta.1.tgz#da3c22d2a7504c7b0643e978b72e0df7a6a0be91" - integrity sha1-2jwi0qdQTHsGQ+l4ty4N96agvpE= +"@polkadot/types@1.9.0-beta.0": + version "1.9.0-beta.0" + resolved "https://registry.npm.taobao.org/@polkadot/types/download/@polkadot/types-1.9.0-beta.0.tgz#b881d8c9acd831dd24cbd820c5e0138420cb3f85" + integrity sha1-uIHYyazYMd0ky9ggxeAThCDLP4U= dependencies: - "@babel/runtime" "^7.8.7" - "@polkadot/metadata" "1.8.0-beta.1" + "@babel/runtime" "^7.9.2" + "@polkadot/metadata" "1.9.0-beta.0" "@polkadot/util" "^2.6.2" "@polkadot/util-crypto" "^2.6.2" "@types/bn.js" "^4.11.6" diff --git a/lib/service/substrateApi/api.dart b/lib/service/substrateApi/api.dart index 13f57a2e..c2cd10dc 100644 --- a/lib/service/substrateApi/api.dart +++ b/lib/service/substrateApi/api.dart @@ -34,6 +34,8 @@ class Api { staking = ApiStaking(this); gov = ApiGovernance(this); + _msgHandlers['txStatusChange'] = store.account.setTxStatus; + _web = FlutterWebviewPlugin(); _web.onStateChanged.listen((viewState) async { diff --git a/lib/service/substrateApi/apiGov.dart b/lib/service/substrateApi/apiGov.dart index 490a1e4c..f4f68b03 100644 --- a/lib/service/substrateApi/apiGov.dart +++ b/lib/service/substrateApi/apiGov.dart @@ -42,19 +42,13 @@ class ApiGovernance { if (data != null) { List list = data['referendums']; if (list.length > 0) { - list.asMap().forEach((k, v) => v['detail'] = data['details'][k]); + list.asMap().forEach((k, v) { + v['detail'] = data['details'][k]; + v['votes'] = data['votes'][k]; + }); store.gov.setReferendums(List>.from(list)); - fetchReferendumVotes(List.from(list.map((i) => i['index']))); } } return data; } - - Future fetchReferendumVotes(List indexes) async { - String code = indexes.map((i) => 'gov.getReferendumVotes($i)').join(','); - List res = await apiRoot.evalJavascript('Promise.all([$code])'); - res.asMap().forEach((k, v) { - store.gov.setReferendumVotes(indexes[k], v as Map); - }); - } } diff --git a/lib/store/account.dart b/lib/store/account.dart index a6c66e06..4088f2e9 100644 --- a/lib/store/account.dart +++ b/lib/store/account.dart @@ -29,6 +29,9 @@ abstract class _AccountStore with Store { @observable bool loading = true; + @observable + String txStatus = ''; + @observable AccountCreate newAccount = AccountCreate(); @@ -68,6 +71,11 @@ abstract class _AccountStore with Store { return pubKeyAddressMap[currentAccount.pubKey] ?? currentAccount.address; } + @action + void setTxStatus(String status) { + txStatus = status; + } + @action void setNewAccount(String name, String password) { newAccount.name = name; diff --git a/lib/store/account.g.dart b/lib/store/account.g.dart index 49d47746..87e5df4a 100644 --- a/lib/store/account.g.dart +++ b/lib/store/account.g.dart @@ -66,6 +66,23 @@ mixin _$AccountStore on _AccountStore, Store { }, _$loadingAtom, name: '${_$loadingAtom.name}_set'); } + final _$txStatusAtom = Atom(name: '_AccountStore.txStatus'); + + @override + String get txStatus { + _$txStatusAtom.context.enforceReadPolicy(_$txStatusAtom); + _$txStatusAtom.reportObserved(); + return super.txStatus; + } + + @override + set txStatus(String value) { + _$txStatusAtom.context.conditionallyRunInAction(() { + super.txStatus = value; + _$txStatusAtom.reportChanged(); + }, _$txStatusAtom, name: '${_$txStatusAtom.name}_set'); + } + final _$newAccountAtom = Atom(name: '_AccountStore.newAccount'); @override @@ -283,6 +300,16 @@ mixin _$AccountStore on _AccountStore, Store { final _$_AccountStoreActionController = ActionController(name: '_AccountStore'); + @override + void setTxStatus(String status) { + final _$actionInfo = _$_AccountStoreActionController.startAction(); + try { + return super.setTxStatus(status); + } finally { + _$_AccountStoreActionController.endAction(_$actionInfo); + } + } + @override void setNewAccount(String name, String password) { final _$actionInfo = _$_AccountStoreActionController.startAction(); diff --git a/lib/store/governance.dart b/lib/store/governance.dart index 7c930762..6c0cdf6b 100644 --- a/lib/store/governance.dart +++ b/lib/store/governance.dart @@ -28,10 +28,6 @@ abstract class _GovernanceStore with Store { @observable ObservableList referendums; - @observable - ObservableMap referendumVotes = - ObservableMap(); - @observable ObservableList userReferendumVotes = ObservableList(); @@ -41,7 +37,12 @@ abstract class _GovernanceStore with Store { userReferendumVotes.forEach((i) { int id = i['detail']['params'][0]['value']; if (res[id] == null) { - res[id] = i['detail']['params'][1]['value']; + var value = i['detail']['params'][1]['value']; + if (value.runtimeType == int) { + res[id] = value; + } else { + res[id] = value['Standard']['vote']; + } } }); return res; @@ -69,15 +70,10 @@ abstract class _GovernanceStore with Store { ls.map((i) => ReferendumInfo.fromJson(i as Map))); } - @action - void setReferendumVotes(int index, Map votes) { - referendumVotes[index] = ReferendumVotes.fromJson(votes); - } - @action void setUserReferendumVotes(String address, List ls) { if (account.currentAddress != address) return; - + print(ls); userReferendumVotes.addAll(List.from(ls)); } @@ -129,30 +125,9 @@ abstract class _ReferendumInfo with Store { int index; String hash; - Map info; + Map status; Map proposal; Map preimage; Map detail; -} - -class ReferendumVotes extends _ReferendumVotes { - static ReferendumVotes fromJson(Map json) { - ReferendumVotes res = ReferendumVotes(); - res.voteCount = json['voteCount']; - res.voteCountAye = json['voteCountAye']; - res.voteCountNay = json['voteCountNay']; - res.votedAye = int.parse('0x${json['votedAye']}'); - res.votedNay = int.parse('0x${json['votedNay']}'); - res.votedTotal = int.parse('0x${json['votedTotal']}'); - return res; - } -} - -abstract class _ReferendumVotes { - int voteCount; - int voteCountAye; - int voteCountNay; - int votedAye; - int votedNay; - int votedTotal; + Map votes; } diff --git a/lib/store/governance.g.dart b/lib/store/governance.g.dart index e37e3245..90342a1f 100644 --- a/lib/store/governance.g.dart +++ b/lib/store/governance.g.dart @@ -39,20 +39,22 @@ ReferendumInfo _$ReferendumInfoFromJson(Map json) { return ReferendumInfo() ..index = json['index'] as int ..hash = json['hash'] as String - ..info = json['info'] as Map + ..status = json['status'] as Map ..proposal = json['proposal'] as Map ..preimage = json['preimage'] as Map - ..detail = json['detail'] as Map; + ..detail = json['detail'] as Map + ..votes = json['votes'] as Map; } Map _$ReferendumInfoToJson(ReferendumInfo instance) => { 'index': instance.index, 'hash': instance.hash, - 'info': instance.info, + 'status': instance.status, 'proposal': instance.proposal, 'preimage': instance.preimage, 'detail': instance.detail, + 'votes': instance.votes, }; // ************************************************************************** @@ -140,23 +142,6 @@ mixin _$GovernanceStore on _GovernanceStore, Store { }, _$referendumsAtom, name: '${_$referendumsAtom.name}_set'); } - final _$referendumVotesAtom = Atom(name: '_GovernanceStore.referendumVotes'); - - @override - ObservableMap get referendumVotes { - _$referendumVotesAtom.context.enforceReadPolicy(_$referendumVotesAtom); - _$referendumVotesAtom.reportObserved(); - return super.referendumVotes; - } - - @override - set referendumVotes(ObservableMap value) { - _$referendumVotesAtom.context.conditionallyRunInAction(() { - super.referendumVotes = value; - _$referendumVotesAtom.reportChanged(); - }, _$referendumVotesAtom, name: '${_$referendumVotesAtom.name}_set'); - } - final _$userReferendumVotesAtom = Atom(name: '_GovernanceStore.userReferendumVotes'); @@ -217,16 +202,6 @@ mixin _$GovernanceStore on _GovernanceStore, Store { } } - @override - void setReferendumVotes(int index, Map votes) { - final _$actionInfo = _$_GovernanceStoreActionController.startAction(); - try { - return super.setReferendumVotes(index, votes); - } finally { - _$_GovernanceStoreActionController.endAction(_$actionInfo); - } - } - @override void setUserReferendumVotes(String address, List ls) { final _$actionInfo = _$_GovernanceStoreActionController.startAction(); diff --git a/lib/utils/i18n/home.dart b/lib/utils/i18n/home.dart index 285f85c2..f2159a5b 100644 --- a/lib/utils/i18n/home.dart +++ b/lib/utils/i18n/home.dart @@ -19,6 +19,11 @@ const Map enHome = { 'submit.from': 'You are about to sign a transaction from ', 'submit.call': 'Calling ', 'unlock': 'Unlock Account with Password', + 'tx.queued': 'Queued', + 'tx.Ready': 'Ready', + 'tx.Broadcast': 'Broadcast', + 'tx.Inblock': 'Inblock', + 'tx.error': 'Error', 'edit': 'Edit', 'delete': 'Delete', 'detail': 'Detail', @@ -45,6 +50,11 @@ const Map zhHome = { 'submit.from': '你将使用以下账户发送交易:', 'submit.call': '调用 ', 'unlock': '使用密码解锁账户', + 'tx.queued': '已加入队列', + 'tx.Ready': '准备广播', + 'tx.Broadcast': '正在广播', + 'tx.Inblock': '已被打包', + 'tx.error': '发送失败', 'edit': '编辑', 'delete': '删除', 'detail': '详情', diff --git a/pubspec.yaml b/pubspec.yaml index dacfc945..43c035ee 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: PolkaWallet made with Flutter. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.6.1 +version: 0.6.2 environment: sdk: ">=2.1.0 <3.0.0"