mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-03-12 09:32:33 +00:00
Add Balances for ERC20 tokens
This commit is contained in:
parent
d3f0c7fb85
commit
0dae347190
5 changed files with 84 additions and 25 deletions
|
@ -152,6 +152,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
|
|||
static const uni = CryptoCurrency(title: 'UNI', tag: 'ETH', fullName: 'Uniswap', raw: 60, name: 'uni', iconPath: 'assets/images/uni_icon.png');
|
||||
static const stx = CryptoCurrency(title: 'STX', fullName: 'Stacks', raw: 61, name: 'stx', iconPath: 'assets/images/stx_icon.png');
|
||||
static const btcln = CryptoCurrency(title: 'BTC', tag: 'LN', fullName: 'Bitcoin Lightning Network', raw: 62, name: 'btcln', iconPath: 'assets/images/btc.png');
|
||||
static const shib = CryptoCurrency(title: 'SHIB', tag: 'ETH', fullName: 'SHIBA INU', raw: 63, name: 'shib', iconPath: 'assets/images/shib.png'); // TODO: add image
|
||||
|
||||
|
||||
static final Map<int, CryptoCurrency> _rawCurrencyMap =
|
||||
|
|
|
@ -2,30 +2,33 @@ import 'dart:convert';
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:cw_core/balance.dart';
|
||||
import 'package:web3dart/web3dart.dart';
|
||||
|
||||
class EthereumBalance extends Balance {
|
||||
EthereumBalance(this.balance)
|
||||
: super(balance.getValueInUnit(EtherUnit.wei).toInt(),
|
||||
balance.getValueInUnit(EtherUnit.wei).toInt());
|
||||
class ERC20Balance extends Balance {
|
||||
ERC20Balance(this.balance, {this.exponent = 18})
|
||||
: super(balance.toInt(),
|
||||
balance.toInt());
|
||||
|
||||
final EtherAmount balance;
|
||||
final BigInt balance;
|
||||
final int exponent;
|
||||
|
||||
@override
|
||||
String get formattedAdditionalBalance {
|
||||
final String formattedBalance = balance.getValueInUnit(EtherUnit.ether).toString();
|
||||
final String formattedBalance = (balance / BigInt.from(10).pow(exponent)).toString();
|
||||
return formattedBalance.substring(0, min(12, formattedBalance.length));
|
||||
}
|
||||
|
||||
@override
|
||||
String get formattedAvailableBalance {
|
||||
final String formattedBalance = balance.getValueInUnit(EtherUnit.ether).toString();
|
||||
final String formattedBalance = (balance / BigInt.from(10).pow(exponent)).toString();
|
||||
return formattedBalance.substring(0, min(12, formattedBalance.length));
|
||||
}
|
||||
|
||||
String toJSON() => json.encode({'balanceInWei': balance.getInWei.toString()});
|
||||
String toJSON() => json.encode({
|
||||
'balanceInWei': balance.toString(),
|
||||
'exponent': exponent,
|
||||
});
|
||||
|
||||
static EthereumBalance? fromJSON(String? jsonSource) {
|
||||
static ERC20Balance? fromJSON(String? jsonSource) {
|
||||
if (jsonSource == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -33,9 +36,12 @@ class EthereumBalance extends Balance {
|
|||
final decoded = json.decode(jsonSource) as Map;
|
||||
|
||||
try {
|
||||
return EthereumBalance(EtherAmount.inWei(BigInt.parse(decoded['balanceInWei'])));
|
||||
return ERC20Balance(
|
||||
BigInt.parse(decoded['balanceInWei']),
|
||||
exponent: decoded['exponent'],
|
||||
);
|
||||
} catch (e) {
|
||||
return EthereumBalance(EtherAmount.zero());
|
||||
return ERC20Balance(BigInt.zero);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:typed_data';
|
||||
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_ethereum/ethereum_balance.dart';
|
||||
import 'package:cw_ethereum/pending_ethereum_transaction.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:web3dart/web3dart.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
|
@ -32,9 +33,9 @@ class EthereumClient {
|
|||
// [53000, 53000, 53000]
|
||||
final result = await Future.wait(EthereumTransactionPriority.all.map(
|
||||
(priority) => _client!.estimateGas(
|
||||
maxPriorityFeePerGas: EtherAmount.fromUnitAndValue(EtherUnit.gwei, priority.tip),
|
||||
maxFeePerGas: EtherAmount.fromUnitAndValue(EtherUnit.gwei, priority.tip),
|
||||
),
|
||||
// maxPriorityFeePerGas: EtherAmount.fromUnitAndValue(EtherUnit.gwei, priority.tip),
|
||||
// maxFeePerGas: EtherAmount.fromUnitAndValue(EtherUnit.gwei, priority.tip),
|
||||
),
|
||||
));
|
||||
|
||||
return result.map((e) => e.toInt()).toList();
|
||||
|
@ -133,4 +134,53 @@ I/flutter ( 4474): Gas Used: 53000
|
|||
// },
|
||||
// ));
|
||||
// }
|
||||
|
||||
Future<Map<CryptoCurrency, ERC20Balance>> fetchERC20Balances(EthereumAddress userAddress) async {
|
||||
final String abi = await rootBundle.loadString("assets/abi_json/erc20_abi.json");
|
||||
final contractAbi = ContractAbi.fromJson(abi, "ERC20");
|
||||
|
||||
final Map<CryptoCurrency, ERC20Balance> erc20Balances = {};
|
||||
|
||||
for (var currency in _erc20Currencies.keys) {
|
||||
final contractAddress = _erc20Currencies[currency]!;
|
||||
|
||||
try {
|
||||
final contract = DeployedContract(
|
||||
contractAbi,
|
||||
EthereumAddress.fromHex(contractAddress),
|
||||
);
|
||||
|
||||
final balanceFunction = contract.function('balanceOf');
|
||||
final balance = await _client!.call(
|
||||
contract: contract,
|
||||
function: balanceFunction,
|
||||
params: [userAddress],
|
||||
);
|
||||
|
||||
final decimalsFunction = contract.function('decimals');
|
||||
final decimals = await _client!.call(
|
||||
contract: contract,
|
||||
function: decimalsFunction,
|
||||
params: [],
|
||||
);
|
||||
|
||||
BigInt tokenBalance = BigInt.parse(balance.first.toString());
|
||||
int exponent = int.parse(decimals.first.toString());
|
||||
|
||||
erc20Balances[currency] = ERC20Balance(tokenBalance, exponent: exponent);
|
||||
} catch (e, s) {
|
||||
print(e);
|
||||
print(s);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return erc20Balances;
|
||||
}
|
||||
}
|
||||
|
||||
Map<CryptoCurrency, String> _erc20Currencies = {
|
||||
CryptoCurrency.usdc: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
|
||||
CryptoCurrency.usdterc20: "0xdac17f958d2ee523a2206206994597c13d831ec7",
|
||||
CryptoCurrency.shib: "0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE",
|
||||
};
|
||||
|
|
|
@ -30,21 +30,21 @@ part 'ethereum_wallet.g.dart';
|
|||
class EthereumWallet = EthereumWalletBase with _$EthereumWallet;
|
||||
|
||||
abstract class EthereumWalletBase
|
||||
extends WalletBase<EthereumBalance, EthereumTransactionHistory, EthereumTransactionInfo>
|
||||
extends WalletBase<ERC20Balance, EthereumTransactionHistory, EthereumTransactionInfo>
|
||||
with Store {
|
||||
EthereumWalletBase({
|
||||
required WalletInfo walletInfo,
|
||||
required String mnemonic,
|
||||
required String password,
|
||||
EthereumBalance? initialBalance,
|
||||
ERC20Balance? initialBalance,
|
||||
}) : syncStatus = NotConnectedSyncStatus(),
|
||||
_password = password,
|
||||
_mnemonic = mnemonic,
|
||||
_priorityFees = [],
|
||||
_client = EthereumClient(),
|
||||
walletAddresses = EthereumWalletAddresses(walletInfo),
|
||||
balance = ObservableMap<CryptoCurrency, EthereumBalance>.of(
|
||||
{CryptoCurrency.eth: initialBalance ?? EthereumBalance(EtherAmount.zero())}),
|
||||
balance = ObservableMap<CryptoCurrency, ERC20Balance>.of(
|
||||
{CryptoCurrency.eth: initialBalance ?? ERC20Balance(BigInt.zero)}),
|
||||
super(walletInfo) {
|
||||
this.walletInfo = walletInfo;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ abstract class EthereumWalletBase
|
|||
|
||||
@override
|
||||
@observable
|
||||
late ObservableMap<CryptoCurrency, EthereumBalance> balance;
|
||||
late ObservableMap<CryptoCurrency, ERC20Balance> balance;
|
||||
|
||||
Future<void> init() async {
|
||||
await walletAddresses.init();
|
||||
|
@ -234,7 +234,7 @@ abstract class EthereumWalletBase
|
|||
final data = json.decode(jsonSource) as Map;
|
||||
final mnemonic = data['mnemonic'] as String;
|
||||
final balance =
|
||||
EthereumBalance.fromJSON(data['balance'] as String) ?? EthereumBalance(EtherAmount.zero());
|
||||
ERC20Balance.fromJSON(data['balance'] as String) ?? ERC20Balance(BigInt.zero);
|
||||
|
||||
return EthereumWallet(
|
||||
walletInfo: walletInfo,
|
||||
|
@ -246,12 +246,13 @@ abstract class EthereumWalletBase
|
|||
|
||||
Future<void> _updateBalance() async {
|
||||
balance[currency] = await _fetchBalances();
|
||||
balance.addAll(await _client.fetchERC20Balances(_privateKey.address));
|
||||
await save();
|
||||
}
|
||||
|
||||
Future<EthereumBalance> _fetchBalances() async {
|
||||
Future<ERC20Balance> _fetchBalances() async {
|
||||
final balance = await _client.getBalance(_privateKey.address);
|
||||
return EthereumBalance(balance);
|
||||
return ERC20Balance(balance.getInWei);
|
||||
}
|
||||
|
||||
Future<EthPrivateKey> getPrivateKey(String mnemonic, String password) async {
|
||||
|
|
|
@ -112,6 +112,7 @@ flutter:
|
|||
- assets/text/
|
||||
- assets/faq/
|
||||
- assets/animation/
|
||||
- assets/abi_json/
|
||||
|
||||
fonts:
|
||||
- family: Lato
|
||||
|
|
Loading…
Reference in a new issue