mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
nano-unfinished
This commit is contained in:
parent
33c99cb2a5
commit
601b646e27
10 changed files with 154 additions and 94 deletions
7
cw_nano/lib/nano_transaction_credentials.dart
Normal file
7
cw_nano/lib/nano_transaction_credentials.dart
Normal file
|
@ -0,0 +1,7 @@
|
|||
import 'package:cw_core/output_info.dart';
|
||||
|
||||
class NanoTransactionCredentials {
|
||||
NanoTransactionCredentials(this.outputs);
|
||||
|
||||
final List<OutputInfo> outputs;
|
||||
}
|
|
@ -16,6 +16,7 @@ import 'package:cw_nano/nano_transaction_history.dart';
|
|||
import 'package:cw_nano/nano_transaction_info.dart';
|
||||
import 'package:cw_nano/nano_util.dart';
|
||||
import 'package:cw_nano/nano_wallet_info.dart';
|
||||
import 'package:cw_nano/pending_nano_transaction.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'dart:async';
|
||||
import 'package:cw_nano/nano_wallet_addresses.dart';
|
||||
|
@ -126,55 +127,19 @@ abstract class NanoWalletBase
|
|||
print(credentials);
|
||||
// throw UnimplementedError();
|
||||
|
||||
// final _credentials = credentials as EthereumTransactionCredentials;
|
||||
// final outputs = _credentials.outputs;
|
||||
// final hasMultiDestination = outputs.length > 1;
|
||||
// final _erc20Balance = balance[_credentials.currency]!;
|
||||
// BigInt totalAmount = BigInt.zero;
|
||||
// int exponent =
|
||||
// _credentials.currency is Erc20Token ? (_credentials.currency as Erc20Token).decimal : 18;
|
||||
// BigInt amountToEthereumMultiplier = BigInt.from(pow(10, exponent));
|
||||
return PendingNanoTransaction(
|
||||
amount: BigInt.one,
|
||||
fee: 0,
|
||||
id: "test",
|
||||
nanoClient: _client,
|
||||
);
|
||||
|
||||
// if (hasMultiDestination) {
|
||||
// if (outputs.any((item) => item.sendAll || (item.formattedCryptoAmount ?? 0) <= 0)) {
|
||||
// throw EthereumTransactionCreationException(_credentials.currency);
|
||||
// }
|
||||
|
||||
// final totalOriginalAmount = EthereumFormatter.parseEthereumAmountToDouble(
|
||||
// outputs.fold(0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0)));
|
||||
// totalAmount = BigInt.from(totalOriginalAmount) * amountToEthereumMultiplier;
|
||||
|
||||
// if (_erc20Balance.balance < totalAmount) {
|
||||
// throw EthereumTransactionCreationException(_credentials.currency);
|
||||
// }
|
||||
// } else {
|
||||
// final output = outputs.first;
|
||||
// final BigInt allAmount = _erc20Balance.balance - BigInt.from(feeRate(_credentials.priority!));
|
||||
// final totalOriginalAmount =
|
||||
// EthereumFormatter.parseEthereumAmountToDouble(output.formattedCryptoAmount ?? 0);
|
||||
// totalAmount = output.sendAll
|
||||
// ? allAmount
|
||||
// : BigInt.from(totalOriginalAmount) * amountToEthereumMultiplier;
|
||||
|
||||
// if (_erc20Balance.balance < totalAmount) {
|
||||
// throw EthereumTransactionCreationException(_credentials.currency);
|
||||
// }
|
||||
// }
|
||||
|
||||
// final pendingEthereumTransaction = await _client.signTransaction(
|
||||
// privateKey: _privateKey,
|
||||
// toAddress: _credentials.outputs.first.address,
|
||||
// amount: totalAmount.toString(),
|
||||
// gas: _priorityFees[_credentials.priority!.raw],
|
||||
// priority: _credentials.priority!,
|
||||
// currency: _credentials.currency,
|
||||
// exponent: exponent,
|
||||
// contractAddress: _credentials.currency is Erc20Token
|
||||
// ? (_credentials.currency as Erc20Token).contractAddress
|
||||
// : null,
|
||||
// );
|
||||
|
||||
// return pendingEthereumTransaction;
|
||||
// return PendingNanoTransaction(txb.build(), type,
|
||||
// electrumClient: electrumClient, amount: amount, fee: fee)
|
||||
// ..addListener((transaction) async {
|
||||
// transactionHistory.addOne(transaction);
|
||||
// await updateBalance();
|
||||
// });
|
||||
}
|
||||
|
||||
Future<void> updateTransactions() async {
|
||||
|
|
|
@ -25,13 +25,13 @@ class NanoRestoreWalletFromSeedCredentials extends WalletCredentials {
|
|||
NanoRestoreWalletFromSeedCredentials(
|
||||
{required String name,
|
||||
required this.mnemonic,
|
||||
required this.derivationType,
|
||||
this.derivationType,
|
||||
int height = 0,
|
||||
String? password})
|
||||
: super(name: name, password: password, height: height);
|
||||
|
||||
final String mnemonic;
|
||||
final DerivationType derivationType;
|
||||
final DerivationType? derivationType;
|
||||
}
|
||||
|
||||
class NanoWalletLoadingException implements Exception {
|
||||
|
@ -44,9 +44,11 @@ class NanoRestoreWalletFromKeysCredentials extends WalletCredentials {
|
|||
required String name,
|
||||
required String password,
|
||||
required this.seedKey,
|
||||
this.derivationType,
|
||||
}) : super(name: name, password: password);
|
||||
|
||||
final String seedKey;
|
||||
final DerivationType? derivationType;
|
||||
}
|
||||
|
||||
class NanoWalletService extends WalletService<NanoNewWalletCredentials,
|
||||
|
@ -63,9 +65,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
|
|||
|
||||
@override
|
||||
Future<WalletBase> create(NanoNewWalletCredentials credentials) async {
|
||||
print("nano_wallet_service create");
|
||||
final mnemonic = bip39.generateMnemonic();
|
||||
|
||||
final nanoWalletInfo = NanoWalletInfo(
|
||||
walletInfo: credentials.walletInfo!,
|
||||
derivationType: DerivationType.nano,
|
||||
|
@ -140,7 +140,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
|
|||
NanoBalance bip39Balance = await nanoClient.getBalance(publicAddressBip39);
|
||||
NanoBalance standardBalance = await nanoClient.getBalance(publicAddressStandard);
|
||||
|
||||
// TODO: this is super basic implementation, and if both addresses have balances
|
||||
// TODO: this is a super basic implementation, and if both addresses have balances
|
||||
// it might not be the one that the user wants, though it is unlikely
|
||||
if (bip39Balance.currentBalance > standardBalance.currentBalance) {
|
||||
return DerivationType.bip39;
|
||||
|
@ -156,10 +156,10 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
|
|||
Future<NanoWallet> restoreFromKeys(NanoRestoreWalletFromKeysCredentials credentials) async {
|
||||
throw UnimplementedError("restoreFromKeys");
|
||||
|
||||
// TODO: mnemonic can't be derived from the seedKey in the nanostandard derivation
|
||||
// TODO: mnemonic can't be derived from the seedKey in the nano standard derivation
|
||||
// which complicates things
|
||||
|
||||
// DerivationType derivationType = await compareDerivationMethods(seedKey: credentials.seedKey);
|
||||
// DerivationType derivationType = credentials.derivationType ?? await compareDerivationMethods(seedKey: credentials.seedKey);
|
||||
// String? mnemonic;
|
||||
// final nanoWalletInfo = NanoWalletInfo(
|
||||
// walletInfo: credentials.walletInfo!,
|
||||
|
@ -185,7 +185,8 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
|
|||
throw NanoMnemonicIsIncorrectException();
|
||||
}
|
||||
|
||||
DerivationType derivationType = await compareDerivationMethods(mnemonic: credentials.mnemonic);
|
||||
DerivationType derivationType = credentials.derivationType ??
|
||||
await compareDerivationMethods(mnemonic: credentials.mnemonic);
|
||||
|
||||
final nanoWalletInfo = NanoWalletInfo(
|
||||
walletInfo: credentials.walletInfo!,
|
||||
|
|
62
cw_nano/lib/pending_nano_transaction.dart
Normal file
62
cw_nano/lib/pending_nano_transaction.dart
Normal file
|
@ -0,0 +1,62 @@
|
|||
import 'package:cw_core/pending_transaction.dart';
|
||||
import 'package:cw_core/transaction_direction.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_nano/nano_client.dart';
|
||||
import 'package:cw_nano/nano_transaction_info.dart';
|
||||
import 'package:cw_nano/nano_util.dart';
|
||||
|
||||
class PendingNanoTransaction with PendingTransaction {
|
||||
PendingNanoTransaction({
|
||||
required this.nanoClient,
|
||||
required this.amount,
|
||||
required this.fee,
|
||||
required this.id,
|
||||
});
|
||||
|
||||
final NanoClient nanoClient;
|
||||
final BigInt amount;
|
||||
final int fee;
|
||||
final String id;
|
||||
String hex = "unused";
|
||||
|
||||
// @override
|
||||
// String get id => id;
|
||||
|
||||
// @override
|
||||
// String get hex => _tx.toHex();
|
||||
|
||||
@override
|
||||
String get amountFormatted =>
|
||||
NanoUtil.getRawAsUsableString(amount.toString(), NanoUtil.rawPerNano);
|
||||
|
||||
@override
|
||||
String get feeFormatted => "0";
|
||||
|
||||
// final List<void Function(ElectrumTransactionInfo transaction)> _listeners;
|
||||
|
||||
@override
|
||||
Future<void> commit() async {
|
||||
// final result =
|
||||
// await electrumClient.broadcastTransaction(transactionRaw: _tx.toHex());
|
||||
|
||||
// if (result.isEmpty) {
|
||||
// throw BitcoinCommitTransactionException();
|
||||
// }
|
||||
|
||||
// _listeners?.forEach((listener) => listener(transactionInfo()));
|
||||
}
|
||||
|
||||
// void addListener(
|
||||
// void Function(ElectrumTransactionInfo transaction) listener) =>
|
||||
// _listeners.add(listener);
|
||||
|
||||
// ElectrumTransactionInfo transactionInfo() => ElectrumTransactionInfo(type,
|
||||
// id: id,
|
||||
// height: 0,
|
||||
// amount: amount,
|
||||
// direction: TransactionDirection.outgoing,
|
||||
// date: DateTime.now(),
|
||||
// isPending: true,
|
||||
// confirmations: 0,
|
||||
// fee: fee);
|
||||
}
|
|
@ -39,9 +39,9 @@ class CWNano extends Nano {
|
|||
@override
|
||||
WalletCredentials createNanoRestoreWalletFromSeedCredentials({
|
||||
required String name,
|
||||
required String mnemonic,
|
||||
required DerivationType derivationType,
|
||||
required String password,
|
||||
required String mnemonic,
|
||||
DerivationType? derivationType,
|
||||
}) =>
|
||||
NanoRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
|
@ -61,4 +61,22 @@ class CWNano extends Nano {
|
|||
void onStartup() {
|
||||
// monero_wallet_api.onStartup();
|
||||
}
|
||||
|
||||
@override
|
||||
Object createNanoTransactionCredentials(List<Output> outputs) {
|
||||
return NanoTransactionCredentials(
|
||||
outputs
|
||||
.map((out) => OutputInfo(
|
||||
fiatAmount: out.fiatAmount,
|
||||
cryptoAmount: out.cryptoAmount,
|
||||
address: out.address,
|
||||
note: out.note,
|
||||
sendAll: out.sendAll,
|
||||
extractedAddress: out.extractedAddress,
|
||||
isParsedAddress: out.isParsedAddress,
|
||||
formattedCryptoAmount: out.formattedCryptoAmount,
|
||||
))
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cake_wallet/view_model/send/output.dart';
|
||||
import 'package:cw_core/output_info.dart';
|
||||
import 'package:cw_nano/nano_wallet.dart';
|
||||
import 'package:cw_nano/nano_wallet_info.dart';
|
||||
import 'package:cw_nano/nano_wallet_service.dart';
|
||||
|
@ -9,6 +12,7 @@ import 'package:cw_core/wallet_service.dart';
|
|||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_nano/nano_balance.dart';
|
||||
import 'package:cw_nano/nano_wallet_creation_credentials.dart';
|
||||
import 'package:cw_nano/nano_transaction_credentials.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
|
@ -52,9 +56,9 @@ abstract class Nano {
|
|||
|
||||
WalletCredentials createNanoRestoreWalletFromSeedCredentials({
|
||||
required String name,
|
||||
required String mnemonic,
|
||||
required String password,
|
||||
required DerivationType derivationType,
|
||||
required String mnemonic,
|
||||
DerivationType? derivationType,
|
||||
});
|
||||
|
||||
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex);
|
||||
|
@ -62,6 +66,8 @@ abstract class Nano {
|
|||
void onStartup();
|
||||
|
||||
List<String> getNanoWordList(String language);
|
||||
|
||||
Object createNanoTransactionCredentials(List<Output> outputs);
|
||||
}
|
||||
|
||||
abstract class NanoAccountList {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
|
||||
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:cake_wallet/nano/nano.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cake_wallet/view_model/send/output.dart';
|
||||
|
@ -32,13 +33,8 @@ part 'send_view_model.g.dart';
|
|||
class SendViewModel = SendViewModelBase with _$SendViewModel;
|
||||
|
||||
abstract class SendViewModelBase with Store {
|
||||
SendViewModelBase(
|
||||
this._wallet,
|
||||
this._settingsStore,
|
||||
this.sendTemplateViewModel,
|
||||
this._fiatConversationStore,
|
||||
this.balanceViewModel,
|
||||
this.transactionDescriptionBox)
|
||||
SendViewModelBase(this._wallet, this._settingsStore, this.sendTemplateViewModel,
|
||||
this._fiatConversationStore, this.balanceViewModel, this.transactionDescriptionBox)
|
||||
: state = InitialExecutionState(),
|
||||
currencies = _wallet.balance.keys.toList(),
|
||||
selectedCryptoCurrency = _wallet.currency,
|
||||
|
@ -52,7 +48,8 @@ abstract class SendViewModelBase with Store {
|
|||
_settingsStore.priority[_wallet.type] = priorities.first;
|
||||
}
|
||||
|
||||
outputs.add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
|
||||
outputs
|
||||
.add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
|
||||
}
|
||||
|
||||
@observable
|
||||
|
@ -62,7 +59,8 @@ abstract class SendViewModelBase with Store {
|
|||
|
||||
@action
|
||||
void addOutput() {
|
||||
outputs.add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
|
||||
outputs
|
||||
.add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
|
||||
}
|
||||
|
||||
@action
|
||||
|
@ -149,13 +147,11 @@ abstract class SendViewModelBase with Store {
|
|||
|
||||
@computed
|
||||
String get pendingTransactionFiatAmountFormatted =>
|
||||
isFiatDisabled ? '' : pendingTransactionFiatAmount +
|
||||
' ' + fiat.title;
|
||||
isFiatDisabled ? '' : pendingTransactionFiatAmount + ' ' + fiat.title;
|
||||
|
||||
@computed
|
||||
String get pendingTransactionFeeFiatAmountFormatted =>
|
||||
isFiatDisabled ? '' : pendingTransactionFeeFiatAmount +
|
||||
' ' + fiat.title;
|
||||
isFiatDisabled ? '' : pendingTransactionFeeFiatAmount + ' ' + fiat.title;
|
||||
|
||||
@computed
|
||||
bool get isReadyForSend => _wallet.syncStatus is SyncedSyncStatus;
|
||||
|
@ -176,9 +172,8 @@ abstract class SendViewModelBase with Store {
|
|||
|
||||
bool get hasMultiRecipient => _wallet.type != WalletType.haven;
|
||||
|
||||
bool get hasYat => outputs.any((out) =>
|
||||
out.isParsedAddress &&
|
||||
out.parsedAddress.parseFrom == ParseFrom.yatRecord);
|
||||
bool get hasYat => outputs
|
||||
.any((out) => out.isParsedAddress && out.parsedAddress.parseFrom == ParseFrom.yatRecord);
|
||||
|
||||
WalletType get walletType => _wallet.type;
|
||||
|
||||
|
@ -236,11 +231,9 @@ abstract class SendViewModelBase with Store {
|
|||
if (pendingTransaction!.id.isNotEmpty) {
|
||||
_settingsStore.shouldSaveRecipientAddress
|
||||
? await transactionDescriptionBox.add(TransactionDescription(
|
||||
id: pendingTransaction!.id,
|
||||
recipientAddress: address,
|
||||
transactionNote: note))
|
||||
: await transactionDescriptionBox.add(TransactionDescription(
|
||||
id: pendingTransaction!.id, transactionNote: note));
|
||||
id: pendingTransaction!.id, recipientAddress: address, transactionNote: note))
|
||||
: await transactionDescriptionBox
|
||||
.add(TransactionDescription(id: pendingTransaction!.id, transactionNote: note));
|
||||
}
|
||||
|
||||
state = TransactionCommitted();
|
||||
|
@ -278,8 +271,8 @@ abstract class SendViewModelBase with Store {
|
|||
throw Exception('Priority is null for wallet type: ${_wallet.type}');
|
||||
}
|
||||
|
||||
return monero!.createMoneroTransactionCreationCredentials(
|
||||
outputs: outputs, priority: priority);
|
||||
return monero!
|
||||
.createMoneroTransactionCreationCredentials(outputs: outputs, priority: priority);
|
||||
case WalletType.haven:
|
||||
final priority = _settingsStore.priority[_wallet.type];
|
||||
|
||||
|
@ -296,8 +289,12 @@ abstract class SendViewModelBase with Store {
|
|||
throw Exception('Priority is null for wallet type: ${_wallet.type}');
|
||||
}
|
||||
|
||||
return ethereum!.createEthereumTransactionCredentials(
|
||||
outputs, priority: priority, currency: selectedCryptoCurrency);
|
||||
return ethereum!.createEthereumTransactionCredentials(outputs,
|
||||
priority: priority, currency: selectedCryptoCurrency);
|
||||
case WalletType.nano:
|
||||
return nano!.createNanoTransactionCredentials(
|
||||
outputs,
|
||||
);
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_wallet.type}');
|
||||
}
|
||||
|
@ -319,10 +316,8 @@ abstract class SendViewModelBase with Store {
|
|||
currency.toLowerCase() == _wallet.currency.title.toLowerCase();
|
||||
|
||||
@action
|
||||
void onClose() =>
|
||||
_settingsStore.fiatCurrency = fiatFromSettings;
|
||||
void onClose() => _settingsStore.fiatCurrency = fiatFromSettings;
|
||||
|
||||
@action
|
||||
void setFiatCurrency(FiatCurrency fiat) =>
|
||||
_settingsStore.fiatCurrency = fiat;
|
||||
void setFiatCurrency(FiatCurrency fiat) => _settingsStore.fiatCurrency = fiat;
|
||||
}
|
||||
|
|
|
@ -118,6 +118,10 @@ abstract class WalletKeysViewModelBase with Store {
|
|||
return 'litecoin-wallet';
|
||||
case WalletType.haven:
|
||||
return 'haven-wallet';
|
||||
case WalletType.nano:
|
||||
return 'nano-wallet';
|
||||
case WalletType.banano:
|
||||
return 'banano-wallet';
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${_appStore.wallet!.toString()}');
|
||||
}
|
||||
|
|
|
@ -77,13 +77,11 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
|||
return ethereum!.createEthereumRestoreWalletFromSeedCredentials(
|
||||
name: name, mnemonic: seed, password: password);
|
||||
case WalletType.nano:
|
||||
// default to bip39 for now:
|
||||
final DerivationType derivationType = DerivationType.bip39;
|
||||
return nano!.createNanoRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password,
|
||||
derivationType: derivationType,
|
||||
derivationType: null,
|
||||
);
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -585,10 +585,12 @@ import 'package:cw_nano/nano_wallet_info.dart';
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/wallet_service.dart';
|
||||
import 'package:cw_core/output_info.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_nano/api/wallet.dart' as nano_wallet_api;
|
||||
import 'package:cw_nano/nano_balance.dart';
|
||||
import 'package:cw_nano/nano_wallet_creation_credentials.dart';
|
||||
import 'package:cw_nano/nano_transaction_credentials.dart';
|
||||
""";
|
||||
const nanoCwPart = "part 'cw_nano.dart';";
|
||||
const nanoContent = """
|
||||
|
@ -608,9 +610,9 @@ abstract class Nano {
|
|||
|
||||
WalletCredentials createNanoRestoreWalletFromSeedCredentials({
|
||||
required String name,
|
||||
required String mnemonic,
|
||||
required String password,
|
||||
required DerivationType derivationType,
|
||||
required String mnemonic,
|
||||
DerivationType? derivationType,
|
||||
});
|
||||
|
||||
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex);
|
||||
|
@ -618,6 +620,8 @@ abstract class Nano {
|
|||
void onStartup();
|
||||
|
||||
List<String> getNanoWordList(String language);
|
||||
|
||||
Object createNanoTransactionCredentials(List<Output> outputs);
|
||||
}
|
||||
|
||||
abstract class NanoAccountList {
|
||||
|
|
Loading…
Reference in a new issue