Fix Private key for Ethereum wallets

This commit is contained in:
OmarHatem 2023-04-05 18:01:20 +02:00
parent db90dde952
commit b02b653ceb
6 changed files with 52 additions and 58 deletions

View file

@ -27,7 +27,7 @@ dependencies:
unorm_dart: ^0.2.0
cryptography: ^2.0.5
encrypt: ^5.0.1
dev_dependencies:
flutter_test:
sdk: flutter

View file

@ -4,20 +4,19 @@ import 'package:cw_core/balance.dart';
import 'package:web3dart/web3dart.dart';
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
String get formattedAdditionalBalance {
return EtherAmount.fromUnitAndValue(EtherUnit.ether, additional.toString())
.getInEther
.toString();
}
String get formattedAdditionalBalance => balance.getValueInUnit(EtherUnit.ether).toString();
@override
String get formattedAvailableBalance =>
EtherAmount.fromUnitAndValue(EtherUnit.ether, available.toString()).getInEther.toString();
String get formattedAvailableBalance => balance.getValueInUnit(EtherUnit.ether).toString();
String toJSON() => json.encode({'available': available, 'additional': additional});
String toJSON() => json.encode({'balanceInWei': balance.getInWei.toString()});
static EthereumBalance? fromJSON(String? jsonSource) {
if (jsonSource == null) {
@ -26,9 +25,10 @@ class EthereumBalance extends Balance {
final decoded = json.decode(jsonSource) as Map;
return EthereumBalance(
available: decoded['available'] as int? ?? 0,
additional: decoded['additional'] as int? ?? 0,
);
try {
return EthereumBalance(EtherAmount.inWei(BigInt.parse(decoded['balanceInWei'])));
} catch (e) {
return EthereumBalance(EtherAmount.zero());
}
}
}

View file

@ -1,3 +1,5 @@
import 'dart:typed_data';
import 'package:cw_core/node.dart';
import 'package:cw_ethereum/ethereum_transaction_priority.dart';
import 'package:http/http.dart';
@ -17,10 +19,8 @@ class EthereumClient {
}
}
Future<EtherAmount> getBalance(String privateKey) async {
final private = EthPrivateKey.fromHex(privateKey);
return _client!.getBalance(private.address);
Future<EtherAmount> getBalance(EthereumAddress address) async {
return await _client!.getBalance(address);
}
Future<int> getGasUnitPrice() async {
@ -39,35 +39,33 @@ class EthereumClient {
return result.map((e) => e.toInt()).toList();
}
Future<String> signTransaction(String privateKey, String toAddress, String amount) async {
final credentials = EthPrivateKey.fromHex(privateKey);
Future<String> signTransaction(
EthPrivateKey privateKey,
String toAddress,
String amount,
int fee,
) async {
final transaction = Transaction(
from: credentials.address,
from: privateKey.address,
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));
print("@@@@@@@@@@@@@@@@@");
print(tr);
final Uint8List signedTransaction = await _client!.signTransaction(privateKey, transaction);
return tr;
return bytesToHex(signedTransaction);
}
Future<String> sendTransaction(String privateKey, String toAddress, String amount) async {
final credentials = EthPrivateKey.fromHex(privateKey);
Future<String> sendTransaction(EthPrivateKey privateKey, String toAddress, String amount) async {
final transaction = Transaction(
from: credentials.address,
from: privateKey.address,
to: EthereumAddress.fromHex(toAddress),
value: EtherAmount.fromUnitAndValue(EtherUnit.ether, amount),
);
return await _client!.sendTransaction(
credentials,
privateKey,
transaction,
);
}

View file

@ -22,9 +22,7 @@ import 'package:cw_ethereum/file.dart';
import 'package:cw_ethereum/pending_ethereum_transaction.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';
@ -45,7 +43,7 @@ abstract class EthereumWalletBase
_client = EthereumClient(),
walletAddresses = EthereumWalletAddresses(walletInfo),
balance = ObservableMap<CryptoCurrency, EthereumBalance>.of(
{CryptoCurrency.eth: initialBalance ?? EthereumBalance(available: 0, additional: 0)}),
{CryptoCurrency.eth: initialBalance ?? EthereumBalance(EtherAmount.zero())}),
super(walletInfo) {
this.walletInfo = walletInfo;
}
@ -53,7 +51,7 @@ abstract class EthereumWalletBase
final String _mnemonic;
final String _password;
late final String _privateKey;
late final EthPrivateKey _privateKey;
late EthereumClient _client;
@ -75,7 +73,7 @@ abstract class EthereumWalletBase
await walletAddresses.init();
_privateKey = await getPrivateKey(_mnemonic, _password);
transactionHistory = EthereumTransactionHistory();
walletAddresses.address = EthPrivateKey.fromHex(_privateKey).address.toString();
walletAddresses.address = _privateKey.address.toString();
}
@override
@ -121,11 +119,10 @@ abstract class EthereumWalletBase
@override
Future<PendingTransaction> createTransaction(Object credentials) async {
print("!!!!!!!!!!!!!!!!!!!");
final _credentials = credentials as EthereumTransactionCredentials;
final outputs = _credentials.outputs;
final hasMultiDestination = outputs.length > 1;
final balance = await _client.getBalance(_privateKey);
final balance = await _client.getBalance(_privateKey.address);
int totalAmount = 0;
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(
client: _client,
@ -235,8 +237,8 @@ abstract class EthereumWalletBase
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);
final balance =
EthereumBalance.fromJSON(data['balance'] as String) ?? EthereumBalance(EtherAmount.zero());
return EthereumWallet(
walletInfo: walletInfo,
@ -252,21 +254,12 @@ abstract class EthereumWalletBase
}
Future<EthereumBalance> _fetchBalances() async {
final balance = await _client.getBalance(_privateKey);
return EthereumBalance(
available: balance.getInEther.toInt(),
additional: balance.getInEther.toInt(),
);
final balance = await _client.getBalance(_privateKey.address);
return EthereumBalance(balance);
}
Future<String> getPrivateKey(String mnemonic, String password) async {
Future<EthPrivateKey> 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;
return EthPrivateKey.fromHex(seed);
}
}

View file

@ -3,11 +3,12 @@ import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_ethereum/ethereum_client.dart';
import 'package:cw_ethereum/ethereum_transaction_credentials.dart';
import 'package:web3dart/web3dart.dart';
class PendingEthereumTransaction with PendingTransaction {
final EthereumClient client;
final EthereumTransactionCredentials credentials;
final String privateKey;
final EthPrivateKey privateKey;
final int amount;
PendingEthereumTransaction({

View file

@ -104,6 +104,7 @@ abstract class BalanceViewModelBase with Store {
switch(wallet.type) {
case WalletType.monero:
case WalletType.haven:
case WalletType.ethereum:
return S.current.xmr_available_balance;
default:
return S.current.confirmed;
@ -115,6 +116,7 @@ abstract class BalanceViewModelBase with Store {
switch(wallet.type) {
case WalletType.monero:
case WalletType.haven:
case WalletType.ethereum:
return S.current.xmr_full_balance;
default:
return S.current.unconfirmed;