Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
RomeroYang committed Aug 10, 2021
2 parents 7566360 + a62407c commit d4829c0
Show file tree
Hide file tree
Showing 18 changed files with 216 additions and 46 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 2.2.1-beta
- update uos flow.
- add apk download notes.

# 2.1.6-2.2.0-beta
- add tokens market prices.
- update Karura plugin.

# 2.1.5-beta
- Add address format limit for transfer.
- update Karura plugin.
Expand Down
6 changes: 3 additions & 3 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
MARKETING_VERSION = 2.1.5;
MARKETING_VERSION = 2.2.1;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.polkawallet.polkawallet;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -527,7 +527,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
MARKETING_VERSION = 2.1.5;
MARKETING_VERSION = 2.2.1;
PRODUCT_BUNDLE_IDENTIFIER = io.polkawallet.polkawallet;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -564,7 +564,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
MARKETING_VERSION = 2.1.5;
MARKETING_VERSION = 2.2.1;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.polkawallet.polkawallet;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
2 changes: 1 addition & 1 deletion lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ class _WalletAppState extends State<WalletApp> {
Future<void> _startPlugin(AppService service) async {
// _initWalletConnect();

_service.assets.fetchMarketPrice();
_service.assets.fetchMarketPriceFromSubScan();

setState(() {
_connectedNode = null;
Expand Down
6 changes: 3 additions & 3 deletions lib/common/consts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const local_tx_store_key = 'local_tx_store';

/// app versions
enum BuildTargets { apk, playStore, dev }
const String app_beta_version = 'v2.1.5-beta.1';
const int app_beta_version_code = 2151;
const String app_beta_version = 'v2.2.1-beta.1';
const int app_beta_version_code = 2211;
const plugin_github_links = {
'kusama': 'https://github.com/polkawallet-io/app/issues',
'polkadot': 'https://github.com/polkawallet-io/app/issues',
Expand All @@ -28,7 +28,7 @@ const plugin_github_links = {
'karura': 'https://github.com/AcalaNetwork/polkawallet_plugin_acala/issues',
'laminar-tc3':
'https://github.com/polkawallet-io/polkawallet_plugin_laminar/issues',
'chainx': 'https://github.com/true-eye/polkawallet_plugin_chainx/issues',
'chainx': 'https://github.com/chainx-org/polkawallet_plugin_chainx/issues',
'edgeware': 'https://github.com/remzrn/polkawallet_plugin_edgeware/issues',
};
const plugin_from_community = ['chainx', 'edgeware'];
Expand Down
2 changes: 1 addition & 1 deletion lib/pages/assets/asset/assetPage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class _AssetPageState extends State<AssetPage> {
_isLastPage = false;
});

widget.service.assets.fetchMarketPrice();
widget.service.assets.fetchMarketPriceFromSubScan();

await _updateData();
}
Expand Down
142 changes: 122 additions & 20 deletions lib/pages/assets/index.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import 'package:polkawallet_plugin_acala/common/constants/base.dart';
import 'package:polkawallet_sdk/api/types/networkParams.dart';
import 'package:polkawallet_sdk/plugin/index.dart';
import 'package:polkawallet_sdk/plugin/store/balances.dart';
import 'package:polkawallet_sdk/storage/types/keyPairData.dart';
import 'package:polkawallet_sdk/utils/i18n.dart';
import 'package:polkawallet_ui/components/addressIcon.dart';
import 'package:polkawallet_ui/components/borderedTitle.dart';
Expand Down Expand Up @@ -59,17 +60,16 @@ class _AssetsState extends State<AssetsPage> {

List _announcements;

Timer _priceUpdateTimer;

Future<void> _updateBalances() async {
setState(() {
_refreshing = true;
});
final balances = await widget.service.plugin.sdk.api.account
.queryBalance(widget.service.keyring.current.address);
await widget.service.assets.updateBalances();
setState(() {
_refreshing = false;
});
widget.service.plugin
.updateBalances(widget.service.keyring.current, balances);
}

Future<List> _fetchAnnouncements() async {
Expand All @@ -82,6 +82,15 @@ class _AssetsState extends State<AssetsPage> {
return res;
}

Future<void> _updateMarketPrices() async {
if (widget.service.plugin.balances.tokens.length > 0) {
widget.service.assets.fetchMarketPrices(
widget.service.plugin.balances.tokens.map((e) => e.symbol).toList());
}

_priceUpdateTimer = Timer(Duration(seconds: 30), _updateMarketPrices);
}

Future<void> _handleScan(bool transferEnabled) async {
final dic = I18n.of(context).getDic(i18n_full_dic_app, 'account');
final data = (await Navigator.pushNamed(
Expand Down Expand Up @@ -125,19 +134,67 @@ class _AssetsState extends State<AssetsPage> {
}

String errorMsg;
KeyPairData sender;
try {
final senderPubKey = await widget.service.plugin.sdk.api.uos
.parseQrCode(
widget.service.keyring, data.rawData.toString().trim());
if (senderPubKey == widget.service.keyring.current.pubKey) {
final password = await widget.service.account
.getPassword(context, widget.service.keyring.current);
print('pass ok: $password');
_signAsync(password);
if (password != null) {
print('pass ok: $password');
_signAsync(password);
}
return;
} else {
if (senderPubKey != null) {
errorMsg = dic['uos.qr.mismatch'];
final senderAccIndex = widget.service.keyring.optionals
.indexWhere((e) => e.pubKey == senderPubKey);
if (senderAccIndex >= 0) {
sender = widget.service.keyring.optionals[senderAccIndex];
errorMsg = dic['uos.acc.mismatch.switch'] +
' ${Fmt.address(sender.address)} ?';
final needSwitch = await showCupertinoDialog(
context: context,
builder: (_) {
return CupertinoAlertDialog(
title: Text(dic['uos.title']),
content: Text(errorMsg),
actions: <Widget>[
CupertinoButton(
child: Text(I18n.of(context)
.getDic(i18n_full_dic_ui, 'common')['cancel']),
onPressed: () => Navigator.of(context).pop(false),
),
CupertinoButton(
child: Text(I18n.of(context)
.getDic(i18n_full_dic_ui, 'common')['ok']),
onPressed: () {
Navigator.of(context).pop(true);
},
),
],
);
},
);
if (needSwitch) {
widget.service.keyring.setCurrent(sender);
widget.service.plugin.changeAccount(sender);
widget.service.store.assets
.loadCache(sender, widget.service.plugin.basic.name);

final password = await widget.service.account
.getPassword(context, widget.service.keyring.current);
if (password != null) {
print('pass ok: $password');
_signAsync(password);
}
}
return;
} else {
errorMsg = dic['uos.acc.mismatch'];
}
} else {
errorMsg = dic['uos.qr.invalid'];
}
Expand Down Expand Up @@ -167,10 +224,21 @@ class _AssetsState extends State<AssetsPage> {
Future<void> _signAsync(String password) async {
final dic = I18n.of(context).getDic(i18n_full_dic_app, 'account');
try {
showCupertinoDialog(
context: context,
builder: (_) {
return CupertinoAlertDialog(
title: Text(dic['uos.title']),
content: Text(dic['uos.signing']),
);
},
);

final signed = await widget.service.plugin.sdk.api.uos
.signAsync(widget.service.plugin.basic.name, password);
print('signed: $signed');
Navigator.of(context).pushNamed(

Navigator.of(context).popAndPushNamed(
QrSignerPage.route,
arguments: signed.substring(2),
);
Expand Down Expand Up @@ -273,6 +341,15 @@ class _AssetsState extends State<AssetsPage> {
}
}

@override
void initState() {
super.initState();

WidgetsBinding.instance.addPostFrameCallback((_) {
_updateMarketPrices();
});
}

@override
Widget build(BuildContext context) {
return Observer(
Expand Down Expand Up @@ -338,10 +415,13 @@ class _AssetsState extends State<AssetsPage> {
),
onPressed: widget.service.keyring.allAccounts.length > 0
? () async {
final selected = await Navigator.of(context)
.pushNamed(NetworkSelectPage.route);
final selected = (await Navigator.of(context)
.pushNamed(NetworkSelectPage.route))
as PolkawalletPlugin;
setState(() {});
if (selected != null) {
if (selected != null &&
selected.basic.name !=
widget.service.plugin.basic.name) {
widget.checkJSCodeUpdate(selected);
}
}
Expand Down Expand Up @@ -469,9 +549,10 @@ class _AssetsState extends State<AssetsPage> {
: Colors.black26),
),
Text(
'≈ \$ ${tokenPrice ?? '--.--'}',
'≈ \$${tokenPrice ?? '--.--'}',
style: TextStyle(
color: Theme.of(context).disabledColor,
fontSize: 12,
),
),
],
Expand All @@ -492,6 +573,8 @@ class _AssetsState extends State<AssetsPage> {
i.decimals,
isFromCache: isTokensFromCache,
detailPageRoute: i.detailPageRoute,
marketPrice: widget.service.store.assets
.marketPrices[i.symbol],
icon: TokenIcon(i.symbol,
widget.service.plugin.tokenIcons),
))
Expand Down Expand Up @@ -553,9 +636,13 @@ class _AssetsState extends State<AssetsPage> {

class TokenItem extends StatelessWidget {
TokenItem(this.item, this.decimals,
{this.detailPageRoute, this.icon, this.isFromCache = false});
{this.marketPrice,
this.detailPageRoute,
this.icon,
this.isFromCache = false});
final TokenBalanceData item;
final int decimals;
final double marketPrice;
final String detailPageRoute;
final Widget icon;
final bool isFromCache;
Expand All @@ -575,13 +662,28 @@ class TokenItem extends StatelessWidget {
),
),
title: Text(item.name),
trailing: Text(
Fmt.priceFloorBigInt(Fmt.balanceInt(item.amount), decimals,
lengthFixed: 4),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: isFromCache ? Colors.black26 : Colors.black54),
trailing: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
Fmt.priceFloorBigInt(Fmt.balanceInt(item.amount), decimals,
lengthFixed: 4),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: isFromCache ? Colors.black26 : Colors.black54),
),
marketPrice != null
? Text(
'≈ \$${Fmt.priceFloor(Fmt.balanceDouble(item.amount, decimals) * marketPrice)}',
style: TextStyle(
color: Theme.of(context).disabledColor,
fontSize: 12,
),
)
: Container(height: 0, width: 8),
],
),
onTap: detailPageRoute == null
? null
Expand Down
31 changes: 27 additions & 4 deletions lib/service/apiAssets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,39 @@ class ApiAssets {
return res;
}

Future<void> fetchMarketPrice() async {
Future<void> fetchMarketPriceFromSubScan() async {
if (apiRoot.plugin.basic.isTestNet) return;

final res = await WalletApi.getTokenPrice(apiRoot.plugin.basic.name);
final res =
await WalletApi.getTokenPriceFromSubScan(apiRoot.plugin.basic.name);
if (res == null || res['data'] == null) {
print('fetch market price failed');
return;
}
final symbol = res['data']['token'][0];
apiRoot.store.assets
.setMarketPrices(symbol, res['data']['detail'][symbol]['price']);
apiRoot.store.assets.setMarketPrices(
{symbol: double.parse(res['data']['detail'][symbol]['price'])});
}

Future<void> fetchMarketPrices(List<String> tokens) async {
final List res = await Future.wait(
tokens.map((e) => WalletApi.getTokenPrice(e)).toList());

final Map<String, double> prices = {
'KUSD': 1.0,
'AUSD': 1.0,
};
res.forEach((e) {
if (e != null && e['price'] != null) {
prices[e['token']] = double.parse(e['price']);
}
});
apiRoot.store.assets.setMarketPrices(prices);
}

Future<void> updateBalances() async {
final balances = await apiRoot.plugin.sdk.api.account
.queryBalance(apiRoot.keyring.current.address);
apiRoot.plugin.updateBalances(apiRoot.keyring.current, balances);
}
}
17 changes: 16 additions & 1 deletion lib/service/walletApi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class WalletApi {
}
}

static Future<Map> getTokenPrice(String network) async {
static Future<Map> getTokenPriceFromSubScan(String network) async {
final url = 'https://${network.toLowerCase()}.subscan.io/api/scan/token';
try {
Response res = await get(Uri.parse(url));
Expand All @@ -125,6 +125,21 @@ class WalletApi {
}
}

static Future<Map> getTokenPrice(String token) async {
final url = '$_endpoint/price/price/latest?token=$token';
try {
Response res = await get(Uri.parse(url));
if (res == null) {
return null;
} else {
return jsonDecode(utf8.decode(res.bodyBytes));
}
} catch (err) {
print(err);
return null;
}
}

static Future<Map> getKarCrowdLoanStarted() async {
try {
final res = await get(Uri.parse('$_endpoint/crowdloan/health'));
Expand Down
Loading

0 comments on commit d4829c0

Please sign in to comment.