mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-25 04:59:33 +00:00
Fix Private key for Ethereum wallets
This commit is contained in:
parent
db90dde952
commit
b02b653ceb
6 changed files with 52 additions and 58 deletions
|
@ -4,20 +4,19 @@ import 'package:cw_core/balance.dart';
|
||||||
import 'package:web3dart/web3dart.dart';
|
import 'package:web3dart/web3dart.dart';
|
||||||
|
|
||||||
class EthereumBalance extends Balance {
|
class EthereumBalance extends Balance {
|
||||||
EthereumBalance({required int available, required int additional}) : super(available, additional);
|
EthereumBalance(this.balance)
|
||||||
|
: super(balance.getValueInUnit(EtherUnit.wei).toInt(),
|
||||||
|
balance.getValueInUnit(EtherUnit.wei).toInt());
|
||||||
|
|
||||||
|
final EtherAmount balance;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get formattedAdditionalBalance {
|
String get formattedAdditionalBalance => balance.getValueInUnit(EtherUnit.ether).toString();
|
||||||
return EtherAmount.fromUnitAndValue(EtherUnit.ether, additional.toString())
|
|
||||||
.getInEther
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get formattedAvailableBalance =>
|
String get formattedAvailableBalance => balance.getValueInUnit(EtherUnit.ether).toString();
|
||||||
EtherAmount.fromUnitAndValue(EtherUnit.ether, available.toString()).getInEther.toString();
|
|
||||||
|
|
||||||
String toJSON() => json.encode({'available': available, 'additional': additional});
|
String toJSON() => json.encode({'balanceInWei': balance.getInWei.toString()});
|
||||||
|
|
||||||
static EthereumBalance? fromJSON(String? jsonSource) {
|
static EthereumBalance? fromJSON(String? jsonSource) {
|
||||||
if (jsonSource == null) {
|
if (jsonSource == null) {
|
||||||
|
@ -26,9 +25,10 @@ class EthereumBalance extends Balance {
|
||||||
|
|
||||||
final decoded = json.decode(jsonSource) as Map;
|
final decoded = json.decode(jsonSource) as Map;
|
||||||
|
|
||||||
return EthereumBalance(
|
try {
|
||||||
available: decoded['available'] as int? ?? 0,
|
return EthereumBalance(EtherAmount.inWei(BigInt.parse(decoded['balanceInWei'])));
|
||||||
additional: decoded['additional'] as int? ?? 0,
|
} catch (e) {
|
||||||
);
|
return EthereumBalance(EtherAmount.zero());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:cw_core/node.dart';
|
import 'package:cw_core/node.dart';
|
||||||
import 'package:cw_ethereum/ethereum_transaction_priority.dart';
|
import 'package:cw_ethereum/ethereum_transaction_priority.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
|
@ -17,10 +19,8 @@ class EthereumClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<EtherAmount> getBalance(String privateKey) async {
|
Future<EtherAmount> getBalance(EthereumAddress address) async {
|
||||||
final private = EthPrivateKey.fromHex(privateKey);
|
return await _client!.getBalance(address);
|
||||||
|
|
||||||
return _client!.getBalance(private.address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> getGasUnitPrice() async {
|
Future<int> getGasUnitPrice() async {
|
||||||
|
@ -39,35 +39,33 @@ class EthereumClient {
|
||||||
return result.map((e) => e.toInt()).toList();
|
return result.map((e) => e.toInt()).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> signTransaction(String privateKey, String toAddress, String amount) async {
|
Future<String> signTransaction(
|
||||||
final credentials = EthPrivateKey.fromHex(privateKey);
|
EthPrivateKey privateKey,
|
||||||
|
String toAddress,
|
||||||
|
String amount,
|
||||||
|
int fee,
|
||||||
|
) async {
|
||||||
final transaction = Transaction(
|
final transaction = Transaction(
|
||||||
from: credentials.address,
|
from: privateKey.address,
|
||||||
to: EthereumAddress.fromHex(toAddress),
|
to: EthereumAddress.fromHex(toAddress),
|
||||||
value: EtherAmount.zero(),
|
value: EtherAmount.fromUnitAndValue(EtherUnit.ether, amount),
|
||||||
|
// maxPriorityFeePerGas: EtherAmount.inWei(BigInt.from(fee)),
|
||||||
);
|
);
|
||||||
print("@@@@@@@@@@@@@@@@@");
|
|
||||||
print(transaction);
|
|
||||||
|
|
||||||
String tr = bytesToHex(await _client!.signTransaction(credentials, transaction));
|
final Uint8List signedTransaction = await _client!.signTransaction(privateKey, transaction);
|
||||||
print("@@@@@@@@@@@@@@@@@");
|
|
||||||
print(tr);
|
|
||||||
|
|
||||||
return tr;
|
return bytesToHex(signedTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> sendTransaction(String privateKey, String toAddress, String amount) async {
|
Future<String> sendTransaction(EthPrivateKey privateKey, String toAddress, String amount) async {
|
||||||
final credentials = EthPrivateKey.fromHex(privateKey);
|
|
||||||
|
|
||||||
final transaction = Transaction(
|
final transaction = Transaction(
|
||||||
from: credentials.address,
|
from: privateKey.address,
|
||||||
to: EthereumAddress.fromHex(toAddress),
|
to: EthereumAddress.fromHex(toAddress),
|
||||||
value: EtherAmount.fromUnitAndValue(EtherUnit.ether, amount),
|
value: EtherAmount.fromUnitAndValue(EtherUnit.ether, amount),
|
||||||
);
|
);
|
||||||
|
|
||||||
return await _client!.sendTransaction(
|
return await _client!.sendTransaction(
|
||||||
credentials,
|
privateKey,
|
||||||
transaction,
|
transaction,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,7 @@ import 'package:cw_ethereum/file.dart';
|
||||||
import 'package:cw_ethereum/pending_ethereum_transaction.dart';
|
import 'package:cw_ethereum/pending_ethereum_transaction.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:web3dart/web3dart.dart';
|
import 'package:web3dart/web3dart.dart';
|
||||||
import 'package:ed25519_hd_key/ed25519_hd_key.dart';
|
|
||||||
import 'package:bip39/bip39.dart' as bip39;
|
import 'package:bip39/bip39.dart' as bip39;
|
||||||
import 'package:hex/hex.dart';
|
|
||||||
|
|
||||||
part 'ethereum_wallet.g.dart';
|
part 'ethereum_wallet.g.dart';
|
||||||
|
|
||||||
|
@ -45,7 +43,7 @@ abstract class EthereumWalletBase
|
||||||
_client = EthereumClient(),
|
_client = EthereumClient(),
|
||||||
walletAddresses = EthereumWalletAddresses(walletInfo),
|
walletAddresses = EthereumWalletAddresses(walletInfo),
|
||||||
balance = ObservableMap<CryptoCurrency, EthereumBalance>.of(
|
balance = ObservableMap<CryptoCurrency, EthereumBalance>.of(
|
||||||
{CryptoCurrency.eth: initialBalance ?? EthereumBalance(available: 0, additional: 0)}),
|
{CryptoCurrency.eth: initialBalance ?? EthereumBalance(EtherAmount.zero())}),
|
||||||
super(walletInfo) {
|
super(walletInfo) {
|
||||||
this.walletInfo = walletInfo;
|
this.walletInfo = walletInfo;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +51,7 @@ abstract class EthereumWalletBase
|
||||||
final String _mnemonic;
|
final String _mnemonic;
|
||||||
final String _password;
|
final String _password;
|
||||||
|
|
||||||
late final String _privateKey;
|
late final EthPrivateKey _privateKey;
|
||||||
|
|
||||||
late EthereumClient _client;
|
late EthereumClient _client;
|
||||||
|
|
||||||
|
@ -75,7 +73,7 @@ abstract class EthereumWalletBase
|
||||||
await walletAddresses.init();
|
await walletAddresses.init();
|
||||||
_privateKey = await getPrivateKey(_mnemonic, _password);
|
_privateKey = await getPrivateKey(_mnemonic, _password);
|
||||||
transactionHistory = EthereumTransactionHistory();
|
transactionHistory = EthereumTransactionHistory();
|
||||||
walletAddresses.address = EthPrivateKey.fromHex(_privateKey).address.toString();
|
walletAddresses.address = _privateKey.address.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -121,11 +119,10 @@ abstract class EthereumWalletBase
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<PendingTransaction> createTransaction(Object credentials) async {
|
Future<PendingTransaction> createTransaction(Object credentials) async {
|
||||||
print("!!!!!!!!!!!!!!!!!!!");
|
|
||||||
final _credentials = credentials as EthereumTransactionCredentials;
|
final _credentials = credentials as EthereumTransactionCredentials;
|
||||||
final outputs = _credentials.outputs;
|
final outputs = _credentials.outputs;
|
||||||
final hasMultiDestination = outputs.length > 1;
|
final hasMultiDestination = outputs.length > 1;
|
||||||
final balance = await _client.getBalance(_privateKey);
|
final balance = await _client.getBalance(_privateKey.address);
|
||||||
int totalAmount = 0;
|
int totalAmount = 0;
|
||||||
|
|
||||||
if (hasMultiDestination) {
|
if (hasMultiDestination) {
|
||||||
|
@ -150,7 +147,12 @@ abstract class EthereumWalletBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await _client.signTransaction(_privateKey, _credentials.outputs.first.address, totalAmount.toString());
|
await _client.signTransaction(
|
||||||
|
_privateKey,
|
||||||
|
_credentials.outputs.first.address,
|
||||||
|
totalAmount.toString(),
|
||||||
|
_priorityFees[_credentials.priority!.raw],
|
||||||
|
);
|
||||||
|
|
||||||
return PendingEthereumTransaction(
|
return PendingEthereumTransaction(
|
||||||
client: _client,
|
client: _client,
|
||||||
|
@ -235,8 +237,8 @@ abstract class EthereumWalletBase
|
||||||
final jsonSource = await read(path: path, password: password);
|
final jsonSource = await read(path: path, password: password);
|
||||||
final data = json.decode(jsonSource) as Map;
|
final data = json.decode(jsonSource) as Map;
|
||||||
final mnemonic = data['mnemonic'] as String;
|
final mnemonic = data['mnemonic'] as String;
|
||||||
final balance = EthereumBalance.fromJSON(data['balance'] as String) ??
|
final balance =
|
||||||
EthereumBalance(available: 0, additional: 0);
|
EthereumBalance.fromJSON(data['balance'] as String) ?? EthereumBalance(EtherAmount.zero());
|
||||||
|
|
||||||
return EthereumWallet(
|
return EthereumWallet(
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
|
@ -252,21 +254,12 @@ abstract class EthereumWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<EthereumBalance> _fetchBalances() async {
|
Future<EthereumBalance> _fetchBalances() async {
|
||||||
final balance = await _client.getBalance(_privateKey);
|
final balance = await _client.getBalance(_privateKey.address);
|
||||||
|
return EthereumBalance(balance);
|
||||||
return EthereumBalance(
|
|
||||||
available: balance.getInEther.toInt(),
|
|
||||||
additional: balance.getInEther.toInt(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getPrivateKey(String mnemonic, String password) async {
|
Future<EthPrivateKey> getPrivateKey(String mnemonic, String password) async {
|
||||||
final seed = bip39.mnemonicToSeedHex(mnemonic);
|
final seed = bip39.mnemonicToSeedHex(mnemonic);
|
||||||
final master = await ED25519_HD_KEY.getMasterKeyFromSeed(
|
return EthPrivateKey.fromHex(seed);
|
||||||
HEX.decode(seed),
|
|
||||||
masterSecret: password,
|
|
||||||
);
|
|
||||||
final privateKey = HEX.encode(master.key);
|
|
||||||
return privateKey;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,12 @@ import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cw_core/pending_transaction.dart';
|
import 'package:cw_core/pending_transaction.dart';
|
||||||
import 'package:cw_ethereum/ethereum_client.dart';
|
import 'package:cw_ethereum/ethereum_client.dart';
|
||||||
import 'package:cw_ethereum/ethereum_transaction_credentials.dart';
|
import 'package:cw_ethereum/ethereum_transaction_credentials.dart';
|
||||||
|
import 'package:web3dart/web3dart.dart';
|
||||||
|
|
||||||
class PendingEthereumTransaction with PendingTransaction {
|
class PendingEthereumTransaction with PendingTransaction {
|
||||||
final EthereumClient client;
|
final EthereumClient client;
|
||||||
final EthereumTransactionCredentials credentials;
|
final EthereumTransactionCredentials credentials;
|
||||||
final String privateKey;
|
final EthPrivateKey privateKey;
|
||||||
final int amount;
|
final int amount;
|
||||||
|
|
||||||
PendingEthereumTransaction({
|
PendingEthereumTransaction({
|
||||||
|
|
|
@ -104,6 +104,7 @@ abstract class BalanceViewModelBase with Store {
|
||||||
switch(wallet.type) {
|
switch(wallet.type) {
|
||||||
case WalletType.monero:
|
case WalletType.monero:
|
||||||
case WalletType.haven:
|
case WalletType.haven:
|
||||||
|
case WalletType.ethereum:
|
||||||
return S.current.xmr_available_balance;
|
return S.current.xmr_available_balance;
|
||||||
default:
|
default:
|
||||||
return S.current.confirmed;
|
return S.current.confirmed;
|
||||||
|
@ -115,6 +116,7 @@ abstract class BalanceViewModelBase with Store {
|
||||||
switch(wallet.type) {
|
switch(wallet.type) {
|
||||||
case WalletType.monero:
|
case WalletType.monero:
|
||||||
case WalletType.haven:
|
case WalletType.haven:
|
||||||
|
case WalletType.ethereum:
|
||||||
return S.current.xmr_full_balance;
|
return S.current.xmr_full_balance;
|
||||||
default:
|
default:
|
||||||
return S.current.unconfirmed;
|
return S.current.unconfirmed;
|
||||||
|
|
Loading…
Reference in a new issue