mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-22 18:54:47 +00:00
Add initial create Eth wallet flow
This commit is contained in:
parent
2c7883e099
commit
91ef1fdc7d
8 changed files with 208 additions and 14 deletions
|
@ -1,7 +1,19 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_core/pathForWallet.dart';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cw_core/wallet_addresses.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_ethereum/ethereum_balance.dart';
|
||||
import 'package:cw_ethereum/ethereum_transaction_history.dart';
|
||||
import 'package:cw_ethereum/ethereum_transaction_info.dart';
|
||||
import 'package:cw_ethereum/ethereum_wallet_addresses.dart';
|
||||
import 'package:cw_ethereum/file.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'ethereum_wallet.g.dart';
|
||||
|
@ -11,5 +23,87 @@ class EthereumWallet = EthereumWalletBase with _$EthereumWallet;
|
|||
abstract class EthereumWalletBase
|
||||
extends WalletBase<EthereumBalance, EthereumTransactionHistory, EthereumTransactionInfo>
|
||||
with Store {
|
||||
EthereumWalletBase(super.walletInfo);
|
||||
EthereumWalletBase({
|
||||
required WalletInfo walletInfo,
|
||||
required this.mnemonic,
|
||||
required this.privateKey,
|
||||
required String password,
|
||||
}) : syncStatus = NotConnectedSyncStatus(),
|
||||
_password = password,
|
||||
walletAddresses = EthereumWalletAddresses(walletInfo),
|
||||
super(walletInfo) {
|
||||
this.walletInfo = walletInfo;
|
||||
transactionHistory = EthereumTransactionHistory();
|
||||
}
|
||||
|
||||
final String mnemonic;
|
||||
final String privateKey;
|
||||
final String _password;
|
||||
|
||||
@override
|
||||
SyncStatus syncStatus;
|
||||
|
||||
@override
|
||||
ObservableMap<CryptoCurrency, EthereumBalance> get balance => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> changePassword(String password) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
void close() {}
|
||||
|
||||
@override
|
||||
Future<void> connectToNode({required Node node}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<PendingTransaction> createTransaction(Object credentials) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, EthereumTransactionInfo>> fetchTransactions() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Object get keys => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future<void> rescan({required int height}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> save() async {
|
||||
final path = await makePath();
|
||||
await write(path: path, password: _password, data: toJSON());
|
||||
await transactionHistory.save();
|
||||
}
|
||||
|
||||
@override
|
||||
String get seed => mnemonic;
|
||||
|
||||
@override
|
||||
Future<void> startSync() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
WalletAddresses walletAddresses;
|
||||
|
||||
Future<String> makePath() async => pathForWallet(name: walletInfo.name, type: walletInfo.type);
|
||||
|
||||
String toJSON() => json.encode({
|
||||
'mnemonic': mnemonic,
|
||||
// TODO: save other attributes
|
||||
});
|
||||
}
|
||||
|
|
28
cw_ethereum/lib/ethereum_wallet_addresses.dart
Normal file
28
cw_ethereum/lib/ethereum_wallet_addresses.dart
Normal file
|
@ -0,0 +1,28 @@
|
|||
import 'package:cw_core/wallet_addresses.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'ethereum_wallet_addresses.g.dart';
|
||||
|
||||
class EthereumWalletAddresses = EthereumWalletAddressesBase with _$EthereumWalletAddresses;
|
||||
|
||||
abstract class EthereumWalletAddressesBase extends WalletAddresses with Store {
|
||||
EthereumWalletAddressesBase(WalletInfo walletInfo)
|
||||
: address = '',
|
||||
super(walletInfo);
|
||||
|
||||
@override
|
||||
String address;
|
||||
|
||||
@override
|
||||
Future<void> init() {
|
||||
// TODO: implement init
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateAddressesInBox() {
|
||||
// TODO: implement updateAddressesInBox
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
|
@ -10,7 +10,10 @@ 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> {
|
||||
|
@ -20,13 +23,15 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
|||
|
||||
@override
|
||||
Future<EthereumWallet> create(EthereumNewWalletCredentials credentials) async {
|
||||
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||
await monero_wallet_manager.createWallet(
|
||||
path: path,
|
||||
password: credentials.password!,
|
||||
final mnemonic = bip39.generateMnemonic();
|
||||
final privateKey = await getPrivateKey(mnemonic, credentials.password!);
|
||||
final wallet = EthereumWallet(
|
||||
walletInfo: credentials.walletInfo!,
|
||||
mnemonic: mnemonic,
|
||||
privateKey: privateKey,
|
||||
password: credentials.password!,
|
||||
);
|
||||
final wallet = EthereumWallet(credentials.walletInfo!);
|
||||
await wallet.init();
|
||||
await wallet.save();
|
||||
|
||||
return wallet;
|
||||
}
|
||||
|
@ -61,4 +66,12 @@ 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;
|
||||
}
|
||||
}
|
||||
|
|
39
cw_ethereum/lib/file.dart
Normal file
39
cw_ethereum/lib/file.dart
Normal file
|
@ -0,0 +1,39 @@
|
|||
import 'dart:io';
|
||||
import 'package:cw_core/key.dart';
|
||||
import 'package:encrypt/encrypt.dart' as encrypt;
|
||||
|
||||
Future<void> write(
|
||||
{required String path,
|
||||
required String password,
|
||||
required String data}) async {
|
||||
final keys = extractKeys(password);
|
||||
final key = encrypt.Key.fromBase64(keys.first);
|
||||
final iv = encrypt.IV.fromBase64(keys.last);
|
||||
final encrypted = await encode(key: key, iv: iv, data: data);
|
||||
final f = File(path);
|
||||
f.writeAsStringSync(encrypted);
|
||||
}
|
||||
|
||||
Future<void> writeData(
|
||||
{required String path,
|
||||
required String password,
|
||||
required String data}) async {
|
||||
final keys = extractKeys(password);
|
||||
final key = encrypt.Key.fromBase64(keys.first);
|
||||
final iv = encrypt.IV.fromBase64(keys.last);
|
||||
final encrypted = await encode(key: key, iv: iv, data: data);
|
||||
final f = File(path);
|
||||
f.writeAsStringSync(encrypted);
|
||||
}
|
||||
|
||||
Future<String> read({required String path, required String password}) async {
|
||||
final file = File(path);
|
||||
|
||||
if (!file.existsSync()) {
|
||||
file.createSync();
|
||||
}
|
||||
|
||||
final encrypted = file.readAsStringSync();
|
||||
|
||||
return decode(password: password, data: encrypted);
|
||||
}
|
|
@ -12,14 +12,19 @@ environment:
|
|||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
web3dart: ^2.5.1
|
||||
# web3dart: ^2.4.1
|
||||
mobx: ^2.0.7+4
|
||||
bip39: ^1.0.6
|
||||
ed25519_hd_key: ^2.2.0
|
||||
hex: ^0.2.0
|
||||
cw_core:
|
||||
path: ../cw_core
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
build_runner: ^2.1.11
|
||||
mobx_codegen: ^2.0.7
|
||||
hive_generator: ^1.1.3
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
|
|
|
@ -2,11 +2,15 @@ part of 'ethereum.dart';
|
|||
|
||||
class CWEthereum extends Ethereum {
|
||||
@override
|
||||
List<String> getEthereumWordList(String language) {
|
||||
return EthereumMnemonics.englishWordlist;
|
||||
}
|
||||
List<String> getEthereumWordList(String language) => EthereumMnemonics.englishWordlist;
|
||||
|
||||
WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource) {
|
||||
return EthereumWalletService(walletInfoSource);
|
||||
}
|
||||
WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource) =>
|
||||
EthereumWalletService(walletInfoSource);
|
||||
|
||||
@override
|
||||
WalletCredentials createEthereumNewWalletCredentials({
|
||||
required String name,
|
||||
WalletInfo? walletInfo,
|
||||
}) =>
|
||||
EthereumNewWalletCredentials(name: name, walletInfo: walletInfo);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
@ -41,6 +42,8 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
|||
case WalletType.haven:
|
||||
return haven!.createHavenNewWalletCredentials(
|
||||
name: name, language: options as String);
|
||||
case WalletType.ethereum:
|
||||
return ethereum!.createEthereumNewWalletCredentials(name: name);
|
||||
default:
|
||||
throw Exception('Unexpected type: ${type.toString()}');;
|
||||
}
|
||||
|
|
|
@ -477,12 +477,20 @@ Future<void> generateEthereum(bool hasImplementation) async {
|
|||
const ethereumCommonHeaders = """
|
||||
""";
|
||||
const ethereumCWHeaders = """
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_service.dart';
|
||||
import 'package:cw_ethereum/ethereum_mnemonics.dart';
|
||||
import 'package:cw_ethereum/ethereum_wallet_creation_credentials.dart';
|
||||
import 'package:cw_ethereum/ethereum_wallet_service.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
""";
|
||||
const ethereumCwPart = "part 'cw_ethereum.dart';";
|
||||
const ethereumContent = """
|
||||
abstract class Ethereum {
|
||||
List<String> getEthereumWordList(String language);
|
||||
WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource);
|
||||
WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo});
|
||||
}
|
||||
""";
|
||||
|
||||
|
|
Loading…
Reference in a new issue