nano-unfinished

This commit is contained in:
fosse 2023-07-31 09:10:33 -04:00
parent 33c99cb2a5
commit 601b646e27
10 changed files with 154 additions and 94 deletions

View file

@ -0,0 +1,7 @@
import 'package:cw_core/output_info.dart';
class NanoTransactionCredentials {
NanoTransactionCredentials(this.outputs);
final List<OutputInfo> outputs;
}

View file

@ -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 {

View file

@ -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!,

View 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);
}

View file

@ -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(),
);
}
}

View file

@ -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 {

View file

@ -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;
}

View file

@ -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()}');
}

View file

@ -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;

View file

@ -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 {