Skip to content

Commit a97463f

Browse files
authored
Feature/make available to other networks (#20)
* added matic and bsc networks * WIP: idea how to manage multiple networks * introduced change network component * introduced service locator * changed to a websocket address that allows subscription * disposed transaction listener properly * extended network config and adjusted menu and balance componenets * last design tweaks * typo * updated EOL char * added git attributes and fixed EOL
1 parent e4c2237 commit a97463f

27 files changed

+468
-95
lines changed

.gitattributes

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Automatically normalize line endings for all text-based files
2+
# http://git-scm.com/docs/gitattributes#_end_of_line_conversion
3+
* text=auto
4+
5+
# For the following file types, normalize line endings to LF on
6+
# checkin and prevent conversion to CRLF when they are checked out
7+
# (this is required in order to prevent newline related issues like,
8+
# for example, after the build script is run)
9+
.* text eol=lf
10+
*.html text eol=lf
11+
*.css text eol=lf
12+
*.less text eol=lf
13+
*.styl text eol=lf
14+
*.scss text eol=lf
15+
*.sass text eol=lf
16+
*.sss text eol=lf
17+
*.js text eol=lf
18+
*.jsx text eol=lf
19+
*.tsx text eol=lf
20+
*.json text eol=lf
21+
*.md text eol=lf
22+
*.mjs text eol=lf
23+
*.sh text eol=lf
24+
*.svg text eol=lf
25+
*.txt text eol=lf
26+
*.xml text eol=lf
27+
.dart text eof=lf

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ Feel free to check out the smart contract used in this project [https://github.c
6060

6161
### Release notes
6262

63-
2.0.0+7:
63+
2.1.0+8:
64+
65+
- Flutter upgraded to version 2.2.3 (dart 2.13.4)
66+
- Multi network support (ETH Ropsten, MATIC Mumbai and BSC)
67+
68+
2.0.0+7:
6469

6570
- Flutter has been upgraded to version 2.0.6 (dart 2.12.3)
6671
- Handled null-safety
@@ -69,14 +74,13 @@ Feel free to check out the smart contract used in this project [https://github.c
6974
- Removed discontinued [firebase_ml_vision](https://pub.dev/packages/firebase_ml_vision) in favor of [qr_code_scanner](https://pub.dev/packages/qr_code_scanner)
7075
- Added menu option to reveal private key
7176

72-
73-
1.3.0+6:
77+
1.3.0+6:
7478

7579
- Flutter has been upgraded to version 2.0.1 (dart 2.12.0).
7680
- Libraries has been upgraded.
7781
- Fixed issue to generate and store private key when imported from seed phrase.
7882

79-
1.2.0+5:
83+
1.2.0+5:
8084

8185
- Flutter has been upgraded to version 1.22 (dart 2.10.5).
8286
- Libraries has been upgraded.

fonts/MyFlutterApp.ttf

548 Bytes
Binary file not shown.

fonts/config.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@
2929
"css": "key",
3030
"code": 61572,
3131
"src": "fontawesome5"
32+
},
33+
{
34+
"uid": "8edaefd94639c91605b18d3183eb5b12",
35+
"css": "coins",
36+
"code": 62750,
37+
"src": "fontawesome5"
38+
},
39+
{
40+
"uid": "dd6c6b221a1088ff8a9b9cd32d0b3dd5",
41+
"css": "check",
42+
"code": 59392,
43+
"src": "fontawesome"
3244
}
3345
]
3446
}

lib/app_config.dart

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,68 @@
1-
class AppConfig {
2-
AppConfig() {
3-
params['dev'] = AppConfigParams(
4-
'http://192.168.40.197:8545',
5-
'ws://192.168.40.197:8545',
6-
'0xD933a953f4786Eed5E58D234dFeadE15c96bAa8b');
7-
8-
params['ropsten'] = AppConfigParams(
9-
'https://ropsten.infura.io/v3/628074215a2449eb960b4fe9e95feb09',
10-
'wss://ropsten.infura.io/ws/v3/628074215a2449eb960b4fe9e95feb09',
11-
'0x5060b60cb8Bd1C94B7ADEF4134555CDa7B45c461');
12-
}
1+
import 'package:etherwallet/model/network_type.dart';
2+
import 'package:etherwallet/utils/wallet_icons.dart';
3+
import 'package:flutter/material.dart';
134

14-
Map<String, AppConfigParams> params = <String, AppConfigParams>{};
5+
// ignore: avoid_classes_with_only_static_members
6+
class AppConfig {
7+
static Map<NetworkType, AppConfigParams> networks =
8+
<NetworkType, AppConfigParams>{
9+
NetworkType.Local: AppConfigParams(
10+
'http://192.168.40.197:8545',
11+
'0xD933a953f4786Eed5E58D234dFeadE15c96bAa8b',
12+
web3RdpUrl: 'ws://192.168.40.197:8545',
13+
symbol: 'ETH',
14+
faucetUrl: 'about:blank',
15+
enabled: false,
16+
label: 'Local (Truffle)',
17+
),
18+
NetworkType.Ethereum: AppConfigParams(
19+
'https://ropsten.infura.io/v3/628074215a2449eb960b4fe9e95feb09',
20+
'0x5060b60cb8Bd1C94B7ADEF4134555CDa7B45c461',
21+
web3RdpUrl:
22+
'wss://ropsten.infura.io/ws/v3/628074215a2449eb960b4fe9e95feb09',
23+
symbol: 'ETH',
24+
faucetUrl: 'https://faucet.ropsten.be',
25+
enabled: true,
26+
icon: WalletIcons.ethereum,
27+
label: 'Ethereum (Ropsten)',
28+
),
29+
NetworkType.BSC: AppConfigParams(
30+
'https://data-seed-prebsc-1-s1.binance.org:8545',
31+
'0x73434bb95eC80d623359f6f9d7b84568407187BA',
32+
symbol: 'BNB',
33+
faucetUrl: 'https://testnet.binance.org/faucet-smart',
34+
enabled: true,
35+
label: 'Binance Chain (BSC)',
36+
),
37+
NetworkType.Matic: AppConfigParams(
38+
'https://rpc-mumbai.maticvigil.com',
39+
'0x73434bb95eC80d623359f6f9d7b84568407187BA',
40+
web3RdpUrl: 'wss://ws-mumbai.matic.today',
41+
symbol: 'MATIC',
42+
faucetUrl: 'https://faucet.matic.network',
43+
enabled: true,
44+
label: 'Matic (Mumbai)',
45+
)
46+
};
1547
}
1648

1749
class AppConfigParams {
18-
AppConfigParams(this.web3HttpUrl, this.web3RdpUrl, this.contractAddress);
19-
final String web3RdpUrl;
50+
AppConfigParams(
51+
this.web3HttpUrl,
52+
this.contractAddress, {
53+
required this.symbol,
54+
required this.faucetUrl,
55+
required this.enabled,
56+
required this.label,
57+
this.web3RdpUrl,
58+
this.icon = WalletIcons.coins,
59+
});
60+
final String? web3RdpUrl;
2061
final String web3HttpUrl;
2162
final String contractAddress;
63+
final String symbol;
64+
final String faucetUrl;
65+
final IconData icon;
66+
final bool enabled;
67+
final String label;
2268
}

lib/components/menu/main_menu.dart

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:etherwallet/model/network_type.dart';
12
import 'package:etherwallet/utils/wallet_icons.dart';
23
import 'package:flutter/material.dart';
34
import 'package:url_launcher/url_launcher.dart';
@@ -6,11 +7,13 @@ class MainMenu extends StatelessWidget {
67
const MainMenu({
78
Key? key,
89
required this.address,
10+
required this.network,
911
required this.onReset,
1012
required this.onRevealKey,
1113
}) : super(key: key);
1214

1315
final String? address;
16+
final NetworkType network;
1417
final GestureTapCallback? onReset;
1518
final GestureTapCallback? onRevealKey;
1619

@@ -24,7 +27,8 @@ class MainMenu extends StatelessWidget {
2427
subtitle: const Text('Claim some test tokens'),
2528
trailing: const Icon(WalletIcons.gem, color: Colors.blue),
2629
onTap: () async {
27-
var url = 'https://faucet.clempe.dev?address=$address';
30+
final url =
31+
'https://faucet.clempe.dev?address=$address&network=${network.name.toLowerCase()}';
2832
if (await canLaunch(url)) {
2933
await launch(url);
3034
} else {
@@ -33,14 +37,11 @@ class MainMenu extends StatelessWidget {
3337
},
3438
),
3539
ListTile(
36-
title: const Text('Get ETH'),
37-
subtitle: const Text('Claim some test ether'),
38-
trailing: const Icon(
39-
WalletIcons.ethereum,
40-
color: Colors.black,
41-
),
40+
title: Text('Get ${network.config.symbol}'),
41+
subtitle: Text('Claim some test ${network.config.symbol}'),
42+
trailing: Icon(network.config.icon, color: Colors.black),
4243
onTap: () async {
43-
const url = 'https://faucet.ropsten.be';
44+
final url = network.config.faucetUrl;
4445
if (await canLaunch(url)) {
4546
await launch(url);
4647
} else {

lib/components/wallet/balance.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,29 @@ class Balance extends StatelessWidget {
99
required this.address,
1010
required this.ethBalance,
1111
required this.tokenBalance,
12+
required this.symbol,
1213
}) : super(key: key);
1314

1415
final String? address;
1516
final BigInt? ethBalance;
1617
final BigInt? tokenBalance;
18+
final String? symbol;
1719

1820
@override
1921
Widget build(BuildContext context) {
22+
final mediaQuery = MediaQuery.of(context);
23+
2024
return Center(
2125
child: Column(
2226
mainAxisAlignment: MainAxisAlignment.center,
2327
children: <Widget>[
2428
Text(address ?? ''),
29+
const SizedBox(height: 10),
2530
CopyButton(
2631
text: const Text('Copy address'),
2732
value: address,
2833
),
29-
if (address != null)
34+
if (address != null && mediaQuery.orientation == Orientation.portrait)
3035
QrImage(
3136
data: address!,
3237
size: 150.0,
@@ -37,7 +42,7 @@ class Balance extends StatelessWidget {
3742
Theme.of(context).textTheme.bodyText2?.apply(fontSizeDelta: 6),
3843
),
3944
Text(
40-
'${EthAmountFormatter(ethBalance).format()} eth',
45+
'${EthAmountFormatter(ethBalance).format()} $symbol',
4146
style: Theme.of(context)
4247
.textTheme
4348
.bodyText2
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import 'package:etherwallet/model/network_type.dart';
2+
import 'package:etherwallet/utils/wallet_icons.dart';
3+
import 'package:flutter/cupertino.dart';
4+
import 'package:flutter/material.dart';
5+
6+
class ChangeNetwork extends StatelessWidget {
7+
const ChangeNetwork(
8+
{Key? key,
9+
required this.currentValue,
10+
required this.onChange,
11+
this.loading = false})
12+
: super(key: key);
13+
14+
final NetworkType currentValue;
15+
final bool loading;
16+
final Function(NetworkType network) onChange;
17+
18+
@override
19+
Widget build(BuildContext context) {
20+
final networks = NetworkType.enabledValues;
21+
const itemHeight = 48.0;
22+
23+
return ElevatedButton(
24+
child: Text(currentValue.config.label),
25+
onPressed: !loading
26+
? () {
27+
showModalBottomSheet<void>(
28+
context: context,
29+
builder: (BuildContext context) {
30+
return SizedBox(
31+
height: itemHeight * networks.length,
32+
child: Column(
33+
children: <Widget>[
34+
for (var network in networks)
35+
TextButton(
36+
style: TextButton.styleFrom(
37+
minimumSize:
38+
const Size(double.infinity, itemHeight),
39+
),
40+
onPressed: () {
41+
onChange(network);
42+
Navigator.pop(context);
43+
},
44+
child: Row(
45+
mainAxisAlignment: MainAxisAlignment.center,
46+
children: [
47+
Text(network.config.label),
48+
if (network == currentValue) ...[
49+
const SizedBox(width: 10),
50+
const Icon(
51+
WalletIcons.check,
52+
size: 15,
53+
)
54+
]
55+
]),
56+
),
57+
],
58+
),
59+
);
60+
},
61+
);
62+
}
63+
: null,
64+
);
65+
}
66+
}

lib/context/transfer/wallet_transfer_handler.dart

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,34 @@ import 'dart:async';
22
import 'dart:math';
33

44
import 'package:etherwallet/context/transfer/wallet_transfer_state.dart';
5+
import 'package:etherwallet/model/network_type.dart';
56
import 'package:etherwallet/model/wallet_transfer.dart';
67
import 'package:etherwallet/service/configuration_service.dart';
7-
import 'package:etherwallet/service/contract_service.dart';
8+
import 'package:etherwallet/service/contract_locator.dart';
89
import 'package:flutter_hooks/flutter_hooks.dart';
910
import 'package:web3dart/credentials.dart';
1011

1112
class WalletTransferHandler {
1213
WalletTransferHandler(
1314
this._store,
14-
this._contractService,
15+
this._contractLocator,
1516
this._configurationService,
1617
);
1718

1819
final Store<WalletTransfer, WalletTransferAction> _store;
19-
final ContractService _contractService;
20+
final ContractLocator _contractLocator;
2021
final ConfigurationService _configurationService;
2122

2223
WalletTransfer get state => _store.state;
2324

24-
Future<bool> transfer(String to, String amount) async {
25+
Future<bool> transfer(NetworkType network, String to, String amount) async {
2526
final completer = Completer<bool>();
2627
final privateKey = _configurationService.getPrivateKey();
2728

2829
_store.dispatch(WalletTransferStarted());
2930

3031
try {
31-
await _contractService.send(
32+
await _contractLocator.getInstance(network).send(
3233
privateKey!,
3334
EthereumAddress.fromHex(to),
3435
BigInt.from(double.parse(amount) * pow(10, 18)),

lib/context/transfer/wallet_transfer_provider.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import 'package:etherwallet/context/transfer/wallet_transfer_handler.dart';
22
import 'package:etherwallet/context/transfer/wallet_transfer_state.dart';
33
import 'package:etherwallet/model/wallet_transfer.dart';
44
import 'package:etherwallet/service/configuration_service.dart';
5-
import 'package:etherwallet/service/contract_service.dart';
5+
import 'package:etherwallet/service/contract_locator.dart';
66
import 'package:flutter/widgets.dart';
77
import 'package:flutter_hooks/flutter_hooks.dart';
88

@@ -23,7 +23,7 @@ class WalletTransferProvider
2323
final store = useReducer<WalletTransfer, WalletTransferAction>(reducer,
2424
initialState: WalletTransfer(), initialAction: WalletTransferInit());
2525

26-
final contractService = Provider.of<ContractService>(context);
26+
final contractService = Provider.of<ContractLocator>(context);
2727
final configurationService = Provider.of<ConfigurationService>(context);
2828
final handler = useMemoized(
2929
() => WalletTransferHandler(store, contractService, configurationService),

0 commit comments

Comments
 (0)