mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-25 04:59:33 +00:00
Implement open wallet functionality
This commit is contained in:
parent
73680a96e2
commit
e1639cdc34
3 changed files with 78 additions and 27 deletions
|
@ -4,7 +4,7 @@ import 'package:cw_core/balance.dart';
|
|||
import 'package:web3dart/web3dart.dart';
|
||||
|
||||
class EthereumBalance extends Balance {
|
||||
EthereumBalance(super.available, super.additional);
|
||||
EthereumBalance({required int available, required int additional}) : super(available, additional);
|
||||
|
||||
@override
|
||||
String get formattedAdditionalBalance {
|
||||
|
@ -18,4 +18,17 @@ class EthereumBalance extends Balance {
|
|||
EtherAmount.fromUnitAndValue(EtherUnit.ether, available.toString()).getInEther.toString();
|
||||
|
||||
String toJSON() => json.encode({'available': available, 'additional': additional});
|
||||
|
||||
static EthereumBalance? fromJSON(String? jsonSource) {
|
||||
if (jsonSource == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final decoded = json.decode(jsonSource) as Map;
|
||||
|
||||
return EthereumBalance(
|
||||
available: decoded['available'] as int? ?? 0,
|
||||
additional: decoded['additional'] as int? ?? 0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@ import 'package:cw_ethereum/ethereum_wallet_addresses.dart';
|
|||
import 'package:cw_ethereum/file.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:web3dart/web3dart.dart';
|
||||
import 'package:ed25519_hd_key/ed25519_hd_key.dart';
|
||||
import 'package:bip39/bip39.dart' as bip39;
|
||||
import 'package:hex/hex.dart';
|
||||
|
||||
part 'ethereum_wallet.g.dart';
|
||||
|
||||
|
@ -28,25 +31,24 @@ abstract class EthereumWalletBase
|
|||
with Store {
|
||||
EthereumWalletBase({
|
||||
required WalletInfo walletInfo,
|
||||
required this.mnemonic,
|
||||
required this.privateKey,
|
||||
required String mnemonic,
|
||||
required String password,
|
||||
EthereumBalance? initialBalance,
|
||||
}) : syncStatus = NotConnectedSyncStatus(),
|
||||
_password = password,
|
||||
_mnemonic = mnemonic,
|
||||
walletAddresses = EthereumWalletAddresses(walletInfo),
|
||||
balance = ObservableMap<CryptoCurrency, EthereumBalance>.of(
|
||||
{CryptoCurrency.eth: initialBalance ?? EthereumBalance(0, 0)}),
|
||||
{CryptoCurrency.eth: initialBalance ?? EthereumBalance(available: 0, additional: 0)}),
|
||||
super(walletInfo) {
|
||||
this.walletInfo = walletInfo;
|
||||
transactionHistory = EthereumTransactionHistory();
|
||||
walletAddresses.address = EthPrivateKey.fromHex(privateKey).address.toString();
|
||||
}
|
||||
|
||||
final String mnemonic;
|
||||
final String privateKey;
|
||||
final String _mnemonic;
|
||||
final String _password;
|
||||
|
||||
late final String privateKey;
|
||||
|
||||
late EthereumClient _client;
|
||||
|
||||
EtherAmount? _gasPrice;
|
||||
|
@ -61,6 +63,12 @@ abstract class EthereumWalletBase
|
|||
@observable
|
||||
late ObservableMap<CryptoCurrency, EthereumBalance> balance;
|
||||
|
||||
Future<void> init() async {
|
||||
privateKey = await getPrivateKey(_mnemonic, _password);
|
||||
transactionHistory = EthereumTransactionHistory();
|
||||
walletAddresses.address = EthPrivateKey.fromHex(privateKey).address.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
||||
throw UnimplementedError("calculateEstimatedFee");
|
||||
|
@ -119,7 +127,7 @@ abstract class EthereumWalletBase
|
|||
}
|
||||
|
||||
@override
|
||||
String get seed => mnemonic;
|
||||
String get seed => _mnemonic;
|
||||
|
||||
@override
|
||||
Future<void> startSync() async {
|
||||
|
@ -150,11 +158,31 @@ abstract class EthereumWalletBase
|
|||
Future<String> makePath() async => pathForWallet(name: walletInfo.name, type: walletInfo.type);
|
||||
|
||||
String toJSON() => json.encode({
|
||||
'mnemonic': mnemonic,
|
||||
'mnemonic': _mnemonic,
|
||||
'balance': balance[currency]!.toJSON(),
|
||||
// TODO: save other attributes
|
||||
});
|
||||
|
||||
static Future<EthereumWallet> open({
|
||||
required String name,
|
||||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
}) async {
|
||||
final path = await pathForWallet(name: name, type: walletInfo.type);
|
||||
final jsonSource = await read(path: path, password: password);
|
||||
final data = json.decode(jsonSource) as Map;
|
||||
final mnemonic = data['mnemonic'] as String;
|
||||
final balance = EthereumBalance.fromJSON(data['balance'] as String) ??
|
||||
EthereumBalance(available: 0, additional: 0);
|
||||
|
||||
return EthereumWallet(
|
||||
walletInfo: walletInfo,
|
||||
password: password,
|
||||
mnemonic: mnemonic,
|
||||
initialBalance: balance,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _updateBalance() async {
|
||||
balance[currency] = await _fetchBalances();
|
||||
await save();
|
||||
|
@ -163,6 +191,17 @@ abstract class EthereumWalletBase
|
|||
Future<EthereumBalance> _fetchBalances() async {
|
||||
final balance = await _client.getBalance(privateKey);
|
||||
|
||||
return EthereumBalance(balance.getInEther.toInt(), balance.getInEther.toInt());
|
||||
return EthereumBalance(
|
||||
available: balance.getInEther.toInt(),
|
||||
additional: balance.getInEther.toInt(),
|
||||
);
|
||||
}
|
||||
|
||||
Future<String> getPrivateKey(String mnemonic, String password) async {
|
||||
final seed = bip39.mnemonicToSeedHex(mnemonic);
|
||||
final master = await ED25519_HD_KEY.getMasterKeyFromSeed(HEX.decode(seed),
|
||||
masterSecret: password);
|
||||
final privateKey = HEX.encode(master.key);
|
||||
return privateKey;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,10 +10,8 @@ import 'package:cw_core/wallet_service.dart';
|
|||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_ethereum/ethereum_wallet.dart';
|
||||
import 'package:cw_ethereum/ethereum_wallet_creation_credentials.dart';
|
||||
import 'package:ed25519_hd_key/ed25519_hd_key.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:bip39/bip39.dart' as bip39;
|
||||
import 'package:hex/hex.dart';
|
||||
|
||||
class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
||||
EthereumRestoreWalletFromSeedCredentials, EthereumRestoreWalletFromWIFCredentials> {
|
||||
|
@ -24,13 +22,13 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
|||
@override
|
||||
Future<EthereumWallet> create(EthereumNewWalletCredentials credentials) async {
|
||||
final mnemonic = bip39.generateMnemonic();
|
||||
final privateKey = await getPrivateKey(mnemonic, credentials.password!);
|
||||
final wallet = EthereumWallet(
|
||||
walletInfo: credentials.walletInfo!,
|
||||
mnemonic: mnemonic,
|
||||
privateKey: privateKey,
|
||||
password: credentials.password!,
|
||||
);
|
||||
|
||||
await wallet.init();
|
||||
await wallet.save();
|
||||
|
||||
return wallet;
|
||||
|
@ -44,10 +42,19 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
|||
File(await pathForWallet(name: name, type: getType())).existsSync();
|
||||
|
||||
@override
|
||||
Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>> openWallet(
|
||||
String name, String password) {
|
||||
// TODO: implement openWallet
|
||||
throw UnimplementedError();
|
||||
Future<EthereumWallet> openWallet(String name, String password) async {
|
||||
final walletInfo =
|
||||
walletInfoSource.values.firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
|
||||
final wallet = await EthereumWalletBase.open(
|
||||
name: name,
|
||||
password: password,
|
||||
walletInfo: walletInfo,
|
||||
);
|
||||
|
||||
await wallet.init();
|
||||
await wallet.save();
|
||||
|
||||
return wallet;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -66,12 +73,4 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
|||
// TODO: implement restoreFromSeed
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
Future<String> getPrivateKey(String mnemonic, String password) async {
|
||||
final seed = bip39.mnemonicToSeedHex(mnemonic);
|
||||
final master = await ED25519_HD_KEY.getMasterKeyFromSeed(HEX.decode(seed),
|
||||
masterSecret: password);
|
||||
final privateKey = HEX.encode(master.key);
|
||||
return privateKey;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue