Peg in and peg out flow (#1745)

* version 4.20.0

* update build numbers

* UI updates and script fix for ios bundle identifier

* disable mweb for desktop

* change hardcoded ltc server ip address
electrum connection enhancement

* additional logging and minor fixes

* additional logging and minor fixes

* addresses pt.1

* logs of fixes and experimental changes, close wallet before opening next

* save

* fix icon

* fixes

* [skip ci] updates

* [skip ci] updates

* updates

* minor optimizations

* fix for when switching between wallets

* [skip ci] updates

* [skip ci] updates

* Update cw_bitcoin/lib/litecoin_wallet.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* Update cw_bitcoin/lib/litecoin_wallet.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* mobx

* mostly logging

* stream fix pt.1 [skip ci]

* updates

* some fixes and enhancements

* [skip ci] minor

* potential partial fix for streamsink closed

* fix stream sink closed errors

* fix mweb logo colors

* add initial whitelisting for coin types on send screen

* MWEB enhancements 2.0 (#1735)

* additional logging and minor fixes

* additional logging and minor fixes

* addresses pt.1

* Allow Wallet Group Names to be the same as Wallet Names (#1730)

* fix: Issues with imaging

* fix: Allow group names to be the same as wallet names

* fix: Bug with wallet grouping when a wallet is minimized

* fix: Bug with wallet grouping when a wallet is minimized

* logs of fixes and experimental changes, close wallet before opening next

* save

* fix icon

* fixes

* [skip ci] updates

* [skip ci] updates

* updates

* minor optimizations

* fix for when switching between wallets

* [skip ci] updates

* [skip ci] updates

* Update cw_bitcoin/lib/litecoin_wallet.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* Update cw_bitcoin/lib/litecoin_wallet.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* mobx

* mostly logging

* stream fix pt.1 [skip ci]

* updates

* some fixes and enhancements

* [skip ci] minor

* potential partial fix for streamsink closed

* fix stream sink closed errors

* fix mweb logo colors

* save

* minor enhancements [skip ci]

* save

* experimental

* minor

* minor [skip ci]

---------

Co-authored-by: David Adegoke <64401859+Blazebrain@users.noreply.github.com>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* fix menu list removing from original list

* handle pegin and pegout

* fix text color

* fix import

* pegin/out button ui updates

* update spacing + tx creation fix

* add correct args for link view model [skip ci]

---------

Co-authored-by: Matthew Fosse <matt@fosse.co>
Co-authored-by: fossephate <matt.cfosse@gmail.com>
Co-authored-by: David Adegoke <64401859+Blazebrain@users.noreply.github.com>
This commit is contained in:
Omar Hatem 2024-10-15 00:28:38 +03:00 committed by GitHub
parent 380f7653b2
commit ebe8c65407
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 428 additions and 253 deletions

View file

@ -1,11 +1,13 @@
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart'; import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
import 'package:cw_core/output_info.dart'; import 'package:cw_core/output_info.dart';
import 'package:cw_core/unspent_coin_type.dart';
class BitcoinTransactionCredentials { class BitcoinTransactionCredentials {
BitcoinTransactionCredentials(this.outputs, BitcoinTransactionCredentials(this.outputs,
{required this.priority, this.feeRate}); {required this.priority, this.feeRate, this.coinTypeToSpendFrom = UnspentCoinType.any});
final List<OutputInfo> outputs; final List<OutputInfo> outputs;
final BitcoinTransactionPriority? priority; final BitcoinTransactionPriority? priority;
final int? feeRate; final int? feeRate;
final UnspentCoinType coinTypeToSpendFrom;
} }

View file

@ -37,6 +37,7 @@ import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_keys_file.dart'; import 'package:cw_core/wallet_keys_file.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:cw_core/get_height_by_date.dart'; import 'package:cw_core/get_height_by_date.dart';
import 'package:cw_core/unspent_coin_type.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
@ -584,6 +585,7 @@ abstract class ElectrumWalletBase
required int credentialsAmount, required int credentialsAmount,
required bool paysToSilentPayment, required bool paysToSilentPayment,
int? inputsCount, int? inputsCount,
UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any,
}) { }) {
List<UtxoWithAddress> utxos = []; List<UtxoWithAddress> utxos = [];
List<Outpoint> vinOutpoints = []; List<Outpoint> vinOutpoints = [];
@ -594,7 +596,20 @@ abstract class ElectrumWalletBase
bool spendsUnconfirmedTX = false; bool spendsUnconfirmedTX = false;
int leftAmount = credentialsAmount; int leftAmount = credentialsAmount;
final availableInputs = unspentCoins.where((utx) => utx.isSending && !utx.isFrozen).toList(); final availableInputs = unspentCoins.where((utx) {
if (!utx.isSending || utx.isFrozen) {
return false;
}
switch (coinTypeToSpendFrom) {
case UnspentCoinType.mweb:
return utx.bitcoinAddressRecord.type == SegwitAddresType.mweb;
case UnspentCoinType.nonMweb:
return utx.bitcoinAddressRecord.type != SegwitAddresType.mweb;
case UnspentCoinType.any:
return true;
}
}).toList();
final unconfirmedCoins = availableInputs.where((utx) => utx.confirmations == 0).toList(); final unconfirmedCoins = availableInputs.where((utx) => utx.confirmations == 0).toList();
for (int i = 0; i < availableInputs.length; i++) { for (int i = 0; i < availableInputs.length; i++) {
@ -701,11 +716,13 @@ abstract class ElectrumWalletBase
String? memo, String? memo,
int credentialsAmount = 0, int credentialsAmount = 0,
bool hasSilentPayment = false, bool hasSilentPayment = false,
UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any,
}) async { }) async {
final utxoDetails = _createUTXOS( final utxoDetails = _createUTXOS(
sendAll: true, sendAll: true,
credentialsAmount: credentialsAmount, credentialsAmount: credentialsAmount,
paysToSilentPayment: hasSilentPayment, paysToSilentPayment: hasSilentPayment,
coinTypeToSpendFrom: coinTypeToSpendFrom,
); );
int fee = await calcFee( int fee = await calcFee(
@ -772,12 +789,14 @@ abstract class ElectrumWalletBase
String? memo, String? memo,
bool? useUnconfirmed, bool? useUnconfirmed,
bool hasSilentPayment = false, bool hasSilentPayment = false,
UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any,
}) async { }) async {
final utxoDetails = _createUTXOS( final utxoDetails = _createUTXOS(
sendAll: false, sendAll: false,
credentialsAmount: credentialsAmount, credentialsAmount: credentialsAmount,
inputsCount: inputsCount, inputsCount: inputsCount,
paysToSilentPayment: hasSilentPayment, paysToSilentPayment: hasSilentPayment,
coinTypeToSpendFrom: coinTypeToSpendFrom,
); );
final spendingAllCoins = utxoDetails.availableInputs.length == utxoDetails.utxos.length; final spendingAllCoins = utxoDetails.availableInputs.length == utxoDetails.utxos.length;
@ -797,6 +816,7 @@ abstract class ElectrumWalletBase
inputsCount: utxoDetails.utxos.length + 1, inputsCount: utxoDetails.utxos.length + 1,
memo: memo, memo: memo,
hasSilentPayment: hasSilentPayment, hasSilentPayment: hasSilentPayment,
coinTypeToSpendFrom: coinTypeToSpendFrom,
); );
} }
@ -855,6 +875,7 @@ abstract class ElectrumWalletBase
inputsCount: utxoDetails.utxos.length + 1, inputsCount: utxoDetails.utxos.length + 1,
memo: memo, memo: memo,
useUnconfirmed: useUnconfirmed ?? spendingAllConfirmedCoins, useUnconfirmed: useUnconfirmed ?? spendingAllConfirmedCoins,
coinTypeToSpendFrom: coinTypeToSpendFrom,
); );
} }
@ -862,6 +883,7 @@ abstract class ElectrumWalletBase
outputs, outputs,
feeRate, feeRate,
memo: memo, memo: memo,
coinTypeToSpendFrom: coinTypeToSpendFrom,
); );
if (estimatedSendAll.amount == credentialsAmount) { if (estimatedSendAll.amount == credentialsAmount) {
@ -900,6 +922,7 @@ abstract class ElectrumWalletBase
memo: memo, memo: memo,
useUnconfirmed: useUnconfirmed ?? spendingAllConfirmedCoins, useUnconfirmed: useUnconfirmed ?? spendingAllConfirmedCoins,
hasSilentPayment: hasSilentPayment, hasSilentPayment: hasSilentPayment,
coinTypeToSpendFrom: coinTypeToSpendFrom,
); );
} }
} }
@ -957,6 +980,7 @@ abstract class ElectrumWalletBase
final hasMultiDestination = transactionCredentials.outputs.length > 1; final hasMultiDestination = transactionCredentials.outputs.length > 1;
final sendAll = !hasMultiDestination && transactionCredentials.outputs.first.sendAll; final sendAll = !hasMultiDestination && transactionCredentials.outputs.first.sendAll;
final memo = transactionCredentials.outputs.first.memo; final memo = transactionCredentials.outputs.first.memo;
final coinTypeToSpendFrom = transactionCredentials.coinTypeToSpendFrom;
int credentialsAmount = 0; int credentialsAmount = 0;
bool hasSilentPayment = false; bool hasSilentPayment = false;
@ -1012,6 +1036,7 @@ abstract class ElectrumWalletBase
memo: memo, memo: memo,
credentialsAmount: credentialsAmount, credentialsAmount: credentialsAmount,
hasSilentPayment: hasSilentPayment, hasSilentPayment: hasSilentPayment,
coinTypeToSpendFrom: coinTypeToSpendFrom,
); );
} else { } else {
estimatedTx = await estimateTxForAmount( estimatedTx = await estimateTxForAmount(
@ -1020,6 +1045,7 @@ abstract class ElectrumWalletBase
feeRateInt, feeRateInt,
memo: memo, memo: memo,
hasSilentPayment: hasSilentPayment, hasSilentPayment: hasSilentPayment,
coinTypeToSpendFrom: coinTypeToSpendFrom,
); );
} }

View file

@ -251,7 +251,11 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
_syncTimer?.cancel(); _syncTimer?.cancel();
try { try {
syncStatus = SyncronizingSyncStatus(); syncStatus = SyncronizingSyncStatus();
await subscribeForUpdates(); try {
await subscribeForUpdates();
} catch (e) {
print("failed to subcribe for updates: $e");
}
updateFeeRates(); updateFeeRates();
_feeRatesTimer?.cancel(); _feeRatesTimer?.cancel();
_feeRatesTimer = _feeRatesTimer =
@ -916,6 +920,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
} }
if (!hasMwebInput && !hasMwebOutput) { if (!hasMwebInput && !hasMwebOutput) {
tx.isMweb = false;
return tx; return tx;
} }

View file

@ -21,10 +21,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: archive name: archive
sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.4.10" version: "3.6.1"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -336,10 +336,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: file name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.0.0" version: "7.0.1"
fixnum: fixnum:
dependency: transitive dependency: transitive
description: description:
@ -403,14 +403,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.2"
google_identity_services_web:
dependency: transitive
description:
name: google_identity_services_web
sha256: "5be191523702ba8d7a01ca97c17fca096822ccf246b0a9f11923a6ded06199b6"
url: "https://pub.dev"
source: hosted
version: "0.3.1+4"
googleapis_auth: googleapis_auth:
dependency: transitive dependency: transitive
description: description:
name: googleapis_auth name: googleapis_auth
sha256: af7c3a3edf9d0de2e1e0a77e994fae0a581c525fa7012af4fa0d4a52ed9484da sha256: befd71383a955535060acde8792e7efc11d2fccd03dd1d3ec434e85b68775938
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.1" version: "1.6.0"
graphs: graphs:
dependency: transitive dependency: transitive
description: description:
@ -809,10 +817,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_foundation name: shared_preferences_foundation
sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f sha256: "07e050c7cd39bad516f8d64c455f04508d09df104be326d8c02551590a0d513d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.2" version: "2.5.3"
shared_preferences_linux: shared_preferences_linux:
dependency: transitive dependency: transitive
description: description:
@ -1031,10 +1039,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: xdg_directories name: xdg_directories
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.4" version: "1.1.0"
yaml: yaml:
dependency: transitive dependency: transitive
description: description:

View file

@ -0,0 +1 @@
enum UnspentCoinType { mweb, nonMweb, any }

View file

@ -106,34 +106,33 @@ class CWBitcoin extends Bitcoin {
} }
@override @override
Object createBitcoinTransactionCredentials(List<Output> outputs, Object createBitcoinTransactionCredentials(
{required TransactionPriority priority, int? feeRate}) { List<Output> outputs, {
required TransactionPriority priority,
int? feeRate,
UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any,
}) {
final bitcoinFeeRate = final bitcoinFeeRate =
priority == BitcoinTransactionPriority.custom && feeRate != null ? feeRate : null; priority == BitcoinTransactionPriority.custom && feeRate != null ? feeRate : null;
return BitcoinTransactionCredentials( return BitcoinTransactionCredentials(
outputs outputs
.map((out) => OutputInfo( .map((out) => OutputInfo(
fiatAmount: out.fiatAmount, fiatAmount: out.fiatAmount,
cryptoAmount: out.cryptoAmount, cryptoAmount: out.cryptoAmount,
address: out.address, address: out.address,
note: out.note, note: out.note,
sendAll: out.sendAll, sendAll: out.sendAll,
extractedAddress: out.extractedAddress, extractedAddress: out.extractedAddress,
isParsedAddress: out.isParsedAddress, isParsedAddress: out.isParsedAddress,
formattedCryptoAmount: out.formattedCryptoAmount, formattedCryptoAmount: out.formattedCryptoAmount,
memo: out.memo)) memo: out.memo))
.toList(), .toList(),
priority: priority as BitcoinTransactionPriority, priority: priority as BitcoinTransactionPriority,
feeRate: bitcoinFeeRate); feeRate: bitcoinFeeRate,
coinTypeToSpendFrom: coinTypeToSpendFrom,
);
} }
@override
Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs,
{TransactionPriority? priority, required int feeRate}) =>
BitcoinTransactionCredentials(outputs,
priority: priority != null ? priority as BitcoinTransactionPriority : null,
feeRate: feeRate);
@override @override
@computed @computed
List<ElectrumSubAddress> getSubAddresses(Object wallet) { List<ElectrumSubAddress> getSubAddresses(Object wallet) {
@ -205,9 +204,20 @@ class CWBitcoin extends Bitcoin {
(priority as BitcoinTransactionPriority).labelWithRate(rate, customRate); (priority as BitcoinTransactionPriority).labelWithRate(rate, customRate);
@override @override
List<BitcoinUnspent> getUnspents(Object wallet) { List<BitcoinUnspent> getUnspents(Object wallet,
{UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any}) {
final bitcoinWallet = wallet as ElectrumWallet; final bitcoinWallet = wallet as ElectrumWallet;
return bitcoinWallet.unspentCoins; return bitcoinWallet.unspentCoins.where((element) {
switch(coinTypeToSpendFrom) {
case UnspentCoinType.mweb:
return element.bitcoinAddressRecord.type == SegwitAddresType.mweb;
case UnspentCoinType.nonMweb:
return element.bitcoinAddressRecord.type != SegwitAddresType.mweb;
case UnspentCoinType.any:
return true;
}
}).toList();
} }
Future<void> updateUnspents(Object wallet) async { Future<void> updateUnspents(Object wallet) async {

View file

@ -167,6 +167,7 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_i
import 'package:cake_wallet/view_model/wallet_list/wallet_edit_view_model.dart'; import 'package:cake_wallet/view_model/wallet_list/wallet_edit_view_model.dart';
import 'package:cake_wallet/view_model/wallet_restore_choose_derivation_view_model.dart'; import 'package:cake_wallet/view_model/wallet_restore_choose_derivation_view_model.dart';
import 'package:cw_core/nano_account.dart'; import 'package:cw_core/nano_account.dart';
import 'package:cw_core/unspent_coin_type.dart';
import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_service.dart'; import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/transaction_info.dart';
@ -725,8 +726,8 @@ Future<void> setup({
getIt.get<SendTemplateStore>(), getIt.get<SendTemplateStore>(),
getIt.get<FiatConversionStore>())); getIt.get<FiatConversionStore>()));
getIt.registerFactory<SendViewModel>( getIt.registerFactoryParam<SendViewModel, UnspentCoinType?, void>(
() => SendViewModel( (coinTypeToSpendFrom, _) => SendViewModel(
getIt.get<AppStore>(), getIt.get<AppStore>(),
getIt.get<SendTemplateViewModel>(), getIt.get<SendTemplateViewModel>(),
getIt.get<FiatConversionStore>(), getIt.get<FiatConversionStore>(),
@ -734,12 +735,13 @@ Future<void> setup({
getIt.get<ContactListViewModel>(), getIt.get<ContactListViewModel>(),
_transactionDescriptionBox, _transactionDescriptionBox,
getIt.get<AppStore>().wallet!.isHardwareWallet ? getIt.get<LedgerViewModel>() : null, getIt.get<AppStore>().wallet!.isHardwareWallet ? getIt.get<LedgerViewModel>() : null,
coinTypeToSpendFrom: coinTypeToSpendFrom ?? UnspentCoinType.any,
), ),
); );
getIt.registerFactoryParam<SendPage, PaymentRequest?, void>( getIt.registerFactoryParam<SendPage, PaymentRequest?, UnspentCoinType?>(
(PaymentRequest? initialPaymentRequest, _) => SendPage( (PaymentRequest? initialPaymentRequest, coinTypeToSpendFrom) => SendPage(
sendViewModel: getIt.get<SendViewModel>(), sendViewModel: getIt.get<SendViewModel>(param1: coinTypeToSpendFrom),
authService: getIt.get<AuthService>(), authService: getIt.get<AuthService>(),
initialPaymentRequest: initialPaymentRequest, initialPaymentRequest: initialPaymentRequest,
)); ));
@ -1215,14 +1217,21 @@ Future<void> setup({
getIt.registerFactory(() => SupportOtherLinksPage(getIt.get<SupportViewModel>())); getIt.registerFactory(() => SupportOtherLinksPage(getIt.get<SupportViewModel>()));
getIt.registerFactory(() { getIt.registerFactoryParam<UnspentCoinsListViewModel, UnspentCoinType?, void>(
(coinTypeToSpendFrom, _) {
final wallet = getIt.get<AppStore>().wallet; final wallet = getIt.get<AppStore>().wallet;
return UnspentCoinsListViewModel(wallet: wallet!, unspentCoinsInfo: _unspentCoinsInfoSource); return UnspentCoinsListViewModel(
wallet: wallet!,
unspentCoinsInfo: _unspentCoinsInfoSource,
coinTypeToSpendFrom: coinTypeToSpendFrom ?? UnspentCoinType.any,
);
}); });
getIt.registerFactory(() => getIt.registerFactoryParam<UnspentCoinsListPage, UnspentCoinType?, void>(
UnspentCoinsListPage(unspentCoinsListViewModel: getIt.get<UnspentCoinsListViewModel>())); (coinTypeToSpendFrom, _) => UnspentCoinsListPage(
unspentCoinsListViewModel:
getIt.get<UnspentCoinsListViewModel>(param1: coinTypeToSpendFrom)));
getIt.registerFactoryParam<UnspentCoinsDetailsViewModel, UnspentCoinsItem, getIt.registerFactoryParam<UnspentCoinsDetailsViewModel, UnspentCoinsItem,
UnspentCoinsListViewModel>( UnspentCoinsListViewModel>(

View file

@ -120,6 +120,7 @@ import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/nano_account.dart'; import 'package:cw_core/nano_account.dart';
import 'package:cw_core/node.dart'; import 'package:cw_core/node.dart';
import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/unspent_coin_type.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@ -184,7 +185,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
final type = settings.arguments as WalletType; final type = settings.arguments as WalletType;
final walletGroupsDisplayVM = getIt.get<WalletGroupsDisplayViewModel>(param1: type); final walletGroupsDisplayVM = getIt.get<WalletGroupsDisplayViewModel>(param1: type);
return CupertinoPageRoute<void>(builder: (_) => WalletGroupsDisplayPage(walletGroupsDisplayVM)); return CupertinoPageRoute<void>(
builder: (_) => WalletGroupsDisplayPage(walletGroupsDisplayVM));
case Routes.newWallet: case Routes.newWallet:
final args = settings.arguments as NewWalletArguments; final args = settings.arguments as NewWalletArguments;
@ -348,13 +350,17 @@ Route<dynamic> createRoute(RouteSettings settings) {
settings: settings, builder: (_) => getIt.get<DashboardPage>()); settings: settings, builder: (_) => getIt.get<DashboardPage>());
case Routes.send: case Routes.send:
final initialPaymentRequest = settings.arguments as PaymentRequest?; final args = settings.arguments as Map<String, dynamic>?;
final initialPaymentRequest = args?['paymentRequest'] as PaymentRequest?;
final coinTypeToSpendFrom = args?['coinTypeToSpendFrom'] as UnspentCoinType?;
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
fullscreenDialog: true, fullscreenDialog: true,
builder: (_) => getIt.get<SendPage>( builder: (_) => getIt.get<SendPage>(
param1: initialPaymentRequest, param1: initialPaymentRequest,
)); param2: coinTypeToSpendFrom,
),
);
case Routes.sendTemplate: case Routes.sendTemplate:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
@ -604,7 +610,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
fullscreenDialog: true, builder: (_) => getIt.get<SupportOtherLinksPage>()); fullscreenDialog: true, builder: (_) => getIt.get<SupportOtherLinksPage>());
case Routes.unspentCoinsList: case Routes.unspentCoinsList:
return MaterialPageRoute<void>(builder: (_) => getIt.get<UnspentCoinsListPage>()); final coinTypeToSpendFrom = settings.arguments as UnspentCoinType?;
return MaterialPageRoute<void>(
builder: (_) => getIt.get<UnspentCoinsListPage>(param1: coinTypeToSpendFrom));
case Routes.unspentCoinsDetails: case Routes.unspentCoinsDetails:
final args = settings.arguments as List; final args = settings.arguments as List;
@ -778,7 +786,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.walletGroupDescription: case Routes.walletGroupDescription:
final walletType = settings.arguments as WalletType; final walletType = settings.arguments as WalletType;
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
builder: (_) => WalletGroupDescriptionPage( builder: (_) => WalletGroupDescriptionPage(
selectedWalletType: walletType, selectedWalletType: walletType,

View file

@ -17,13 +17,15 @@ import 'package:cake_wallet/src/widgets/standard_switch.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart'; import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart'; import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart'; import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/utils/feature_flag.dart'; import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:flutter/cupertino.dart'; import 'package:cw_core/unspent_coin_type.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -837,216 +839,300 @@ class BalanceRowWidget extends StatelessWidget {
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor, color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
), ),
child: Container( child: Container(
margin: const EdgeInsets.only(top: 0, left: 24, right: 8, bottom: 16),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Stack( Container(
children: [ margin: const EdgeInsets.only(top: 0, left: 24, right: 8, bottom: 16),
if (currency == CryptoCurrency.ltc) child: Stack(
Row( children: [
mainAxisAlignment: MainAxisAlignment.end, if (currency == CryptoCurrency.ltc)
children: [ Row(
Container( mainAxisAlignment: MainAxisAlignment.end,
padding: EdgeInsets.only(right: 16, top: 16), children: [
child: Column( Container(
children: [ padding: EdgeInsets.only(right: 16, top: 16),
Container( child: Column(
decoration: BoxDecoration( children: [
color: Colors.white, Container(
shape: BoxShape.circle, decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: ImageIcon(
AssetImage('assets/images/mweb_logo.png'),
color: Color.fromARGB(255, 11, 70, 129),
size: 40,
),
), ),
child: ImageIcon( const SizedBox(height: 10),
AssetImage('assets/images/mweb_logo.png'), Text(
color: Color.fromARGB(255, 11, 70, 129), 'MWEB',
size: 40, style: TextStyle(
fontSize: 15,
fontFamily: 'Lato',
fontWeight: FontWeight.w800,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.assetTitleColor,
height: 1,
),
),
],
),
),
],
),
if (hasSecondAvailableBalance)
Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 24),
Text(
'${secondAvailableBalanceLabel}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.labelTextColor,
height: 1,
), ),
), ),
const SizedBox(height: 10), SizedBox(height: 8),
Text( AutoSizeText(
'MWEB', secondAvailableBalance,
style: TextStyle( style: TextStyle(
fontSize: 15, fontSize: 20,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w800, fontWeight: FontWeight.w400,
color: Theme.of(context) color: Theme.of(context)
.extension<BalancePageTheme>()! .extension<BalancePageTheme>()!
.assetTitleColor, .assetTitleColor,
height: 1, height: 1,
), ),
maxLines: 1,
textAlign: TextAlign.center,
), ),
SizedBox(height: 4),
if (!isTestnet)
Text(
'${secondAvailableFiatBalance}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.textColor,
height: 1,
),
),
], ],
), ),
), ],
], ),
), ],
if (hasSecondAvailableBalance) ),
Row( ),
children: [ Container(
Column( margin: const EdgeInsets.only(top: 0, left: 24, right: 8, bottom: 16),
crossAxisAlignment: CrossAxisAlignment.start, child: Stack(
children: [ children: [
SizedBox(height: 24), if (hasSecondAdditionalBalance)
Text( Row(
'${secondAvailableBalanceLabel}', children: [
textAlign: TextAlign.center, Column(
style: TextStyle( crossAxisAlignment: CrossAxisAlignment.start,
fontSize: 12, children: [
fontFamily: 'Lato', SizedBox(height: 24),
fontWeight: FontWeight.w400,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.labelTextColor,
height: 1,
),
),
SizedBox(height: 8),
AutoSizeText(
secondAvailableBalance,
style: TextStyle(
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.assetTitleColor,
height: 1,
),
maxLines: 1,
textAlign: TextAlign.center,
),
SizedBox(height: 4),
if (!isTestnet)
Text( Text(
'${secondAvailableFiatBalance}', '${secondAdditionalBalanceLabel}',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: color: Theme.of(context)
Theme.of(context).extension<BalancePageTheme>()!.textColor, .extension<BalancePageTheme>()!
.labelTextColor,
height: 1, height: 1,
), ),
), ),
], SizedBox(height: 8),
), AutoSizeText(
], secondAdditionalBalance,
),
],
),
Stack(
children: [
if (hasSecondAdditionalBalance)
Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 24),
Text(
'${secondAdditionalBalanceLabel}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.labelTextColor,
height: 1,
),
),
SizedBox(height: 8),
AutoSizeText(
secondAdditionalBalance,
style: TextStyle(
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.assetTitleColor,
height: 1,
),
maxLines: 1,
textAlign: TextAlign.center,
),
SizedBox(height: 4),
if (!isTestnet)
Text(
'${secondAdditionalFiatBalance}',
textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 20,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: color: Theme.of(context)
Theme.of(context).extension<BalancePageTheme>()!.textColor, .extension<BalancePageTheme>()!
.assetTitleColor,
height: 1, height: 1,
), ),
maxLines: 1,
textAlign: TextAlign.center,
), ),
], SizedBox(height: 4),
), if (!isTestnet)
], Text(
), '${secondAdditionalFiatBalance}',
// TODO: smarter peg in / out buttons textAlign: TextAlign.center,
// if (currency == CryptoCurrency.ltc) style: TextStyle(
// Row( fontSize: 12,
// mainAxisAlignment: MainAxisAlignment.end, fontFamily: 'Lato',
// children: [ fontWeight: FontWeight.w400,
// Container( color: Theme.of(context)
// margin: EdgeInsets.only(top: 24, right: 8), .extension<BalancePageTheme>()!
// child: ElevatedButton( .textColor,
// style: ElevatedButton.styleFrom( height: 1,
// backgroundColor: Theme.of(context).highlightColor, ),
// ), ),
// onPressed: () { ],
// final mwebAddress = ),
// bitcoin!.getUnusedMwebAddress(dashboardViewModel.wallet); ],
// if (mwebAddress == null) return; ),
// final paymentRequest = ],
// PaymentRequest.fromUri(Uri.parse("litecoin:${mwebAddress}")); ),
// Navigator.of(context)
// .pushNamed(Routes.send, arguments: paymentRequest);
// },
// child: Container(
// color: Colors.transparent,
// margin: EdgeInsets.all(4),
// child: Column(
// mainAxisSize: MainAxisSize.max,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: <Widget>[
// Container(
// alignment: Alignment.center,
// decoration: BoxDecoration(shape: BoxShape.circle),
// child: Image.asset(
// 'assets/images/received.png',
// color: Theme.of(context)
// .extension<BalancePageTheme>()!
// .balanceAmountColor,
// width: 64,
// height: 32,
// ),
// ),
// SizedBox(height: 4),
// Text(
// S.of(context).litecoin_mweb_pegin,
// style: TextStyle(
// fontSize: 10,
// color: Theme.of(context)
// .extension<DashboardPageTheme>()!
// .cardTextColor),
// )
// ],
// ),
// ),
// ),
// ),
// ],
// ),
],
), ),
IntrinsicHeight(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Semantics(
label: S.of(context).litecoin_mweb_pegin,
child: OutlinedButton(
onPressed: () {
final mwebAddress =
bitcoin!.getUnusedMwebAddress(dashboardViewModel.wallet);
PaymentRequest? paymentRequest = null;
if ((mwebAddress?.isNotEmpty ?? false)) {
paymentRequest =
PaymentRequest.fromUri(Uri.parse("litecoin:${mwebAddress}"));
}
Navigator.pushNamed(
context,
Routes.send,
arguments: {
'paymentRequest': paymentRequest,
'coinTypeToSpendFrom': UnspentCoinType.nonMweb,
},
);
},
style: OutlinedButton.styleFrom(
backgroundColor: Theme.of(context)
.extension<SendPageTheme>()!
.textFieldButtonIconColor
.withAlpha(50),
side: BorderSide(color: Colors.grey.shade400, width: 0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
child: Container(
padding: EdgeInsets.symmetric(vertical: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
height: 30,
width: 30,
'assets/images/received.png',
color: Theme.of(context)
.extension<BalancePageTheme>()!
.balanceAmountColor,
),
const SizedBox(width: 8),
Text(
S.of(context).litecoin_mweb_pegin,
style: TextStyle(
color: Theme.of(context)
.extension<BalancePageTheme>()!
.assetTitleColor,
),
),
],
),
),
),
),
),
SizedBox(width: 32),
Expanded(
child: Semantics(
label: S.of(context).litecoin_mweb_pegout,
child: OutlinedButton(
onPressed: () {
final litecoinAddress =
bitcoin!.getAddress(dashboardViewModel.wallet);
PaymentRequest? paymentRequest = null;
if (litecoinAddress.isNotEmpty) {
paymentRequest = PaymentRequest.fromUri(
Uri.parse("litecoin:${litecoinAddress}"));
}
Navigator.pushNamed(
context,
Routes.send,
arguments: {
'paymentRequest': paymentRequest,
'coinTypeToSpendFrom': UnspentCoinType.mweb,
},
);
},
style: OutlinedButton.styleFrom(
backgroundColor: Theme.of(context)
.extension<SendPageTheme>()!
.textFieldButtonIconColor
.withAlpha(50),
side: BorderSide(color: Colors.grey.shade400, width: 0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
child: Container(
padding: EdgeInsets.symmetric(vertical: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
height: 30,
width: 30,
'assets/images/upload.png',
color: Theme.of(context)
.extension<BalancePageTheme>()!
.balanceAmountColor,
),
const SizedBox(width: 8),
Text(
S.of(context).litecoin_mweb_pegout,
style: TextStyle(
color: Theme.of(context)
.extension<BalancePageTheme>()!
.assetTitleColor,
),
),
],
),
),
),
),
),
],
),
),
),
SizedBox(height: 16),
], ],
), ),
), ),

View file

@ -14,7 +14,6 @@ import 'package:cake_wallet/view_model/send/output.dart';
import 'package:cw_core/transaction_priority.dart'; import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart'; import 'package:keyboard_actions/keyboard_actions.dart';
@ -373,7 +372,10 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
padding: EdgeInsets.only(top: 6), padding: EdgeInsets.only(top: 6),
child: GestureDetector( child: GestureDetector(
key: ValueKey('send_page_unspent_coin_button_key'), key: ValueKey('send_page_unspent_coin_button_key'),
onTap: () => Navigator.of(context).pushNamed(Routes.unspentCoinsList), onTap: () => Navigator.of(context).pushNamed(
Routes.unspentCoinsList,
arguments: widget.sendViewModel.coinTypeToSpendFrom,
),
child: Container( child: Container(
color: Colors.transparent, color: Colors.transparent,
child: Row( child: Row(

View file

@ -65,15 +65,16 @@ class LinkViewModel {
if (isNanoGptLink) { if (isNanoGptLink) {
switch (currentLink?.authority ?? '') { switch (currentLink?.authority ?? '') {
case "exchange": case "exchange":
case "send":
return PaymentRequest.fromUri(currentLink); return PaymentRequest.fromUri(currentLink);
case "send":
return {"paymentRequest": PaymentRequest.fromUri(currentLink)};
case "buy": case "buy":
return true; return true;
} }
} }
if (_isValidPaymentUri) { if (_isValidPaymentUri) {
return PaymentRequest.fromUri(currentLink); return {"paymentRequest": PaymentRequest.fromUri(currentLink)};
} }
return null; return null;

View file

@ -20,6 +20,7 @@ import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cw_core/exceptions.dart'; import 'package:cw_core/exceptions.dart';
import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/transaction_priority.dart'; import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/unspent_coin_type.dart';
import 'package:cake_wallet/view_model/send/output.dart'; import 'package:cake_wallet/view_model/send/output.dart';
import 'package:cake_wallet/view_model/send/send_template_view_model.dart'; import 'package:cake_wallet/view_model/send/send_template_view_model.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
@ -67,8 +68,9 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
this.balanceViewModel, this.balanceViewModel,
this.contactListViewModel, this.contactListViewModel,
this.transactionDescriptionBox, this.transactionDescriptionBox,
this.ledgerViewModel, this.ledgerViewModel, {
) : state = InitialExecutionState(), this.coinTypeToSpendFrom = UnspentCoinType.any,
}) : state = InitialExecutionState(),
currencies = appStore.wallet!.balance.keys.toList(), currencies = appStore.wallet!.balance.keys.toList(),
selectedCryptoCurrency = appStore.wallet!.currency, selectedCryptoCurrency = appStore.wallet!.currency,
hasMultipleTokens = isEVMCompatibleChain(appStore.wallet!.type) || hasMultipleTokens = isEVMCompatibleChain(appStore.wallet!.type) ||
@ -97,6 +99,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
ObservableList<Output> outputs; ObservableList<Output> outputs;
final UnspentCoinType coinTypeToSpendFrom;
@action @action
void addOutput() { void addOutput() {
outputs outputs
@ -217,7 +221,14 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
PendingTransaction? pendingTransaction; PendingTransaction? pendingTransaction;
@computed @computed
String get balance => wallet.balance[selectedCryptoCurrency]!.formattedFullAvailableBalance; String get balance {
if (coinTypeToSpendFrom == UnspentCoinType.mweb) {
return balanceViewModel.balances.values.first.secondAvailableBalance;
} else if (coinTypeToSpendFrom == UnspentCoinType.nonMweb) {
return balanceViewModel.balances.values.first.availableBalance;
}
return wallet.balance[selectedCryptoCurrency]!.formattedFullAvailableBalance;
}
@computed @computed
bool get isFiatDisabled => balanceViewModel.isFiatDisabled; bool get isFiatDisabled => balanceViewModel.isFiatDisabled;
@ -494,8 +505,12 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.litecoin: case WalletType.litecoin:
case WalletType.bitcoinCash: case WalletType.bitcoinCash:
return bitcoin!.createBitcoinTransactionCredentials(outputs, return bitcoin!.createBitcoinTransactionCredentials(
priority: priority!, feeRate: customBitcoinFeeRate); outputs,
priority: priority!,
feeRate: customBitcoinFeeRate,
coinTypeToSpendFrom: coinTypeToSpendFrom,
);
case WalletType.monero: case WalletType.monero:
return monero! return monero!

View file

@ -3,6 +3,7 @@ import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:cake_wallet/utils/exception_handler.dart';
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart'; import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart';
import 'package:cake_wallet/wownero/wownero.dart'; import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cw_core/unspent_coin_type.dart';
import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/unspent_transaction_output.dart'; import 'package:cw_core/unspent_transaction_output.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
@ -16,9 +17,11 @@ part 'unspent_coins_list_view_model.g.dart';
class UnspentCoinsListViewModel = UnspentCoinsListViewModelBase with _$UnspentCoinsListViewModel; class UnspentCoinsListViewModel = UnspentCoinsListViewModelBase with _$UnspentCoinsListViewModel;
abstract class UnspentCoinsListViewModelBase with Store { abstract class UnspentCoinsListViewModelBase with Store {
UnspentCoinsListViewModelBase( UnspentCoinsListViewModelBase({
{required this.wallet, required Box<UnspentCoinsInfo> unspentCoinsInfo}) required this.wallet,
: _unspentCoinsInfo = unspentCoinsInfo, required Box<UnspentCoinsInfo> unspentCoinsInfo,
this.coinTypeToSpendFrom = UnspentCoinType.any,
}) : _unspentCoinsInfo = unspentCoinsInfo,
_items = ObservableList<UnspentCoinsItem>() { _items = ObservableList<UnspentCoinsItem>() {
_updateUnspentCoinsInfo(); _updateUnspentCoinsInfo();
_updateUnspents(); _updateUnspents();
@ -26,6 +29,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
WalletBase wallet; WalletBase wallet;
final Box<UnspentCoinsInfo> _unspentCoinsInfo; final Box<UnspentCoinsInfo> _unspentCoinsInfo;
final UnspentCoinType coinTypeToSpendFrom;
@observable @observable
ObservableList<UnspentCoinsItem> _items; ObservableList<UnspentCoinsItem> _items;
@ -103,7 +107,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.litecoin: case WalletType.litecoin:
case WalletType.bitcoinCash: case WalletType.bitcoinCash:
return bitcoin!.getUnspents(wallet); return bitcoin!.getUnspents(wallet, coinTypeToSpendFrom: coinTypeToSpendFrom);
default: default:
return List.empty(); return List.empty();
} }

View file

@ -87,6 +87,7 @@ import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/receive_page_option.dart'; import 'package:cw_core/receive_page_option.dart';
import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/transaction_priority.dart'; import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/unspent_coin_type.dart';
import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/unspent_transaction_output.dart'; import 'package:cw_core/unspent_transaction_output.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
@ -94,6 +95,7 @@ import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_service.dart'; import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:cw_core/get_height_by_date.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:ledger_flutter/ledger_flutter.dart'; import 'package:ledger_flutter/ledger_flutter.dart';
import 'package:blockchain_utils/blockchain_utils.dart'; import 'package:blockchain_utils/blockchain_utils.dart';
@ -108,7 +110,6 @@ import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
import 'package:cw_bitcoin/bitcoin_receive_page_option.dart'; import 'package:cw_bitcoin/bitcoin_receive_page_option.dart';
import 'package:cw_bitcoin/bitcoin_wallet.dart'; import 'package:cw_bitcoin/bitcoin_wallet.dart';
import 'package:cw_bitcoin/electrum_wallet.dart'; import 'package:cw_bitcoin/electrum_wallet.dart';
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
import 'package:cw_bitcoin/bitcoin_unspent.dart'; import 'package:cw_bitcoin/bitcoin_unspent.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart'; import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
@ -119,8 +120,6 @@ import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart'; import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
import 'package:cw_bitcoin/litecoin_wallet_service.dart'; import 'package:cw_bitcoin/litecoin_wallet_service.dart';
import 'package:cw_bitcoin/litecoin_wallet.dart'; import 'package:cw_bitcoin/litecoin_wallet.dart';
import 'package:cw_core/get_height_by_date.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:cw_bitcoin/bitcoin_hardware_wallet_service.dart'; import 'package:cw_bitcoin/bitcoin_hardware_wallet_service.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
"""; """;
@ -166,8 +165,7 @@ abstract class Bitcoin {
int getFeeRate(Object wallet, TransactionPriority priority); int getFeeRate(Object wallet, TransactionPriority priority);
Future<void> generateNewAddress(Object wallet, String label); Future<void> generateNewAddress(Object wallet, String label);
Future<void> updateAddress(Object wallet,String address, String label); Future<void> updateAddress(Object wallet,String address, String label);
Object createBitcoinTransactionCredentials(List<Output> outputs, {required TransactionPriority priority, int? feeRate}); Object createBitcoinTransactionCredentials(List<Output> outputs, {required TransactionPriority priority, int? feeRate, UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any});
Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs, {TransactionPriority? priority, required int feeRate});
String getAddress(Object wallet); String getAddress(Object wallet);
List<ElectrumSubAddress> getSilentPaymentAddresses(Object wallet); List<ElectrumSubAddress> getSilentPaymentAddresses(Object wallet);
@ -181,7 +179,7 @@ abstract class Bitcoin {
int formatterStringDoubleToBitcoinAmount(String amount); int formatterStringDoubleToBitcoinAmount(String amount);
String bitcoinTransactionPriorityWithLabel(TransactionPriority priority, int rate, {int? customRate}); String bitcoinTransactionPriorityWithLabel(TransactionPriority priority, int rate, {int? customRate});
List<Unspent> getUnspents(Object wallet); List<Unspent> getUnspents(Object wallet, {UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any});
Future<void> updateUnspents(Object wallet); Future<void> updateUnspents(Object wallet);
WalletService createBitcoinWalletService( WalletService createBitcoinWalletService(
Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan, bool isDirect); Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan, bool isDirect);