mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-09-30 02:11:22 +00:00
commit
eae00866c3
32 changed files with 787 additions and 582 deletions
|
@ -2,6 +2,7 @@ import 'package:dart_numerics/dart_numerics.dart';
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
|
||||||
part '../type_adaptors/transactions_model.g.dart';
|
part '../type_adaptors/transactions_model.g.dart';
|
||||||
|
|
||||||
|
@ -220,14 +221,16 @@ class Transaction {
|
||||||
(DateTime.now().millisecondsSinceEpoch ~/ 1000),
|
(DateTime.now().millisecondsSinceEpoch ~/ 1000),
|
||||||
txType: json['txType'] as String,
|
txType: json['txType'] as String,
|
||||||
amount: (Decimal.parse(json["amount"].toString()) *
|
amount: (Decimal.parse(json["amount"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(Coin
|
||||||
|
.firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt(),
|
.toInt(),
|
||||||
aliens: [],
|
aliens: [],
|
||||||
worthNow: json['worthNow'] as String,
|
worthNow: json['worthNow'] as String,
|
||||||
worthAtBlockTimestamp: json['worthAtBlockTimestamp'] as String? ?? "0",
|
worthAtBlockTimestamp: json['worthAtBlockTimestamp'] as String? ?? "0",
|
||||||
fees: (Decimal.parse(json["fees"].toString()) *
|
fees: (Decimal.parse(json["fees"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(Coin
|
||||||
|
.firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt(),
|
.toInt(),
|
||||||
inputSize: json['inputSize'] as int? ?? 0,
|
inputSize: json['inputSize'] as int? ?? 0,
|
||||||
|
@ -386,7 +389,8 @@ class Output {
|
||||||
scriptpubkeyType: json['scriptPubKey']['type'] as String?,
|
scriptpubkeyType: json['scriptPubKey']['type'] as String?,
|
||||||
scriptpubkeyAddress: address,
|
scriptpubkeyAddress: address,
|
||||||
value: (Decimal.parse(json["value"].toString()) *
|
value: (Decimal.parse(json["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(Coin
|
||||||
|
.firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt(),
|
.toInt(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -155,7 +155,7 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
|
||||||
final date = await showRoundedDatePicker(
|
final date = await showRoundedDatePicker(
|
||||||
context: context,
|
context: context,
|
||||||
initialDate: DateTime.now(),
|
initialDate: DateTime.now(),
|
||||||
height: height * 0.5,
|
height: height / 3.2,
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
primarySwatch: Util.createMaterialColor(fetchedColor),
|
primarySwatch: Util.createMaterialColor(fetchedColor),
|
||||||
),
|
),
|
||||||
|
|
|
@ -342,6 +342,9 @@ class _ConfirmChangeNowSendViewState
|
||||||
localeServiceChangeNotifierProvider
|
localeServiceChangeNotifierProvider
|
||||||
.select((value) => value.locale),
|
.select((value) => value.locale),
|
||||||
),
|
),
|
||||||
|
ref.watch(
|
||||||
|
managerProvider.select((value) => value.coin),
|
||||||
|
),
|
||||||
)} ${ref.watch(
|
)} ${ref.watch(
|
||||||
managerProvider.select((value) => value.coin),
|
managerProvider.select((value) => value.coin),
|
||||||
).ticker}",
|
).ticker}",
|
||||||
|
@ -382,6 +385,9 @@ class _ConfirmChangeNowSendViewState
|
||||||
localeServiceChangeNotifierProvider
|
localeServiceChangeNotifierProvider
|
||||||
.select((value) => value.locale),
|
.select((value) => value.locale),
|
||||||
),
|
),
|
||||||
|
ref.watch(
|
||||||
|
managerProvider.select((value) => value.coin),
|
||||||
|
),
|
||||||
)} ${ref.watch(
|
)} ${ref.watch(
|
||||||
managerProvider.select((value) => value.coin),
|
managerProvider.select((value) => value.coin),
|
||||||
).ticker}",
|
).ticker}",
|
||||||
|
@ -563,13 +569,12 @@ class _ConfirmChangeNowSendViewState
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
"${Format.satoshiAmountToPrettyString(
|
"${Format.satoshiAmountToPrettyString(transactionInfo["recipientAmt"] as int, ref.watch(
|
||||||
transactionInfo["recipientAmt"] as int,
|
localeServiceChangeNotifierProvider
|
||||||
ref.watch(
|
.select((value) => value.locale),
|
||||||
localeServiceChangeNotifierProvider
|
), ref.watch(
|
||||||
.select((value) => value.locale),
|
managerProvider.select((value) => value.coin),
|
||||||
),
|
))} ${ref.watch(
|
||||||
)} ${ref.watch(
|
|
||||||
managerProvider.select((value) => value.coin),
|
managerProvider.select((value) => value.coin),
|
||||||
).ticker}",
|
).ticker}",
|
||||||
style: STextStyles.itemSubtitle12(context),
|
style: STextStyles.itemSubtitle12(context),
|
||||||
|
@ -597,13 +602,12 @@ class _ConfirmChangeNowSendViewState
|
||||||
style: STextStyles.smallMed12(context),
|
style: STextStyles.smallMed12(context),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"${Format.satoshiAmountToPrettyString(
|
"${Format.satoshiAmountToPrettyString(transactionInfo["fee"] as int, ref.watch(
|
||||||
transactionInfo["fee"] as int,
|
localeServiceChangeNotifierProvider
|
||||||
ref.watch(
|
.select((value) => value.locale),
|
||||||
localeServiceChangeNotifierProvider
|
), ref.watch(
|
||||||
.select((value) => value.locale),
|
managerProvider.select((value) => value.coin),
|
||||||
),
|
))} ${ref.watch(
|
||||||
)} ${ref.watch(
|
|
||||||
managerProvider.select((value) => value.coin),
|
managerProvider.select((value) => value.coin),
|
||||||
).ticker}",
|
).ticker}",
|
||||||
style: STextStyles.itemSubtitle12(context),
|
style: STextStyles.itemSubtitle12(context),
|
||||||
|
@ -685,14 +689,12 @@ class _ConfirmChangeNowSendViewState
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"${Format.satoshiAmountToPrettyString(
|
"${Format.satoshiAmountToPrettyString((transactionInfo["fee"] as int) + (transactionInfo["recipientAmt"] as int), ref.watch(
|
||||||
(transactionInfo["fee"] as int) +
|
localeServiceChangeNotifierProvider
|
||||||
(transactionInfo["recipientAmt"] as int),
|
.select((value) => value.locale),
|
||||||
ref.watch(
|
), ref.watch(
|
||||||
localeServiceChangeNotifierProvider
|
managerProvider.select((value) => value.coin),
|
||||||
.select((value) => value.locale),
|
))} ${ref.watch(
|
||||||
),
|
|
||||||
)} ${ref.watch(
|
|
||||||
managerProvider.select((value) => value.coin),
|
managerProvider.select((value) => value.coin),
|
||||||
).ticker}",
|
).ticker}",
|
||||||
style: STextStyles.itemSubtitle12(context).copyWith(
|
style: STextStyles.itemSubtitle12(context).copyWith(
|
||||||
|
|
|
@ -1281,28 +1281,30 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
||||||
condition: isDesktop,
|
condition: isDesktop,
|
||||||
builder: (child) => MouseRegion(
|
builder: (child) => MouseRegion(
|
||||||
cursor: SystemMouseCursors.click,
|
cursor: SystemMouseCursors.click,
|
||||||
child: RoundedContainer(
|
child: child,
|
||||||
padding: const EdgeInsets.all(6),
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.buttonBackSecondary,
|
|
||||||
radiusMultiplier: 0.75,
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
child: GestureDetector(
|
child: RoundedContainer(
|
||||||
onTap: () async {
|
padding: isDesktop
|
||||||
await _swap();
|
? const EdgeInsets.all(6)
|
||||||
},
|
: const EdgeInsets.all(2),
|
||||||
child: Padding(
|
color: Theme.of(context)
|
||||||
padding: const EdgeInsets.all(4),
|
.extension<StackColors>()!
|
||||||
child: SvgPicture.asset(
|
.buttonBackSecondary,
|
||||||
Assets.svg.swap,
|
radiusMultiplier: 0.75,
|
||||||
width: 20,
|
child: GestureDetector(
|
||||||
height: 20,
|
onTap: () async {
|
||||||
color: Theme.of(context)
|
await _swap();
|
||||||
.extension<StackColors>()!
|
},
|
||||||
.accentColorDark,
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(4),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.svg.swap,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.accentColorDark,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1310,7 +1312,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: isDesktop ? 10 : 4,
|
height: isDesktop ? 10 : 7,
|
||||||
),
|
),
|
||||||
ExchangeTextField(
|
ExchangeTextField(
|
||||||
focusNode: _receiveFocusNode,
|
focusNode: _receiveFocusNode,
|
||||||
|
|
|
@ -7,8 +7,6 @@ import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart
|
||||||
import 'package:stackwallet/pages/exchange_view/choose_from_stack_view.dart';
|
import 'package:stackwallet/pages/exchange_view/choose_from_stack_view.dart';
|
||||||
import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_3_view.dart';
|
import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_3_view.dart';
|
||||||
import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart';
|
import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart';
|
||||||
import 'package:stackwallet/providers/exchange/exchange_flow_is_active_state_provider.dart';
|
|
||||||
import 'package:stackwallet/providers/exchange/exchange_send_from_wallet_id_provider.dart';
|
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/utilities/address_utils.dart';
|
import 'package:stackwallet/utilities/address_utils.dart';
|
||||||
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
|
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
|
||||||
|
@ -20,6 +18,7 @@ import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
|
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
|
||||||
|
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
||||||
import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
|
import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
|
||||||
import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
|
import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
|
||||||
import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
|
import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
|
||||||
|
@ -57,6 +56,8 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
||||||
late final FocusNode _toFocusNode;
|
late final FocusNode _toFocusNode;
|
||||||
late final FocusNode _refundFocusNode;
|
late final FocusNode _refundFocusNode;
|
||||||
|
|
||||||
|
bool enableNext = false;
|
||||||
|
|
||||||
bool isStackCoin(String ticker) {
|
bool isStackCoin(String ticker) {
|
||||||
try {
|
try {
|
||||||
coinFromTickerCaseInsensitive(ticker);
|
coinFromTickerCaseInsensitive(ticker);
|
||||||
|
@ -207,6 +208,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
||||||
_toController.text = manager.walletName;
|
_toController.text = manager.walletName;
|
||||||
model.recipientAddress = await manager
|
model.recipientAddress = await manager
|
||||||
.currentReceivingAddress;
|
.currentReceivingAddress;
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
enableNext = _toController
|
||||||
|
.text.isNotEmpty &&
|
||||||
|
_refundController.text.isNotEmpty;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
|
@ -275,7 +282,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
||||||
model.recipientAddress =
|
model.recipientAddress =
|
||||||
_toController.text;
|
_toController.text;
|
||||||
|
|
||||||
setState(() {});
|
setState(() {
|
||||||
|
enableNext = _toController
|
||||||
|
.text.isNotEmpty &&
|
||||||
|
_refundController
|
||||||
|
.text.isNotEmpty;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
child: const XIcon(),
|
child: const XIcon(),
|
||||||
)
|
)
|
||||||
|
@ -295,7 +307,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
||||||
model.recipientAddress =
|
model.recipientAddress =
|
||||||
_toController.text;
|
_toController.text;
|
||||||
|
|
||||||
setState(() {});
|
setState(() {
|
||||||
|
enableNext = _toController
|
||||||
|
.text.isNotEmpty &&
|
||||||
|
_refundController
|
||||||
|
.text.isNotEmpty;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: _toController.text.isEmpty
|
child: _toController.text.isEmpty
|
||||||
|
@ -338,6 +355,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
||||||
.state)
|
.state)
|
||||||
.state = "";
|
.state = "";
|
||||||
}
|
}
|
||||||
|
setState(() {
|
||||||
|
enableNext = _toController
|
||||||
|
.text.isNotEmpty &&
|
||||||
|
_refundController
|
||||||
|
.text.isNotEmpty;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: const AddressBookIcon(),
|
child: const AddressBookIcon(),
|
||||||
|
@ -361,14 +384,24 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
||||||
model.recipientAddress =
|
model.recipientAddress =
|
||||||
_toController.text;
|
_toController.text;
|
||||||
|
|
||||||
setState(() {});
|
setState(() {
|
||||||
|
enableNext = _toController
|
||||||
|
.text.isNotEmpty &&
|
||||||
|
_refundController
|
||||||
|
.text.isNotEmpty;
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
_toController.text =
|
_toController.text =
|
||||||
qrResult.rawContent;
|
qrResult.rawContent;
|
||||||
model.recipientAddress =
|
model.recipientAddress =
|
||||||
_toController.text;
|
_toController.text;
|
||||||
|
|
||||||
setState(() {});
|
setState(() {
|
||||||
|
enableNext = _toController
|
||||||
|
.text.isNotEmpty &&
|
||||||
|
_refundController
|
||||||
|
.text.isNotEmpty;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} on PlatformException catch (e, s) {
|
} on PlatformException catch (e, s) {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
|
@ -429,6 +462,11 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
||||||
model.refundAddress = await manager
|
model.refundAddress = await manager
|
||||||
.currentReceivingAddress;
|
.currentReceivingAddress;
|
||||||
}
|
}
|
||||||
|
setState(() {
|
||||||
|
enableNext = _toController
|
||||||
|
.text.isNotEmpty &&
|
||||||
|
_refundController.text.isNotEmpty;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance
|
Logging.instance
|
||||||
|
@ -495,7 +533,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
||||||
model.refundAddress =
|
model.refundAddress =
|
||||||
_refundController.text;
|
_refundController.text;
|
||||||
|
|
||||||
setState(() {});
|
setState(() {
|
||||||
|
enableNext = _toController
|
||||||
|
.text.isNotEmpty &&
|
||||||
|
_refundController
|
||||||
|
.text.isNotEmpty;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
child: const XIcon(),
|
child: const XIcon(),
|
||||||
)
|
)
|
||||||
|
@ -516,7 +559,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
||||||
model.refundAddress =
|
model.refundAddress =
|
||||||
_refundController.text;
|
_refundController.text;
|
||||||
|
|
||||||
setState(() {});
|
setState(() {
|
||||||
|
enableNext = _toController
|
||||||
|
.text.isNotEmpty &&
|
||||||
|
_refundController
|
||||||
|
.text.isNotEmpty;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child:
|
child:
|
||||||
|
@ -555,6 +603,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
||||||
model.refundAddress =
|
model.refundAddress =
|
||||||
_refundController.text;
|
_refundController.text;
|
||||||
}
|
}
|
||||||
|
setState(() {
|
||||||
|
enableNext = _toController
|
||||||
|
.text.isNotEmpty &&
|
||||||
|
_refundController
|
||||||
|
.text.isNotEmpty;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: const AddressBookIcon(),
|
child: const AddressBookIcon(),
|
||||||
|
@ -578,14 +632,24 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
||||||
model.refundAddress =
|
model.refundAddress =
|
||||||
_refundController.text;
|
_refundController.text;
|
||||||
|
|
||||||
setState(() {});
|
setState(() {
|
||||||
|
enableNext = _toController
|
||||||
|
.text.isNotEmpty &&
|
||||||
|
_refundController
|
||||||
|
.text.isNotEmpty;
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
_refundController.text =
|
_refundController.text =
|
||||||
qrResult.rawContent;
|
qrResult.rawContent;
|
||||||
model.refundAddress =
|
model.refundAddress =
|
||||||
_refundController.text;
|
_refundController.text;
|
||||||
|
|
||||||
setState(() {});
|
setState(() {
|
||||||
|
enableNext = _toController
|
||||||
|
.text.isNotEmpty &&
|
||||||
|
_refundController
|
||||||
|
.text.isNotEmpty;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} on PlatformException catch (e, s) {
|
} on PlatformException catch (e, s) {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
|
@ -637,20 +701,15 @@ class _Step2ViewState extends ConsumerState<Step2View> {
|
||||||
width: 16,
|
width: 16,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextButton(
|
child: PrimaryButton(
|
||||||
|
label: "Next",
|
||||||
|
enabled: enableNext,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
Step3View.routeName,
|
Step3View.routeName,
|
||||||
arguments: model,
|
arguments: model,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
style: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.getPrimaryEnabledButtonColor(context),
|
|
||||||
child: Text(
|
|
||||||
"Next",
|
|
||||||
style: STextStyles.button(context),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -487,7 +487,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
|
||||||
|
|
||||||
final amount =
|
final amount =
|
||||||
Format.decimalAmountToSatoshis(
|
Format.decimalAmountToSatoshis(
|
||||||
model.sendAmount);
|
model.sendAmount, manager.coin);
|
||||||
final address =
|
final address =
|
||||||
model.trade!.payInAddress;
|
model.trade!.payInAddress;
|
||||||
|
|
||||||
|
|
|
@ -61,25 +61,7 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
|
||||||
late final Trade trade;
|
late final Trade trade;
|
||||||
|
|
||||||
String formatAmount(Decimal amount, Coin coin) {
|
String formatAmount(Decimal amount, Coin coin) {
|
||||||
switch (coin) {
|
return amount.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
|
||||||
case Coin.bitcoin:
|
|
||||||
case Coin.bitcoincash:
|
|
||||||
case Coin.litecoin:
|
|
||||||
case Coin.dogecoin:
|
|
||||||
case Coin.epicCash:
|
|
||||||
case Coin.firo:
|
|
||||||
case Coin.namecoin:
|
|
||||||
case Coin.bitcoinTestNet:
|
|
||||||
case Coin.litecoinTestNet:
|
|
||||||
case Coin.bitcoincashTestnet:
|
|
||||||
case Coin.dogecoinTestNet:
|
|
||||||
case Coin.firoTestNet:
|
|
||||||
return amount.toStringAsFixed(Constants.decimalPlaces);
|
|
||||||
case Coin.monero:
|
|
||||||
return amount.toStringAsFixed(Constants.decimalPlacesMonero);
|
|
||||||
case Coin.wownero:
|
|
||||||
return amount.toStringAsFixed(Constants.decimalPlacesWownero);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -233,7 +215,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
|
||||||
late final Trade trade;
|
late final Trade trade;
|
||||||
|
|
||||||
Future<void> _send(Manager manager, {bool? shouldSendPublicFiroFunds}) async {
|
Future<void> _send(Manager manager, {bool? shouldSendPublicFiroFunds}) async {
|
||||||
final _amount = Format.decimalAmountToSatoshis(amount);
|
final _amount = Format.decimalAmountToSatoshis(amount, manager.coin);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
bool wasCancelled = false;
|
bool wasCancelled = false;
|
||||||
|
@ -464,7 +446,8 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
|
||||||
"${Format.localizedStringAsFixed(
|
"${Format.localizedStringAsFixed(
|
||||||
value: snapshot.data!,
|
value: snapshot.data!,
|
||||||
locale: locale,
|
locale: locale,
|
||||||
decimalPlaces: Constants.decimalPlaces,
|
decimalPlaces:
|
||||||
|
Constants.decimalPlacesForCoin(coin),
|
||||||
)} ${coin.ticker}",
|
)} ${coin.ticker}",
|
||||||
style: STextStyles.itemSubtitle(context),
|
style: STextStyles.itemSubtitle(context),
|
||||||
);
|
);
|
||||||
|
@ -549,7 +532,8 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
|
||||||
"${Format.localizedStringAsFixed(
|
"${Format.localizedStringAsFixed(
|
||||||
value: snapshot.data!,
|
value: snapshot.data!,
|
||||||
locale: locale,
|
locale: locale,
|
||||||
decimalPlaces: Constants.decimalPlaces,
|
decimalPlaces:
|
||||||
|
Constants.decimalPlacesForCoin(coin),
|
||||||
)} ${coin.ticker}",
|
)} ${coin.ticker}",
|
||||||
style: STextStyles.itemSubtitle(context),
|
style: STextStyles.itemSubtitle(context),
|
||||||
);
|
);
|
||||||
|
@ -657,11 +641,8 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
|
||||||
"${Format.localizedStringAsFixed(
|
"${Format.localizedStringAsFixed(
|
||||||
value: snapshot.data!,
|
value: snapshot.data!,
|
||||||
locale: locale,
|
locale: locale,
|
||||||
decimalPlaces: coin == Coin.monero
|
decimalPlaces:
|
||||||
? Constants.decimalPlacesMonero
|
Constants.decimalPlacesForCoin(coin),
|
||||||
: coin == Coin.wownero
|
|
||||||
? Constants.decimalPlacesWownero
|
|
||||||
: Constants.decimalPlaces,
|
|
||||||
)} ${coin.ticker}",
|
)} ${coin.ticker}",
|
||||||
style: STextStyles.itemSubtitle(context),
|
style: STextStyles.itemSubtitle(context),
|
||||||
);
|
);
|
||||||
|
|
|
@ -159,6 +159,14 @@ class ExchangeProviderOptions extends ConsumerWidget {
|
||||||
.toDecimal(
|
.toDecimal(
|
||||||
scaleOnInfinitePrecision: 12);
|
scaleOnInfinitePrecision: 12);
|
||||||
}
|
}
|
||||||
|
Coin coin;
|
||||||
|
try {
|
||||||
|
coin =
|
||||||
|
coinFromTickerCaseInsensitive(to!);
|
||||||
|
} catch (_) {
|
||||||
|
coin = Coin.bitcoin;
|
||||||
|
}
|
||||||
|
|
||||||
return Text(
|
return Text(
|
||||||
"1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
|
"1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
|
||||||
value: rate,
|
value: rate,
|
||||||
|
@ -167,11 +175,9 @@ class ExchangeProviderOptions extends ConsumerWidget {
|
||||||
.select(
|
.select(
|
||||||
(value) => value.locale),
|
(value) => value.locale),
|
||||||
),
|
),
|
||||||
decimalPlaces: to!.toUpperCase() ==
|
decimalPlaces:
|
||||||
Coin.monero.ticker
|
Constants.decimalPlacesForCoin(
|
||||||
.toUpperCase()
|
coin),
|
||||||
? Constants.decimalPlacesMonero
|
|
||||||
: Constants.decimalPlaces,
|
|
||||||
)} ${to!.toUpperCase()}",
|
)} ${to!.toUpperCase()}",
|
||||||
style:
|
style:
|
||||||
STextStyles.itemSubtitle12(context)
|
STextStyles.itemSubtitle12(context)
|
||||||
|
@ -354,6 +360,13 @@ class ExchangeProviderOptions extends ConsumerWidget {
|
||||||
.toDecimal(
|
.toDecimal(
|
||||||
scaleOnInfinitePrecision: 12);
|
scaleOnInfinitePrecision: 12);
|
||||||
|
|
||||||
|
Coin coin;
|
||||||
|
try {
|
||||||
|
coin =
|
||||||
|
coinFromTickerCaseInsensitive(to!);
|
||||||
|
} catch (_) {
|
||||||
|
coin = Coin.bitcoin;
|
||||||
|
}
|
||||||
return Text(
|
return Text(
|
||||||
"1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
|
"1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
|
||||||
value: rate,
|
value: rate,
|
||||||
|
@ -362,11 +375,9 @@ class ExchangeProviderOptions extends ConsumerWidget {
|
||||||
.select(
|
.select(
|
||||||
(value) => value.locale),
|
(value) => value.locale),
|
||||||
),
|
),
|
||||||
decimalPlaces: to!.toUpperCase() ==
|
decimalPlaces:
|
||||||
Coin.monero.ticker
|
Constants.decimalPlacesForCoin(
|
||||||
.toUpperCase()
|
coin),
|
||||||
? Constants.decimalPlacesMonero
|
|
||||||
: Constants.decimalPlaces,
|
|
||||||
)} ${to!.toUpperCase()}",
|
)} ${to!.toUpperCase()}",
|
||||||
style:
|
style:
|
||||||
STextStyles.itemSubtitle12(context)
|
STextStyles.itemSubtitle12(context)
|
||||||
|
|
|
@ -55,7 +55,7 @@ class RateTypeToggle extends ConsumerWidget {
|
||||||
child: RoundedContainer(
|
child: RoundedContainer(
|
||||||
padding: isDesktop
|
padding: isDesktop
|
||||||
? const EdgeInsets.all(17)
|
? const EdgeInsets.all(17)
|
||||||
: const EdgeInsets.all(0),
|
: const EdgeInsets.all(12),
|
||||||
color: estimated
|
color: estimated
|
||||||
? Theme.of(context)
|
? Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
|
@ -136,7 +136,7 @@ class RateTypeToggle extends ConsumerWidget {
|
||||||
child: RoundedContainer(
|
child: RoundedContainer(
|
||||||
padding: isDesktop
|
padding: isDesktop
|
||||||
? const EdgeInsets.all(17)
|
? const EdgeInsets.all(17)
|
||||||
: const EdgeInsets.all(0),
|
: const EdgeInsets.all(12),
|
||||||
color: !estimated
|
color: !estimated
|
||||||
? Theme.of(context)
|
? Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
|
|
|
@ -317,13 +317,12 @@ class _ConfirmTransactionViewState
|
||||||
style: STextStyles.smallMed12(context),
|
style: STextStyles.smallMed12(context),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"${Format.satoshiAmountToPrettyString(
|
"${Format.satoshiAmountToPrettyString(transactionInfo["recipientAmt"] as int, ref.watch(
|
||||||
transactionInfo["recipientAmt"] as int,
|
localeServiceChangeNotifierProvider
|
||||||
ref.watch(
|
.select((value) => value.locale),
|
||||||
localeServiceChangeNotifierProvider
|
), ref.watch(
|
||||||
.select((value) => value.locale),
|
managerProvider.select((value) => value.coin),
|
||||||
),
|
))} ${ref.watch(
|
||||||
)} ${ref.watch(
|
|
||||||
managerProvider.select((value) => value.coin),
|
managerProvider.select((value) => value.coin),
|
||||||
).ticker}",
|
).ticker}",
|
||||||
style: STextStyles.itemSubtitle12(context),
|
style: STextStyles.itemSubtitle12(context),
|
||||||
|
@ -344,13 +343,12 @@ class _ConfirmTransactionViewState
|
||||||
style: STextStyles.smallMed12(context),
|
style: STextStyles.smallMed12(context),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"${Format.satoshiAmountToPrettyString(
|
"${Format.satoshiAmountToPrettyString(transactionInfo["fee"] as int, ref.watch(
|
||||||
transactionInfo["fee"] as int,
|
localeServiceChangeNotifierProvider
|
||||||
ref.watch(
|
.select((value) => value.locale),
|
||||||
localeServiceChangeNotifierProvider
|
), ref.watch(
|
||||||
.select((value) => value.locale),
|
managerProvider.select((value) => value.coin),
|
||||||
),
|
))} ${ref.watch(
|
||||||
)} ${ref.watch(
|
|
||||||
managerProvider.select((value) => value.coin),
|
managerProvider.select((value) => value.coin),
|
||||||
).ticker}",
|
).ticker}",
|
||||||
style: STextStyles.itemSubtitle12(context),
|
style: STextStyles.itemSubtitle12(context),
|
||||||
|
@ -494,6 +492,7 @@ class _ConfirmTransactionViewState
|
||||||
localeServiceChangeNotifierProvider
|
localeServiceChangeNotifierProvider
|
||||||
.select((value) => value.locale),
|
.select((value) => value.locale),
|
||||||
),
|
),
|
||||||
|
coin,
|
||||||
)} ${coin.ticker}",
|
)} ${coin.ticker}",
|
||||||
style: STextStyles
|
style: STextStyles
|
||||||
.desktopTextExtraExtraSmall(
|
.desktopTextExtraExtraSmall(
|
||||||
|
@ -638,11 +637,7 @@ class _ConfirmTransactionViewState
|
||||||
value: fee,
|
value: fee,
|
||||||
locale: ref.watch(localeServiceChangeNotifierProvider
|
locale: ref.watch(localeServiceChangeNotifierProvider
|
||||||
.select((value) => value.locale)),
|
.select((value) => value.locale)),
|
||||||
decimalPlaces: coin == Coin.monero
|
decimalPlaces: Constants.decimalPlacesForCoin(coin),
|
||||||
? Constants.decimalPlacesMonero
|
|
||||||
: coin == Coin.wownero
|
|
||||||
? Constants.decimalPlacesWownero
|
|
||||||
: Constants.decimalPlaces,
|
|
||||||
)} ${coin.ticker}",
|
)} ${coin.ticker}",
|
||||||
style: STextStyles.itemSubtitle(context),
|
style: STextStyles.itemSubtitle(context),
|
||||||
);
|
);
|
||||||
|
@ -750,6 +745,9 @@ class _ConfirmTransactionViewState
|
||||||
localeServiceChangeNotifierProvider
|
localeServiceChangeNotifierProvider
|
||||||
.select((value) => value.locale),
|
.select((value) => value.locale),
|
||||||
),
|
),
|
||||||
|
ref.watch(
|
||||||
|
managerProvider.select((value) => value.coin),
|
||||||
|
),
|
||||||
)} ${ref.watch(
|
)} ${ref.watch(
|
||||||
managerProvider.select((value) => value.coin),
|
managerProvider.select((value) => value.coin),
|
||||||
).ticker}",
|
).ticker}",
|
||||||
|
@ -782,7 +780,7 @@ class _ConfirmTransactionViewState
|
||||||
: const EdgeInsets.all(0),
|
: const EdgeInsets.all(0),
|
||||||
child: PrimaryButton(
|
child: PrimaryButton(
|
||||||
label: "Send",
|
label: "Send",
|
||||||
buttonHeight: ButtonHeight.l,
|
buttonHeight: isDesktop ? ButtonHeight.l : null,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final dynamic unlocked;
|
final dynamic unlocked;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:cw_core/monero_transaction_priority.dart';
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
@ -30,6 +31,7 @@ import 'package:stackwallet/utilities/logger.dart';
|
||||||
import 'package:stackwallet/utilities/prefs.dart';
|
import 'package:stackwallet/utilities/prefs.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
import 'package:stackwallet/widgets/animated_text.dart';
|
import 'package:stackwallet/widgets/animated_text.dart';
|
||||||
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
|
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
|
||||||
|
@ -41,8 +43,6 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
|
||||||
import 'package:stackwallet/widgets/stack_text_field.dart';
|
import 'package:stackwallet/widgets/stack_text_field.dart';
|
||||||
import 'package:stackwallet/widgets/textfield_icon_button.dart';
|
import 'package:stackwallet/widgets/textfield_icon_button.dart';
|
||||||
|
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
|
||||||
|
|
||||||
class SendView extends ConsumerStatefulWidget {
|
class SendView extends ConsumerStatefulWidget {
|
||||||
const SendView({
|
const SendView({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
@ -211,29 +211,47 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
int fee;
|
int fee;
|
||||||
|
if (coin == Coin.monero) {
|
||||||
|
MoneroTransactionPriority specialMoneroId;
|
||||||
|
switch (ref.read(feeRateTypeStateProvider.state).state) {
|
||||||
|
case FeeRateType.fast:
|
||||||
|
specialMoneroId = MoneroTransactionPriority.fast;
|
||||||
|
break;
|
||||||
|
case FeeRateType.average:
|
||||||
|
specialMoneroId = MoneroTransactionPriority.regular;
|
||||||
|
break;
|
||||||
|
case FeeRateType.slow:
|
||||||
|
specialMoneroId = MoneroTransactionPriority.slow;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (coin == Coin.firo || coin == Coin.firoTestNet) {
|
fee = await manager.estimateFeeFor(amount, specialMoneroId.raw!);
|
||||||
|
cachedFees[amount] = Format.satoshisToAmount(fee, coin: coin)
|
||||||
|
.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
|
||||||
|
|
||||||
|
return cachedFees[amount]!;
|
||||||
|
} else if (coin == Coin.firo || coin == Coin.firoTestNet) {
|
||||||
if (ref.read(publicPrivateBalanceStateProvider.state).state ==
|
if (ref.read(publicPrivateBalanceStateProvider.state).state ==
|
||||||
"Private") {
|
"Private") {
|
||||||
fee = await manager.estimateFeeFor(amount, feeRate);
|
fee = await manager.estimateFeeFor(amount, feeRate);
|
||||||
|
|
||||||
cachedFiroPrivateFees[amount] = Format.satoshisToAmount(fee)
|
cachedFiroPrivateFees[amount] = Format.satoshisToAmount(fee, coin: coin)
|
||||||
.toStringAsFixed(Constants.decimalPlaces);
|
.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
|
||||||
|
|
||||||
return cachedFiroPrivateFees[amount]!;
|
return cachedFiroPrivateFees[amount]!;
|
||||||
} else {
|
} else {
|
||||||
fee = await (manager.wallet as FiroWallet)
|
fee = await (manager.wallet as FiroWallet)
|
||||||
.estimateFeeForPublic(amount, feeRate);
|
.estimateFeeForPublic(amount, feeRate);
|
||||||
|
|
||||||
cachedFiroPublicFees[amount] = Format.satoshisToAmount(fee)
|
cachedFiroPublicFees[amount] = Format.satoshisToAmount(fee, coin: coin)
|
||||||
.toStringAsFixed(Constants.decimalPlaces);
|
.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
|
||||||
|
|
||||||
return cachedFiroPublicFees[amount]!;
|
return cachedFiroPublicFees[amount]!;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fee = await manager.estimateFeeFor(amount, feeRate);
|
fee = await manager.estimateFeeFor(amount, feeRate);
|
||||||
cachedFees[amount] =
|
cachedFees[amount] = Format.satoshisToAmount(fee, coin: coin)
|
||||||
Format.satoshisToAmount(fee).toStringAsFixed(Constants.decimalPlaces);
|
.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
|
||||||
|
|
||||||
return cachedFees[amount]!;
|
return cachedFees[amount]!;
|
||||||
}
|
}
|
||||||
|
@ -296,8 +314,8 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
_calculateFeesFuture =
|
_calculateFeesFuture = calculateFees(
|
||||||
calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
|
Format.decimalAmountToSatoshis(_amountToSend!, coin));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,8 +329,8 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
_calculateFeesFuture =
|
_calculateFeesFuture = calculateFees(
|
||||||
calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
|
Format.decimalAmountToSatoshis(_amountToSend!, coin));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,8 +372,8 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
_calculateFeesFuture =
|
_calculateFeesFuture = calculateFees(
|
||||||
calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
|
Format.decimalAmountToSatoshis(_amountToSend!, coin));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -492,7 +510,9 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
onTap: () {
|
onTap: () {
|
||||||
cryptoAmountController.text =
|
cryptoAmountController.text =
|
||||||
_cachedBalance!.toStringAsFixed(
|
_cachedBalance!.toStringAsFixed(
|
||||||
Constants.decimalPlaces);
|
Constants
|
||||||
|
.decimalPlacesForCoin(
|
||||||
|
coin));
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
|
@ -781,8 +801,9 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
.read(
|
.read(
|
||||||
localeServiceChangeNotifierProvider)
|
localeServiceChangeNotifierProvider)
|
||||||
.locale,
|
.locale,
|
||||||
decimalPlaces:
|
decimalPlaces: Constants
|
||||||
Constants.decimalPlaces,
|
.decimalPlacesForCoin(
|
||||||
|
coin),
|
||||||
);
|
);
|
||||||
amount.toString();
|
amount.toString();
|
||||||
_amountToSend = amount;
|
_amountToSend = amount;
|
||||||
|
@ -1044,19 +1065,22 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
(await firoWallet
|
(await firoWallet
|
||||||
.availablePrivateBalance())
|
.availablePrivateBalance())
|
||||||
.toStringAsFixed(
|
.toStringAsFixed(
|
||||||
Constants.decimalPlaces);
|
Constants.decimalPlacesForCoin(
|
||||||
|
coin));
|
||||||
} else {
|
} else {
|
||||||
cryptoAmountController.text =
|
cryptoAmountController.text =
|
||||||
(await firoWallet
|
(await firoWallet
|
||||||
.availablePublicBalance())
|
.availablePublicBalance())
|
||||||
.toStringAsFixed(
|
.toStringAsFixed(
|
||||||
Constants.decimalPlaces);
|
Constants.decimalPlacesForCoin(
|
||||||
|
coin));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cryptoAmountController.text = (await ref
|
cryptoAmountController.text = (await ref
|
||||||
.read(provider)
|
.read(provider)
|
||||||
.availableBalance)
|
.availableBalance)
|
||||||
.toStringAsFixed(Constants.decimalPlaces);
|
.toStringAsFixed(
|
||||||
|
Constants.decimalPlacesForCoin(coin));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -1167,7 +1191,8 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
? Decimal.zero
|
? Decimal.zero
|
||||||
: (baseAmount / _price).toDecimal(
|
: (baseAmount / _price).toDecimal(
|
||||||
scaleOnInfinitePrecision:
|
scaleOnInfinitePrecision:
|
||||||
Constants.decimalPlaces);
|
Constants.decimalPlacesForCoin(
|
||||||
|
coin));
|
||||||
}
|
}
|
||||||
if (_cachedAmountToSend != null &&
|
if (_cachedAmountToSend != null &&
|
||||||
_cachedAmountToSend == _amountToSend) {
|
_cachedAmountToSend == _amountToSend) {
|
||||||
|
@ -1184,7 +1209,8 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
locale: ref
|
locale: ref
|
||||||
.read(localeServiceChangeNotifierProvider)
|
.read(localeServiceChangeNotifierProvider)
|
||||||
.locale,
|
.locale,
|
||||||
decimalPlaces: Constants.decimalPlaces,
|
decimalPlaces:
|
||||||
|
Constants.decimalPlacesForCoin(coin),
|
||||||
);
|
);
|
||||||
|
|
||||||
_cryptoAmountChangeLock = true;
|
_cryptoAmountChangeLock = true;
|
||||||
|
@ -1506,7 +1532,7 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
final amount = Format.decimalAmountToSatoshis(
|
final amount = Format.decimalAmountToSatoshis(
|
||||||
_amountToSend!);
|
_amountToSend!, coin);
|
||||||
int availableBalance;
|
int availableBalance;
|
||||||
if ((coin == Coin.firo ||
|
if ((coin == Coin.firo ||
|
||||||
coin == Coin.firoTestNet)) {
|
coin == Coin.firoTestNet)) {
|
||||||
|
@ -1520,18 +1546,21 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
Format.decimalAmountToSatoshis(
|
Format.decimalAmountToSatoshis(
|
||||||
await (manager.wallet
|
await (manager.wallet
|
||||||
as FiroWallet)
|
as FiroWallet)
|
||||||
.availablePrivateBalance());
|
.availablePrivateBalance(),
|
||||||
|
coin);
|
||||||
} else {
|
} else {
|
||||||
availableBalance =
|
availableBalance =
|
||||||
Format.decimalAmountToSatoshis(
|
Format.decimalAmountToSatoshis(
|
||||||
await (manager.wallet
|
await (manager.wallet
|
||||||
as FiroWallet)
|
as FiroWallet)
|
||||||
.availablePublicBalance());
|
.availablePublicBalance(),
|
||||||
|
coin);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
availableBalance =
|
availableBalance =
|
||||||
Format.decimalAmountToSatoshis(
|
Format.decimalAmountToSatoshis(
|
||||||
await manager.availableBalance);
|
await manager.availableBalance,
|
||||||
|
coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// confirm send all
|
// confirm send all
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cw_core/monero_transaction_priority.dart';
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
@ -70,16 +71,27 @@ class _TransactionFeeSelectionSheetState
|
||||||
final manager =
|
final manager =
|
||||||
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
||||||
|
|
||||||
if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
if (coin == Coin.monero || coin == Coin.wownero) {
|
||||||
|
final fee = await manager.estimateFeeFor(
|
||||||
|
amount, MoneroTransactionPriority.fast.raw!);
|
||||||
|
ref.read(feeSheetSessionCacheProvider).fast[amount] =
|
||||||
|
Format.satoshisToAmount(
|
||||||
|
fee,
|
||||||
|
coin: coin,
|
||||||
|
);
|
||||||
|
} else if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
||||||
ref.read(publicPrivateBalanceStateProvider.state).state !=
|
ref.read(publicPrivateBalanceStateProvider.state).state !=
|
||||||
"Private") {
|
"Private") {
|
||||||
ref.read(feeSheetSessionCacheProvider).fast[amount] =
|
ref.read(feeSheetSessionCacheProvider).fast[amount] =
|
||||||
Format.satoshisToAmount(await (manager.wallet as FiroWallet)
|
Format.satoshisToAmount(
|
||||||
.estimateFeeForPublic(amount, feeRate));
|
await (manager.wallet as FiroWallet)
|
||||||
|
.estimateFeeForPublic(amount, feeRate),
|
||||||
|
coin: coin);
|
||||||
} else {
|
} else {
|
||||||
ref.read(feeSheetSessionCacheProvider).fast[amount] =
|
ref.read(feeSheetSessionCacheProvider).fast[amount] =
|
||||||
Format.satoshisToAmount(
|
Format.satoshisToAmount(
|
||||||
await manager.estimateFeeFor(amount, feeRate));
|
await manager.estimateFeeFor(amount, feeRate),
|
||||||
|
coin: coin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ref.read(feeSheetSessionCacheProvider).fast[amount]!;
|
return ref.read(feeSheetSessionCacheProvider).fast[amount]!;
|
||||||
|
@ -88,17 +100,27 @@ class _TransactionFeeSelectionSheetState
|
||||||
if (ref.read(feeSheetSessionCacheProvider).average[amount] == null) {
|
if (ref.read(feeSheetSessionCacheProvider).average[amount] == null) {
|
||||||
final manager =
|
final manager =
|
||||||
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
||||||
|
if (coin == Coin.monero || coin == Coin.wownero) {
|
||||||
if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
final fee = await manager.estimateFeeFor(
|
||||||
|
amount, MoneroTransactionPriority.regular.raw!);
|
||||||
|
ref.read(feeSheetSessionCacheProvider).average[amount] =
|
||||||
|
Format.satoshisToAmount(
|
||||||
|
fee,
|
||||||
|
coin: coin,
|
||||||
|
);
|
||||||
|
} else if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
||||||
ref.read(publicPrivateBalanceStateProvider.state).state !=
|
ref.read(publicPrivateBalanceStateProvider.state).state !=
|
||||||
"Private") {
|
"Private") {
|
||||||
ref.read(feeSheetSessionCacheProvider).average[amount] =
|
ref.read(feeSheetSessionCacheProvider).average[amount] =
|
||||||
Format.satoshisToAmount(await (manager.wallet as FiroWallet)
|
Format.satoshisToAmount(
|
||||||
.estimateFeeForPublic(amount, feeRate));
|
await (manager.wallet as FiroWallet)
|
||||||
|
.estimateFeeForPublic(amount, feeRate),
|
||||||
|
coin: coin);
|
||||||
} else {
|
} else {
|
||||||
ref.read(feeSheetSessionCacheProvider).average[amount] =
|
ref.read(feeSheetSessionCacheProvider).average[amount] =
|
||||||
Format.satoshisToAmount(
|
Format.satoshisToAmount(
|
||||||
await manager.estimateFeeFor(amount, feeRate));
|
await manager.estimateFeeFor(amount, feeRate),
|
||||||
|
coin: coin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ref.read(feeSheetSessionCacheProvider).average[amount]!;
|
return ref.read(feeSheetSessionCacheProvider).average[amount]!;
|
||||||
|
@ -107,17 +129,27 @@ class _TransactionFeeSelectionSheetState
|
||||||
if (ref.read(feeSheetSessionCacheProvider).slow[amount] == null) {
|
if (ref.read(feeSheetSessionCacheProvider).slow[amount] == null) {
|
||||||
final manager =
|
final manager =
|
||||||
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
||||||
|
if (coin == Coin.monero || coin == Coin.wownero) {
|
||||||
if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
final fee = await manager.estimateFeeFor(
|
||||||
|
amount, MoneroTransactionPriority.slow.raw!);
|
||||||
|
ref.read(feeSheetSessionCacheProvider).slow[amount] =
|
||||||
|
Format.satoshisToAmount(
|
||||||
|
fee,
|
||||||
|
coin: coin,
|
||||||
|
);
|
||||||
|
} else if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
||||||
ref.read(publicPrivateBalanceStateProvider.state).state !=
|
ref.read(publicPrivateBalanceStateProvider.state).state !=
|
||||||
"Private") {
|
"Private") {
|
||||||
ref.read(feeSheetSessionCacheProvider).slow[amount] =
|
ref.read(feeSheetSessionCacheProvider).slow[amount] =
|
||||||
Format.satoshisToAmount(await (manager.wallet as FiroWallet)
|
Format.satoshisToAmount(
|
||||||
.estimateFeeForPublic(amount, feeRate));
|
await (manager.wallet as FiroWallet)
|
||||||
|
.estimateFeeForPublic(amount, feeRate),
|
||||||
|
coin: coin);
|
||||||
} else {
|
} else {
|
||||||
ref.read(feeSheetSessionCacheProvider).slow[amount] =
|
ref.read(feeSheetSessionCacheProvider).slow[amount] =
|
||||||
Format.satoshisToAmount(
|
Format.satoshisToAmount(
|
||||||
await manager.estimateFeeFor(amount, feeRate));
|
await manager.estimateFeeFor(amount, feeRate),
|
||||||
|
coin: coin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ref.read(feeSheetSessionCacheProvider).slow[amount]!;
|
return ref.read(feeSheetSessionCacheProvider).slow[amount]!;
|
||||||
|
@ -225,7 +257,7 @@ class _TransactionFeeSelectionSheetState
|
||||||
ref.read(feeRateTypeStateProvider.state).state =
|
ref.read(feeRateTypeStateProvider.state).state =
|
||||||
FeeRateType.fast;
|
FeeRateType.fast;
|
||||||
}
|
}
|
||||||
String? fee = getAmount(FeeRateType.fast);
|
String? fee = getAmount(FeeRateType.fast, manager.coin);
|
||||||
if (fee != null) {
|
if (fee != null) {
|
||||||
widget.updateChosen(fee);
|
widget.updateChosen(fee);
|
||||||
}
|
}
|
||||||
|
@ -293,7 +325,7 @@ class _TransactionFeeSelectionSheetState
|
||||||
feeRate: feeObject!.fast,
|
feeRate: feeObject!.fast,
|
||||||
amount: Format
|
amount: Format
|
||||||
.decimalAmountToSatoshis(
|
.decimalAmountToSatoshis(
|
||||||
amount)),
|
amount, manager.coin)),
|
||||||
// future: manager.estimateFeeFor(
|
// future: manager.estimateFeeFor(
|
||||||
// Format.decimalAmountToSatoshis(
|
// Format.decimalAmountToSatoshis(
|
||||||
// amount),
|
// amount),
|
||||||
|
@ -358,7 +390,8 @@ class _TransactionFeeSelectionSheetState
|
||||||
ref.read(feeRateTypeStateProvider.state).state =
|
ref.read(feeRateTypeStateProvider.state).state =
|
||||||
FeeRateType.average;
|
FeeRateType.average;
|
||||||
}
|
}
|
||||||
String? fee = getAmount(FeeRateType.average);
|
String? fee =
|
||||||
|
getAmount(FeeRateType.average, manager.coin);
|
||||||
if (fee != null) {
|
if (fee != null) {
|
||||||
widget.updateChosen(fee);
|
widget.updateChosen(fee);
|
||||||
}
|
}
|
||||||
|
@ -424,7 +457,7 @@ class _TransactionFeeSelectionSheetState
|
||||||
feeRate: feeObject!.medium,
|
feeRate: feeObject!.medium,
|
||||||
amount: Format
|
amount: Format
|
||||||
.decimalAmountToSatoshis(
|
.decimalAmountToSatoshis(
|
||||||
amount)),
|
amount, manager.coin)),
|
||||||
// future: manager.estimateFeeFor(
|
// future: manager.estimateFeeFor(
|
||||||
// Format.decimalAmountToSatoshis(
|
// Format.decimalAmountToSatoshis(
|
||||||
// amount),
|
// amount),
|
||||||
|
@ -489,7 +522,7 @@ class _TransactionFeeSelectionSheetState
|
||||||
ref.read(feeRateTypeStateProvider.state).state =
|
ref.read(feeRateTypeStateProvider.state).state =
|
||||||
FeeRateType.slow;
|
FeeRateType.slow;
|
||||||
}
|
}
|
||||||
String? fee = getAmount(FeeRateType.slow);
|
String? fee = getAmount(FeeRateType.slow, manager.coin);
|
||||||
print("fee $fee");
|
print("fee $fee");
|
||||||
if (fee != null) {
|
if (fee != null) {
|
||||||
widget.updateChosen(fee);
|
widget.updateChosen(fee);
|
||||||
|
@ -557,7 +590,7 @@ class _TransactionFeeSelectionSheetState
|
||||||
feeRate: feeObject!.slow,
|
feeRate: feeObject!.slow,
|
||||||
amount: Format
|
amount: Format
|
||||||
.decimalAmountToSatoshis(
|
.decimalAmountToSatoshis(
|
||||||
amount)),
|
amount, manager.coin)),
|
||||||
// future: manager.estimateFeeFor(
|
// future: manager.estimateFeeFor(
|
||||||
// Format.decimalAmountToSatoshis(
|
// Format.decimalAmountToSatoshis(
|
||||||
// amount),
|
// amount),
|
||||||
|
@ -624,10 +657,10 @@ class _TransactionFeeSelectionSheetState
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String? getAmount(FeeRateType feeRateType) {
|
String? getAmount(FeeRateType feeRateType, Coin coin) {
|
||||||
try {
|
try {
|
||||||
print(feeRateType);
|
print(feeRateType);
|
||||||
var amount = Format.decimalAmountToSatoshis(this.amount);
|
var amount = Format.decimalAmountToSatoshis(this.amount, coin);
|
||||||
print(amount);
|
print(amount);
|
||||||
print(ref.read(feeSheetSessionCacheProvider).fast);
|
print(ref.read(feeSheetSessionCacheProvider).fast);
|
||||||
print(ref.read(feeSheetSessionCacheProvider).average);
|
print(ref.read(feeSheetSessionCacheProvider).average);
|
||||||
|
|
|
@ -937,13 +937,9 @@ class _DesktopTransactionCardRowState
|
||||||
flex: 6,
|
flex: 6,
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
final amount = coin == Coin.monero
|
final amount = _transaction.amount;
|
||||||
? (_transaction.amount ~/ 10000)
|
|
||||||
: coin == Coin.wownero
|
|
||||||
? (_transaction.amount ~/ 1000)
|
|
||||||
: _transaction.amount;
|
|
||||||
return Text(
|
return Text(
|
||||||
"$prefix${Format.satoshiAmountToPrettyString(amount, locale)} ${coin.ticker}",
|
"$prefix${Format.satoshiAmountToPrettyString(amount, locale, coin)} ${coin.ticker}",
|
||||||
style: STextStyles.desktopTextExtraExtraSmall(context)
|
style: STextStyles.desktopTextExtraExtraSmall(context)
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
|
@ -960,17 +956,12 @@ class _DesktopTransactionCardRowState
|
||||||
flex: 4,
|
flex: 4,
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
// TODO: modify Format.<functions> to take optional Coin parameter so this type oif check isn't done in ui
|
|
||||||
int value = _transaction.amount;
|
int value = _transaction.amount;
|
||||||
if (coin == Coin.monero) {
|
|
||||||
value = (value ~/ 10000);
|
|
||||||
} else if (coin == Coin.wownero) {
|
|
||||||
value = (value ~/ 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Text(
|
return Text(
|
||||||
"$prefix${Format.localizedStringAsFixed(
|
"$prefix${Format.localizedStringAsFixed(
|
||||||
value: Format.satoshisToAmount(value) * price,
|
value: Format.satoshisToAmount(value, coin: coin) *
|
||||||
|
price,
|
||||||
locale: locale,
|
locale: locale,
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
)} $baseCurrency",
|
)} $baseCurrency",
|
||||||
|
|
|
@ -78,8 +78,8 @@ class _TransactionDetailsViewState
|
||||||
walletId = widget.walletId;
|
walletId = widget.walletId;
|
||||||
|
|
||||||
coin = widget.coin;
|
coin = widget.coin;
|
||||||
amount = Format.satoshisToAmount(_transaction.amount);
|
amount = Format.satoshisToAmount(_transaction.amount, coin: coin);
|
||||||
fee = Format.satoshisToAmount(_transaction.fees);
|
fee = Format.satoshisToAmount(_transaction.fees, coin: coin);
|
||||||
|
|
||||||
if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
||||||
_transaction.subType == "mint") {
|
_transaction.subType == "mint") {
|
||||||
|
@ -418,21 +418,15 @@ class _TransactionDetailsViewState
|
||||||
children: [
|
children: [
|
||||||
SelectableText(
|
SelectableText(
|
||||||
"$amountPrefix${Format.localizedStringAsFixed(
|
"$amountPrefix${Format.localizedStringAsFixed(
|
||||||
value: coin == Coin.monero
|
value: amount,
|
||||||
? (amount / 10000.toDecimal())
|
|
||||||
.toDecimal()
|
|
||||||
: coin == Coin.wownero
|
|
||||||
? (amount /
|
|
||||||
1000.toDecimal())
|
|
||||||
.toDecimal()
|
|
||||||
: amount,
|
|
||||||
locale: ref.watch(
|
locale: ref.watch(
|
||||||
localeServiceChangeNotifierProvider
|
localeServiceChangeNotifierProvider
|
||||||
.select(
|
.select(
|
||||||
(value) => value.locale),
|
(value) => value.locale),
|
||||||
),
|
),
|
||||||
decimalPlaces:
|
decimalPlaces:
|
||||||
Constants.decimalPlaces,
|
Constants.decimalPlacesForCoin(
|
||||||
|
coin),
|
||||||
)} ${coin.ticker}",
|
)} ${coin.ticker}",
|
||||||
style: isDesktop
|
style: isDesktop
|
||||||
? STextStyles
|
? STextStyles
|
||||||
|
@ -454,11 +448,21 @@ class _TransactionDetailsViewState
|
||||||
(value) =>
|
(value) =>
|
||||||
value.externalCalls)))
|
value.externalCalls)))
|
||||||
SelectableText(
|
SelectableText(
|
||||||
"$amountPrefix${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : coin == Coin.wownero ? (amount / 1000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch(
|
"$amountPrefix${Format.localizedStringAsFixed(
|
||||||
localeServiceChangeNotifierProvider
|
value: amount *
|
||||||
.select((value) =>
|
ref.watch(
|
||||||
value.locale),
|
priceAnd24hChangeNotifierProvider
|
||||||
), decimalPlaces: 2)} ${ref.watch(
|
.select((value) => value
|
||||||
|
.getPrice(coin)
|
||||||
|
.item1),
|
||||||
|
),
|
||||||
|
locale: ref.watch(
|
||||||
|
localeServiceChangeNotifierProvider
|
||||||
|
.select((value) =>
|
||||||
|
value.locale),
|
||||||
|
),
|
||||||
|
decimalPlaces: 2,
|
||||||
|
)} ${ref.watch(
|
||||||
prefsChangeNotifierProvider
|
prefsChangeNotifierProvider
|
||||||
.select(
|
.select(
|
||||||
(value) => value.currency,
|
(value) => value.currency,
|
||||||
|
@ -834,32 +838,22 @@ class _TransactionDetailsViewState
|
||||||
final feeString = showFeePending
|
final feeString = showFeePending
|
||||||
? _transaction.confirmedStatus
|
? _transaction.confirmedStatus
|
||||||
? Format.localizedStringAsFixed(
|
? Format.localizedStringAsFixed(
|
||||||
value: coin == Coin.monero
|
value: fee,
|
||||||
? (fee / 10000.toDecimal())
|
|
||||||
.toDecimal()
|
|
||||||
: coin == Coin.wownero
|
|
||||||
? (fee / 1000.toDecimal())
|
|
||||||
.toDecimal()
|
|
||||||
: fee,
|
|
||||||
locale: ref.watch(
|
locale: ref.watch(
|
||||||
localeServiceChangeNotifierProvider
|
localeServiceChangeNotifierProvider
|
||||||
.select(
|
.select(
|
||||||
(value) => value.locale)),
|
(value) => value.locale)),
|
||||||
decimalPlaces:
|
decimalPlaces:
|
||||||
Constants.decimalPlaces)
|
Constants.decimalPlacesForCoin(
|
||||||
|
coin))
|
||||||
: "Pending"
|
: "Pending"
|
||||||
: Format.localizedStringAsFixed(
|
: Format.localizedStringAsFixed(
|
||||||
value: coin == Coin.monero
|
value: fee,
|
||||||
? (fee / 10000.toDecimal())
|
|
||||||
.toDecimal()
|
|
||||||
: coin == Coin.wownero
|
|
||||||
? (fee / 1000.toDecimal())
|
|
||||||
.toDecimal()
|
|
||||||
: fee,
|
|
||||||
locale: ref.watch(
|
locale: ref.watch(
|
||||||
localeServiceChangeNotifierProvider
|
localeServiceChangeNotifierProvider
|
||||||
.select((value) => value.locale)),
|
.select((value) => value.locale)),
|
||||||
decimalPlaces: Constants.decimalPlaces);
|
decimalPlaces:
|
||||||
|
Constants.decimalPlacesForCoin(coin));
|
||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment:
|
||||||
|
|
|
@ -79,7 +79,7 @@ class _TransactionSearchViewState
|
||||||
String amount = "";
|
String amount = "";
|
||||||
if (filterState.amount != null) {
|
if (filterState.amount != null) {
|
||||||
amount = Format.satoshiAmountToPrettyString(filterState.amount!,
|
amount = Format.satoshiAmountToPrettyString(filterState.amount!,
|
||||||
ref.read(localeServiceChangeNotifierProvider).locale);
|
ref.read(localeServiceChangeNotifierProvider).locale, widget.coin);
|
||||||
}
|
}
|
||||||
_amountTextEditingController.text = amount;
|
_amountTextEditingController.text = amount;
|
||||||
}
|
}
|
||||||
|
@ -967,22 +967,7 @@ class _TransactionSearchViewState
|
||||||
}
|
}
|
||||||
int? amount;
|
int? amount;
|
||||||
if (amountDecimal != null) {
|
if (amountDecimal != null) {
|
||||||
if (widget.coin == Coin.monero) {
|
amount = Format.decimalAmountToSatoshis(amountDecimal, widget.coin);
|
||||||
amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoinMonero))
|
|
||||||
.floor()
|
|
||||||
.toBigInt()
|
|
||||||
.toInt();
|
|
||||||
} else if (widget.coin == Coin.wownero) {
|
|
||||||
amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoinWownero))
|
|
||||||
.floor()
|
|
||||||
.toBigInt()
|
|
||||||
.toInt();
|
|
||||||
} else {
|
|
||||||
amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoin))
|
|
||||||
.floor()
|
|
||||||
.toBigInt()
|
|
||||||
.toInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final TransactionFilter filter = TransactionFilter(
|
final TransactionFilter filter = TransactionFilter(
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cw_core/monero_transaction_priority.dart';
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:dropdown_button2/dropdown_button2.dart';
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -55,16 +56,27 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
|
||||||
final manager =
|
final manager =
|
||||||
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
||||||
|
|
||||||
if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
if (coin == Coin.monero || coin == Coin.wownero) {
|
||||||
|
final fee = await manager.estimateFeeFor(
|
||||||
|
amount, MoneroTransactionPriority.fast.raw!);
|
||||||
|
ref.read(feeSheetSessionCacheProvider).fast[amount] =
|
||||||
|
Format.satoshisToAmount(
|
||||||
|
fee,
|
||||||
|
coin: coin,
|
||||||
|
);
|
||||||
|
} else if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
||||||
ref.read(publicPrivateBalanceStateProvider.state).state !=
|
ref.read(publicPrivateBalanceStateProvider.state).state !=
|
||||||
"Private") {
|
"Private") {
|
||||||
ref.read(feeSheetSessionCacheProvider).fast[amount] =
|
ref.read(feeSheetSessionCacheProvider).fast[amount] =
|
||||||
Format.satoshisToAmount(await (manager.wallet as FiroWallet)
|
Format.satoshisToAmount(
|
||||||
.estimateFeeForPublic(amount, feeRate));
|
await (manager.wallet as FiroWallet)
|
||||||
|
.estimateFeeForPublic(amount, feeRate),
|
||||||
|
coin: coin);
|
||||||
} else {
|
} else {
|
||||||
ref.read(feeSheetSessionCacheProvider).fast[amount] =
|
ref.read(feeSheetSessionCacheProvider).fast[amount] =
|
||||||
Format.satoshisToAmount(
|
Format.satoshisToAmount(
|
||||||
await manager.estimateFeeFor(amount, feeRate));
|
await manager.estimateFeeFor(amount, feeRate),
|
||||||
|
coin: coin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ref.read(feeSheetSessionCacheProvider).fast[amount]!;
|
return ref.read(feeSheetSessionCacheProvider).fast[amount]!;
|
||||||
|
@ -74,16 +86,27 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
|
||||||
final manager =
|
final manager =
|
||||||
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
||||||
|
|
||||||
if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
if (coin == Coin.monero || coin == Coin.wownero) {
|
||||||
|
final fee = await manager.estimateFeeFor(
|
||||||
|
amount, MoneroTransactionPriority.regular.raw!);
|
||||||
|
ref.read(feeSheetSessionCacheProvider).average[amount] =
|
||||||
|
Format.satoshisToAmount(
|
||||||
|
fee,
|
||||||
|
coin: coin,
|
||||||
|
);
|
||||||
|
} else if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
||||||
ref.read(publicPrivateBalanceStateProvider.state).state !=
|
ref.read(publicPrivateBalanceStateProvider.state).state !=
|
||||||
"Private") {
|
"Private") {
|
||||||
ref.read(feeSheetSessionCacheProvider).average[amount] =
|
ref.read(feeSheetSessionCacheProvider).average[amount] =
|
||||||
Format.satoshisToAmount(await (manager.wallet as FiroWallet)
|
Format.satoshisToAmount(
|
||||||
.estimateFeeForPublic(amount, feeRate));
|
await (manager.wallet as FiroWallet)
|
||||||
|
.estimateFeeForPublic(amount, feeRate),
|
||||||
|
coin: coin);
|
||||||
} else {
|
} else {
|
||||||
ref.read(feeSheetSessionCacheProvider).average[amount] =
|
ref.read(feeSheetSessionCacheProvider).average[amount] =
|
||||||
Format.satoshisToAmount(
|
Format.satoshisToAmount(
|
||||||
await manager.estimateFeeFor(amount, feeRate));
|
await manager.estimateFeeFor(amount, feeRate),
|
||||||
|
coin: coin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ref.read(feeSheetSessionCacheProvider).average[amount]!;
|
return ref.read(feeSheetSessionCacheProvider).average[amount]!;
|
||||||
|
@ -93,47 +116,33 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
|
||||||
final manager =
|
final manager =
|
||||||
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
ref.read(walletsChangeNotifierProvider).getManager(walletId);
|
||||||
|
|
||||||
if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
if (coin == Coin.monero || coin == Coin.wownero) {
|
||||||
|
final fee = await manager.estimateFeeFor(
|
||||||
|
amount, MoneroTransactionPriority.slow.raw!);
|
||||||
|
ref.read(feeSheetSessionCacheProvider).slow[amount] =
|
||||||
|
Format.satoshisToAmount(
|
||||||
|
fee,
|
||||||
|
coin: coin,
|
||||||
|
);
|
||||||
|
} else if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
|
||||||
ref.read(publicPrivateBalanceStateProvider.state).state !=
|
ref.read(publicPrivateBalanceStateProvider.state).state !=
|
||||||
"Private") {
|
"Private") {
|
||||||
ref.read(feeSheetSessionCacheProvider).slow[amount] =
|
ref.read(feeSheetSessionCacheProvider).slow[amount] =
|
||||||
Format.satoshisToAmount(await (manager.wallet as FiroWallet)
|
Format.satoshisToAmount(
|
||||||
.estimateFeeForPublic(amount, feeRate));
|
await (manager.wallet as FiroWallet)
|
||||||
|
.estimateFeeForPublic(amount, feeRate),
|
||||||
|
coin: coin);
|
||||||
} else {
|
} else {
|
||||||
ref.read(feeSheetSessionCacheProvider).slow[amount] =
|
ref.read(feeSheetSessionCacheProvider).slow[amount] =
|
||||||
Format.satoshisToAmount(
|
Format.satoshisToAmount(
|
||||||
await manager.estimateFeeFor(amount, feeRate));
|
await manager.estimateFeeFor(amount, feeRate),
|
||||||
|
coin: coin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ref.read(feeSheetSessionCacheProvider).slow[amount]!;
|
return ref.read(feeSheetSessionCacheProvider).slow[amount]!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String estimatedTimeToBeIncludedInNextBlock(
|
|
||||||
int targetBlockTime, int estimatedNumberOfBlocks) {
|
|
||||||
int time = targetBlockTime * estimatedNumberOfBlocks;
|
|
||||||
|
|
||||||
int hours = (time / 3600).floor();
|
|
||||||
if (hours > 1) {
|
|
||||||
return "~$hours hours";
|
|
||||||
} else if (hours == 1) {
|
|
||||||
return "~$hours hour";
|
|
||||||
}
|
|
||||||
|
|
||||||
// less than an hour
|
|
||||||
|
|
||||||
final string = (time / 60).toStringAsFixed(1);
|
|
||||||
|
|
||||||
if (string == "1.0") {
|
|
||||||
return "~1 minute";
|
|
||||||
} else {
|
|
||||||
if (string.endsWith(".0")) {
|
|
||||||
return "~${(time / 60).floor()} minutes";
|
|
||||||
}
|
|
||||||
return "~$string minutes";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
walletId = widget.walletId;
|
walletId = widget.walletId;
|
||||||
|
@ -307,7 +316,7 @@ class FeeDropDownChild extends ConsumerWidget {
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: feeFor(
|
future: feeFor(
|
||||||
coin: manager.coin,
|
coin: manager.coin,
|
||||||
feeRateType: FeeRateType.fast,
|
feeRateType: feeRateType,
|
||||||
feeRate: feeRateType == FeeRateType.fast
|
feeRate: feeRateType == FeeRateType.fast
|
||||||
? feeObject!.fast
|
? feeObject!.fast
|
||||||
: feeRateType == FeeRateType.slow
|
: feeRateType == FeeRateType.slow
|
||||||
|
@ -315,6 +324,7 @@ class FeeDropDownChild extends ConsumerWidget {
|
||||||
: feeObject!.medium,
|
: feeObject!.medium,
|
||||||
amount: Format.decimalAmountToSatoshis(
|
amount: Format.decimalAmountToSatoshis(
|
||||||
ref.watch(sendAmountProvider.state).state,
|
ref.watch(sendAmountProvider.state).state,
|
||||||
|
manager.coin,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
builder: (_, AsyncSnapshot<Decimal> snapshot) {
|
builder: (_, AsyncSnapshot<Decimal> snapshot) {
|
||||||
|
|
|
@ -161,20 +161,22 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final amount = Format.decimalAmountToSatoshis(_amountToSend!);
|
final amount = Format.decimalAmountToSatoshis(_amountToSend!, coin);
|
||||||
int availableBalance;
|
int availableBalance;
|
||||||
if ((coin == Coin.firo || coin == Coin.firoTestNet)) {
|
if ((coin == Coin.firo || coin == Coin.firoTestNet)) {
|
||||||
if (ref.read(publicPrivateBalanceStateProvider.state).state ==
|
if (ref.read(publicPrivateBalanceStateProvider.state).state ==
|
||||||
"Private") {
|
"Private") {
|
||||||
availableBalance = Format.decimalAmountToSatoshis(
|
availableBalance = Format.decimalAmountToSatoshis(
|
||||||
await (manager.wallet as FiroWallet).availablePrivateBalance());
|
await (manager.wallet as FiroWallet).availablePrivateBalance(),
|
||||||
|
coin);
|
||||||
} else {
|
} else {
|
||||||
availableBalance = Format.decimalAmountToSatoshis(
|
availableBalance = Format.decimalAmountToSatoshis(
|
||||||
await (manager.wallet as FiroWallet).availablePublicBalance());
|
await (manager.wallet as FiroWallet).availablePublicBalance(),
|
||||||
|
coin);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
availableBalance =
|
availableBalance =
|
||||||
Format.decimalAmountToSatoshis(await manager.availableBalance);
|
Format.decimalAmountToSatoshis(await manager.availableBalance, coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// confirm send all
|
// confirm send all
|
||||||
|
@ -642,7 +644,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
||||||
cryptoAmountController.text = Format.localizedStringAsFixed(
|
cryptoAmountController.text = Format.localizedStringAsFixed(
|
||||||
value: amount,
|
value: amount,
|
||||||
locale: ref.read(localeServiceChangeNotifierProvider).locale,
|
locale: ref.read(localeServiceChangeNotifierProvider).locale,
|
||||||
decimalPlaces: Constants.decimalPlaces,
|
decimalPlaces: Constants.decimalPlacesForCoin(coin),
|
||||||
);
|
);
|
||||||
amount.toString();
|
amount.toString();
|
||||||
_amountToSend = amount;
|
_amountToSend = amount;
|
||||||
|
@ -709,8 +711,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
||||||
} else {
|
} else {
|
||||||
_amountToSend = baseAmount <= Decimal.zero
|
_amountToSend = baseAmount <= Decimal.zero
|
||||||
? Decimal.zero
|
? Decimal.zero
|
||||||
: (baseAmount / _price)
|
: (baseAmount / _price).toDecimal(
|
||||||
.toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces);
|
scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin));
|
||||||
}
|
}
|
||||||
if (_cachedAmountToSend != null && _cachedAmountToSend == _amountToSend) {
|
if (_cachedAmountToSend != null && _cachedAmountToSend == _amountToSend) {
|
||||||
return;
|
return;
|
||||||
|
@ -722,7 +724,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
||||||
final amountString = Format.localizedStringAsFixed(
|
final amountString = Format.localizedStringAsFixed(
|
||||||
value: _amountToSend!,
|
value: _amountToSend!,
|
||||||
locale: ref.read(localeServiceChangeNotifierProvider).locale,
|
locale: ref.read(localeServiceChangeNotifierProvider).locale,
|
||||||
decimalPlaces: Constants.decimalPlaces,
|
decimalPlaces: Constants.decimalPlacesForCoin(coin),
|
||||||
);
|
);
|
||||||
|
|
||||||
_cryptoAmountChangeLock = true;
|
_cryptoAmountChangeLock = true;
|
||||||
|
@ -752,18 +754,18 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
||||||
"Private") {
|
"Private") {
|
||||||
cryptoAmountController.text =
|
cryptoAmountController.text =
|
||||||
(await firoWallet.availablePrivateBalance())
|
(await firoWallet.availablePrivateBalance())
|
||||||
.toStringAsFixed(Constants.decimalPlaces);
|
.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
|
||||||
} else {
|
} else {
|
||||||
cryptoAmountController.text =
|
cryptoAmountController.text =
|
||||||
(await firoWallet.availablePublicBalance())
|
(await firoWallet.availablePublicBalance())
|
||||||
.toStringAsFixed(Constants.decimalPlaces);
|
.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cryptoAmountController.text = (await ref
|
cryptoAmountController.text = (await ref
|
||||||
.read(walletsChangeNotifierProvider)
|
.read(walletsChangeNotifierProvider)
|
||||||
.getManager(walletId)
|
.getManager(walletId)
|
||||||
.availableBalance)
|
.availableBalance)
|
||||||
.toStringAsFixed(Constants.decimalPlaces);
|
.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,58 @@ class _UnlockWalletKeysDesktopState
|
||||||
bool continueEnabled = false;
|
bool continueEnabled = false;
|
||||||
bool hidePassword = true;
|
bool hidePassword = true;
|
||||||
|
|
||||||
|
Future<void> enterPassphrase() async {
|
||||||
|
unawaited(
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: const [
|
||||||
|
LoadingIndicator(
|
||||||
|
width: 200,
|
||||||
|
height: 200,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await Future<void>.delayed(const Duration(seconds: 1));
|
||||||
|
|
||||||
|
final verified = await ref
|
||||||
|
.read(storageCryptoHandlerProvider)
|
||||||
|
.verifyPassphrase(passwordController.text);
|
||||||
|
|
||||||
|
if (verified) {
|
||||||
|
Navigator.of(context, rootNavigator: true).pop();
|
||||||
|
|
||||||
|
final words = await ref
|
||||||
|
.read(walletsChangeNotifierProvider)
|
||||||
|
.getManager(widget.walletId)
|
||||||
|
.mnemonic;
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
await Navigator.of(context).pushReplacementNamed(
|
||||||
|
WalletKeysDesktopPopup.routeName,
|
||||||
|
arguments: words,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Navigator.of(context, rootNavigator: true).pop();
|
||||||
|
|
||||||
|
await Future<void>.delayed(const Duration(milliseconds: 300));
|
||||||
|
|
||||||
|
unawaited(
|
||||||
|
showFloatingFlushBar(
|
||||||
|
type: FlushBarType.warning,
|
||||||
|
message: "Invalid passphrase!",
|
||||||
|
context: context,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
passwordController = TextEditingController();
|
passwordController = TextEditingController();
|
||||||
|
@ -120,6 +172,12 @@ class _UnlockWalletKeysDesktopState
|
||||||
obscureText: hidePassword,
|
obscureText: hidePassword,
|
||||||
enableSuggestions: false,
|
enableSuggestions: false,
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
|
autofocus: true,
|
||||||
|
onSubmitted: (_) {
|
||||||
|
if (continueEnabled) {
|
||||||
|
enterPassphrase();
|
||||||
|
}
|
||||||
|
},
|
||||||
decoration: standardInputDecoration(
|
decoration: standardInputDecoration(
|
||||||
"Enter password",
|
"Enter password",
|
||||||
passwordFocusNode,
|
passwordFocusNode,
|
||||||
|
|
|
@ -200,19 +200,21 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
Future<Decimal> get availableBalance async {
|
Future<Decimal> get availableBalance async {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(
|
return Format.satoshisToAmount(
|
||||||
data.satoshiBalance - data.satoshiBalanceUnconfirmed);
|
data.satoshiBalance - data.satoshiBalanceUnconfirmed,
|
||||||
|
coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Decimal> get pendingBalance async {
|
Future<Decimal> get pendingBalance async {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed);
|
return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Decimal> get balanceMinusMaxFee async =>
|
Future<Decimal> get balanceMinusMaxFee async =>
|
||||||
(await availableBalance) -
|
(await availableBalance) -
|
||||||
(Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
|
(Decimal.fromInt((await maxFee)) /
|
||||||
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal();
|
.toDecimal();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -222,13 +224,13 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
.get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
|
.get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
|
||||||
if (totalBalance == null) {
|
if (totalBalance == null) {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalance);
|
return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
|
||||||
} else {
|
} else {
|
||||||
return Format.satoshisToAmount(totalBalance);
|
return Format.satoshisToAmount(totalBalance, coin: coin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalance);
|
return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -266,7 +268,8 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
@override
|
@override
|
||||||
Future<int> get maxFee async {
|
Future<int> get maxFee async {
|
||||||
final fee = (await fees).fast as String;
|
final fee = (await fees).fast as String;
|
||||||
final satsFee = Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin);
|
final satsFee =
|
||||||
|
Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin(coin));
|
||||||
return satsFee.floor().toBigInt().toInt();
|
return satsFee.floor().toBigInt().toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1093,7 +1096,8 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
// check for send all
|
// check for send all
|
||||||
bool isSendAll = false;
|
bool isSendAll = false;
|
||||||
final balance = Format.decimalAmountToSatoshis(await availableBalance);
|
final balance =
|
||||||
|
Format.decimalAmountToSatoshis(await availableBalance, coin);
|
||||||
if (satoshiAmount == balance) {
|
if (satoshiAmount == balance) {
|
||||||
isSendAll = true;
|
isSendAll = true;
|
||||||
}
|
}
|
||||||
|
@ -1297,7 +1301,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
final String worthNow = Format.localizedStringAsFixed(
|
final String worthNow = Format.localizedStringAsFixed(
|
||||||
value:
|
value:
|
||||||
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
|
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2),
|
.toDecimal(scaleOnInfinitePrecision: 2),
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
locale: locale!);
|
locale: locale!);
|
||||||
|
@ -1497,9 +1501,9 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
numberOfBlocksFast: f,
|
numberOfBlocksFast: f,
|
||||||
numberOfBlocksAverage: m,
|
numberOfBlocksAverage: m,
|
||||||
numberOfBlocksSlow: s,
|
numberOfBlocksSlow: s,
|
||||||
fast: Format.decimalAmountToSatoshis(fast),
|
fast: Format.decimalAmountToSatoshis(fast, coin),
|
||||||
medium: Format.decimalAmountToSatoshis(medium),
|
medium: Format.decimalAmountToSatoshis(medium, coin),
|
||||||
slow: Format.decimalAmountToSatoshis(slow),
|
slow: Format.decimalAmountToSatoshis(slow, coin),
|
||||||
);
|
);
|
||||||
|
|
||||||
Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
|
Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
|
||||||
|
@ -1968,7 +1972,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
utxo["status"]["block_time"] = txn["blocktime"];
|
utxo["status"]["block_time"] = txn["blocktime"];
|
||||||
|
|
||||||
final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
|
final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2);
|
.toDecimal(scaleOnInfinitePrecision: 2);
|
||||||
utxo["rawWorth"] = fiatValue;
|
utxo["rawWorth"] = fiatValue;
|
||||||
utxo["fiatWorth"] = fiatValue.toString();
|
utxo["fiatWorth"] = fiatValue.toString();
|
||||||
|
@ -1978,15 +1982,16 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
Decimal currencyBalanceRaw =
|
Decimal currencyBalanceRaw =
|
||||||
((Decimal.fromInt(satoshiBalance) * currentPrice) /
|
((Decimal.fromInt(satoshiBalance) * currentPrice) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2);
|
.toDecimal(scaleOnInfinitePrecision: 2);
|
||||||
|
|
||||||
final Map<String, dynamic> result = {
|
final Map<String, dynamic> result = {
|
||||||
"total_user_currency": currencyBalanceRaw.toString(),
|
"total_user_currency": currencyBalanceRaw.toString(),
|
||||||
"total_sats": satoshiBalance,
|
"total_sats": satoshiBalance,
|
||||||
"total_btc": (Decimal.fromInt(satoshiBalance) /
|
"total_btc": (Decimal.fromInt(satoshiBalance) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
|
.toDecimal(
|
||||||
|
scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin))
|
||||||
.toString(),
|
.toString(),
|
||||||
"outputArray": outputArray,
|
"outputArray": outputArray,
|
||||||
"unconfirmed": satoshiBalancePending,
|
"unconfirmed": satoshiBalancePending,
|
||||||
|
@ -2532,7 +2537,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
if (prevOut == out["n"]) {
|
if (prevOut == out["n"]) {
|
||||||
inputAmtSentFromWallet +=
|
inputAmtSentFromWallet +=
|
||||||
(Decimal.parse(out["value"]!.toString()) *
|
(Decimal.parse(out["value"]!.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -2545,7 +2550,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
final String address = output["scriptPubKey"]!["address"] as String;
|
final String address = output["scriptPubKey"]!["address"] as String;
|
||||||
final value = output["value"]!;
|
final value = output["value"]!;
|
||||||
final _value = (Decimal.parse(value.toString()) *
|
final _value = (Decimal.parse(value.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
totalOutput += _value;
|
totalOutput += _value;
|
||||||
|
@ -2570,7 +2575,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
final address = output["scriptPubKey"]["address"];
|
final address = output["scriptPubKey"]["address"];
|
||||||
if (address != null) {
|
if (address != null) {
|
||||||
final value = (Decimal.parse(output["value"].toString()) *
|
final value = (Decimal.parse(output["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
totalOut += value;
|
totalOut += value;
|
||||||
|
@ -2593,7 +2598,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
for (final out in tx["vout"] as List) {
|
for (final out in tx["vout"] as List) {
|
||||||
if (prevOut == out["n"]) {
|
if (prevOut == out["n"]) {
|
||||||
totalIn += (Decimal.parse(out["value"].toString()) *
|
totalIn += (Decimal.parse(out["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -2615,7 +2620,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
midSortedTx["amount"] = inputAmtSentFromWallet;
|
midSortedTx["amount"] = inputAmtSentFromWallet;
|
||||||
final String worthNow =
|
final String worthNow =
|
||||||
((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
|
((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2)
|
.toDecimal(scaleOnInfinitePrecision: 2)
|
||||||
.toStringAsFixed(2);
|
.toStringAsFixed(2);
|
||||||
midSortedTx["worthNow"] = worthNow;
|
midSortedTx["worthNow"] = worthNow;
|
||||||
|
@ -2625,7 +2630,7 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
midSortedTx["amount"] = outputAmtAddressedToWallet;
|
midSortedTx["amount"] = outputAmtAddressedToWallet;
|
||||||
final worthNow =
|
final worthNow =
|
||||||
((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
|
((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2)
|
.toDecimal(scaleOnInfinitePrecision: 2)
|
||||||
.toStringAsFixed(2);
|
.toStringAsFixed(2);
|
||||||
midSortedTx["worthNow"] = worthNow;
|
midSortedTx["worthNow"] = worthNow;
|
||||||
|
@ -3753,7 +3758,8 @@ class BitcoinWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
||||||
final available = Format.decimalAmountToSatoshis(await availableBalance);
|
final available =
|
||||||
|
Format.decimalAmountToSatoshis(await availableBalance, coin);
|
||||||
|
|
||||||
if (available == satoshiAmount) {
|
if (available == satoshiAmount) {
|
||||||
return satoshiAmount - sweepAllEstimate(feeRate);
|
return satoshiAmount - sweepAllEstimate(feeRate);
|
||||||
|
|
|
@ -170,19 +170,21 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
Future<Decimal> get availableBalance async {
|
Future<Decimal> get availableBalance async {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(
|
return Format.satoshisToAmount(
|
||||||
data.satoshiBalance - data.satoshiBalanceUnconfirmed);
|
data.satoshiBalance - data.satoshiBalanceUnconfirmed,
|
||||||
|
coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Decimal> get pendingBalance async {
|
Future<Decimal> get pendingBalance async {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed);
|
return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Decimal> get balanceMinusMaxFee async =>
|
Future<Decimal> get balanceMinusMaxFee async =>
|
||||||
(await availableBalance) -
|
(await availableBalance) -
|
||||||
(Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
|
(Decimal.fromInt((await maxFee)) /
|
||||||
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal();
|
.toDecimal();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -192,13 +194,13 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
.get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
|
.get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
|
||||||
if (totalBalance == null) {
|
if (totalBalance == null) {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalance);
|
return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
|
||||||
} else {
|
} else {
|
||||||
return Format.satoshisToAmount(totalBalance);
|
return Format.satoshisToAmount(totalBalance, coin: coin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalance);
|
return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -232,8 +234,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
@override
|
@override
|
||||||
Future<int> get maxFee async {
|
Future<int> get maxFee async {
|
||||||
final fee = (await fees).fast;
|
final fee = (await fees).fast;
|
||||||
final satsFee =
|
final satsFee = Format.satoshisToAmount(fee, coin: coin) *
|
||||||
Format.satoshisToAmount(fee) * Decimal.fromInt(Constants.satsPerCoin);
|
Decimal.fromInt(Constants.satsPerCoin(coin));
|
||||||
return satsFee.floor().toBigInt().toInt();
|
return satsFee.floor().toBigInt().toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -988,7 +990,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
}
|
}
|
||||||
// check for send all
|
// check for send all
|
||||||
bool isSendAll = false;
|
bool isSendAll = false;
|
||||||
final balance = Format.decimalAmountToSatoshis(await availableBalance);
|
final balance =
|
||||||
|
Format.decimalAmountToSatoshis(await availableBalance, coin);
|
||||||
if (satoshiAmount == balance) {
|
if (satoshiAmount == balance) {
|
||||||
isSendAll = true;
|
isSendAll = true;
|
||||||
}
|
}
|
||||||
|
@ -1175,7 +1178,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
final String worthNow = Format.localizedStringAsFixed(
|
final String worthNow = Format.localizedStringAsFixed(
|
||||||
value:
|
value:
|
||||||
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
|
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2),
|
.toDecimal(scaleOnInfinitePrecision: 2),
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
locale: locale!);
|
locale: locale!);
|
||||||
|
@ -1384,9 +1387,9 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
numberOfBlocksFast: f,
|
numberOfBlocksFast: f,
|
||||||
numberOfBlocksAverage: m,
|
numberOfBlocksAverage: m,
|
||||||
numberOfBlocksSlow: s,
|
numberOfBlocksSlow: s,
|
||||||
fast: Format.decimalAmountToSatoshis(fast),
|
fast: Format.decimalAmountToSatoshis(fast, coin),
|
||||||
medium: Format.decimalAmountToSatoshis(medium),
|
medium: Format.decimalAmountToSatoshis(medium, coin),
|
||||||
slow: Format.decimalAmountToSatoshis(slow),
|
slow: Format.decimalAmountToSatoshis(slow, coin),
|
||||||
);
|
);
|
||||||
|
|
||||||
Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
|
Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
|
||||||
|
@ -1791,7 +1794,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
utxo["status"]["block_time"] = txn["blocktime"];
|
utxo["status"]["block_time"] = txn["blocktime"];
|
||||||
|
|
||||||
final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
|
final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2);
|
.toDecimal(scaleOnInfinitePrecision: 2);
|
||||||
utxo["rawWorth"] = fiatValue;
|
utxo["rawWorth"] = fiatValue;
|
||||||
utxo["fiatWorth"] = fiatValue.toString();
|
utxo["fiatWorth"] = fiatValue.toString();
|
||||||
|
@ -1801,15 +1804,16 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
Decimal currencyBalanceRaw =
|
Decimal currencyBalanceRaw =
|
||||||
((Decimal.fromInt(satoshiBalance) * currentPrice) /
|
((Decimal.fromInt(satoshiBalance) * currentPrice) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2);
|
.toDecimal(scaleOnInfinitePrecision: 2);
|
||||||
|
|
||||||
final Map<String, dynamic> result = {
|
final Map<String, dynamic> result = {
|
||||||
"total_user_currency": currencyBalanceRaw.toString(),
|
"total_user_currency": currencyBalanceRaw.toString(),
|
||||||
"total_sats": satoshiBalance,
|
"total_sats": satoshiBalance,
|
||||||
"total_btc": (Decimal.fromInt(satoshiBalance) /
|
"total_btc": (Decimal.fromInt(satoshiBalance) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
|
.toDecimal(
|
||||||
|
scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin))
|
||||||
.toString(),
|
.toString(),
|
||||||
"outputArray": outputArray,
|
"outputArray": outputArray,
|
||||||
"unconfirmed": satoshiBalancePending,
|
"unconfirmed": satoshiBalancePending,
|
||||||
|
@ -2332,7 +2336,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
if (prevOut == out["n"]) {
|
if (prevOut == out["n"]) {
|
||||||
inputAmtSentFromWallet +=
|
inputAmtSentFromWallet +=
|
||||||
(Decimal.parse(out["value"].toString()) *
|
(Decimal.parse(out["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -2345,7 +2349,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
final address = output["scriptPubKey"]["addresses"][0];
|
final address = output["scriptPubKey"]["addresses"][0];
|
||||||
final value = output["value"];
|
final value = output["value"];
|
||||||
final _value = (Decimal.parse(value.toString()) *
|
final _value = (Decimal.parse(value.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
totalOutput += _value;
|
totalOutput += _value;
|
||||||
|
@ -2370,7 +2374,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
final address = output["scriptPubKey"]["addresses"][0];
|
final address = output["scriptPubKey"]["addresses"][0];
|
||||||
if (address != null) {
|
if (address != null) {
|
||||||
final value = (Decimal.parse(output["value"].toString()) *
|
final value = (Decimal.parse(output["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
totalOut += value;
|
totalOut += value;
|
||||||
|
@ -2394,7 +2398,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
for (final out in tx["vout"] as List) {
|
for (final out in tx["vout"] as List) {
|
||||||
if (prevOut == out["n"]) {
|
if (prevOut == out["n"]) {
|
||||||
totalIn += (Decimal.parse(out["value"].toString()) *
|
totalIn += (Decimal.parse(out["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -2416,7 +2420,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
midSortedTx["amount"] = inputAmtSentFromWallet;
|
midSortedTx["amount"] = inputAmtSentFromWallet;
|
||||||
final String worthNow =
|
final String worthNow =
|
||||||
((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
|
((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2)
|
.toDecimal(scaleOnInfinitePrecision: 2)
|
||||||
.toStringAsFixed(2);
|
.toStringAsFixed(2);
|
||||||
midSortedTx["worthNow"] = worthNow;
|
midSortedTx["worthNow"] = worthNow;
|
||||||
|
@ -2426,7 +2430,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
midSortedTx["amount"] = outputAmtAddressedToWallet;
|
midSortedTx["amount"] = outputAmtAddressedToWallet;
|
||||||
final worthNow =
|
final worthNow =
|
||||||
((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
|
((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2)
|
.toDecimal(scaleOnInfinitePrecision: 2)
|
||||||
.toStringAsFixed(2);
|
.toStringAsFixed(2);
|
||||||
midSortedTx["worthNow"] = worthNow;
|
midSortedTx["worthNow"] = worthNow;
|
||||||
|
@ -3457,7 +3461,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
||||||
final available = Format.decimalAmountToSatoshis(await availableBalance);
|
final available =
|
||||||
|
Format.decimalAmountToSatoshis(await availableBalance, coin);
|
||||||
|
|
||||||
if (available == satoshiAmount) {
|
if (available == satoshiAmount) {
|
||||||
return satoshiAmount - sweepAllEstimate(feeRate);
|
return satoshiAmount - sweepAllEstimate(feeRate);
|
||||||
|
|
|
@ -167,19 +167,21 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
Future<Decimal> get availableBalance async {
|
Future<Decimal> get availableBalance async {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(
|
return Format.satoshisToAmount(
|
||||||
data.satoshiBalance - data.satoshiBalanceUnconfirmed);
|
data.satoshiBalance - data.satoshiBalanceUnconfirmed,
|
||||||
|
coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Decimal> get pendingBalance async {
|
Future<Decimal> get pendingBalance async {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed);
|
return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Decimal> get balanceMinusMaxFee async =>
|
Future<Decimal> get balanceMinusMaxFee async =>
|
||||||
(await availableBalance) -
|
(await availableBalance) -
|
||||||
(Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
|
(Decimal.fromInt((await maxFee)) /
|
||||||
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal();
|
.toDecimal();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -189,13 +191,13 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
.get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
|
.get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
|
||||||
if (totalBalance == null) {
|
if (totalBalance == null) {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalance);
|
return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
|
||||||
} else {
|
} else {
|
||||||
return Format.satoshisToAmount(totalBalance);
|
return Format.satoshisToAmount(totalBalance, coin: coin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalance);
|
return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -225,8 +227,8 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
@override
|
@override
|
||||||
Future<int> get maxFee async {
|
Future<int> get maxFee async {
|
||||||
final fee = (await fees).fast;
|
final fee = (await fees).fast;
|
||||||
final satsFee =
|
final satsFee = Format.satoshisToAmount(fee, coin: coin) *
|
||||||
Format.satoshisToAmount(fee) * Decimal.fromInt(Constants.satsPerCoin);
|
Decimal.fromInt(Constants.satsPerCoin(coin));
|
||||||
return satsFee.floor().toBigInt().toInt();
|
return satsFee.floor().toBigInt().toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -878,7 +880,8 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
}
|
}
|
||||||
// check for send all
|
// check for send all
|
||||||
bool isSendAll = false;
|
bool isSendAll = false;
|
||||||
final balance = Format.decimalAmountToSatoshis(await availableBalance);
|
final balance =
|
||||||
|
Format.decimalAmountToSatoshis(await availableBalance, coin);
|
||||||
if (satoshiAmount == balance) {
|
if (satoshiAmount == balance) {
|
||||||
isSendAll = true;
|
isSendAll = true;
|
||||||
}
|
}
|
||||||
|
@ -1065,7 +1068,7 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
final String worthNow = Format.localizedStringAsFixed(
|
final String worthNow = Format.localizedStringAsFixed(
|
||||||
value:
|
value:
|
||||||
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
|
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2),
|
.toDecimal(scaleOnInfinitePrecision: 2),
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
locale: locale!);
|
locale: locale!);
|
||||||
|
@ -1247,9 +1250,9 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
numberOfBlocksFast: f,
|
numberOfBlocksFast: f,
|
||||||
numberOfBlocksAverage: m,
|
numberOfBlocksAverage: m,
|
||||||
numberOfBlocksSlow: s,
|
numberOfBlocksSlow: s,
|
||||||
fast: Format.decimalAmountToSatoshis(fast),
|
fast: Format.decimalAmountToSatoshis(fast, coin),
|
||||||
medium: Format.decimalAmountToSatoshis(medium),
|
medium: Format.decimalAmountToSatoshis(medium, coin),
|
||||||
slow: Format.decimalAmountToSatoshis(slow),
|
slow: Format.decimalAmountToSatoshis(slow, coin),
|
||||||
);
|
);
|
||||||
|
|
||||||
Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
|
Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
|
||||||
|
@ -1650,7 +1653,7 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
utxo["status"]["block_time"] = txn["blocktime"];
|
utxo["status"]["block_time"] = txn["blocktime"];
|
||||||
|
|
||||||
final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
|
final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2);
|
.toDecimal(scaleOnInfinitePrecision: 2);
|
||||||
utxo["rawWorth"] = fiatValue;
|
utxo["rawWorth"] = fiatValue;
|
||||||
utxo["fiatWorth"] = fiatValue.toString();
|
utxo["fiatWorth"] = fiatValue.toString();
|
||||||
|
@ -1660,15 +1663,16 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
Decimal currencyBalanceRaw =
|
Decimal currencyBalanceRaw =
|
||||||
((Decimal.fromInt(satoshiBalance) * currentPrice) /
|
((Decimal.fromInt(satoshiBalance) * currentPrice) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2);
|
.toDecimal(scaleOnInfinitePrecision: 2);
|
||||||
|
|
||||||
final Map<String, dynamic> result = {
|
final Map<String, dynamic> result = {
|
||||||
"total_user_currency": currencyBalanceRaw.toString(),
|
"total_user_currency": currencyBalanceRaw.toString(),
|
||||||
"total_sats": satoshiBalance,
|
"total_sats": satoshiBalance,
|
||||||
"total_btc": (Decimal.fromInt(satoshiBalance) /
|
"total_btc": (Decimal.fromInt(satoshiBalance) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
|
.toDecimal(
|
||||||
|
scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin))
|
||||||
.toString(),
|
.toString(),
|
||||||
"outputArray": outputArray,
|
"outputArray": outputArray,
|
||||||
"unconfirmed": satoshiBalancePending,
|
"unconfirmed": satoshiBalancePending,
|
||||||
|
@ -2144,7 +2148,7 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
if (prevOut == out["n"]) {
|
if (prevOut == out["n"]) {
|
||||||
inputAmtSentFromWallet +=
|
inputAmtSentFromWallet +=
|
||||||
(Decimal.parse(out["value"].toString()) *
|
(Decimal.parse(out["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -2157,7 +2161,7 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
final address = output["scriptPubKey"]["addresses"][0];
|
final address = output["scriptPubKey"]["addresses"][0];
|
||||||
final value = output["value"];
|
final value = output["value"];
|
||||||
final _value = (Decimal.parse(value.toString()) *
|
final _value = (Decimal.parse(value.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
totalOutput += _value;
|
totalOutput += _value;
|
||||||
|
@ -2182,7 +2186,7 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
final address = output["scriptPubKey"]["addresses"][0];
|
final address = output["scriptPubKey"]["addresses"][0];
|
||||||
if (address != null) {
|
if (address != null) {
|
||||||
final value = (Decimal.parse(output["value"].toString()) *
|
final value = (Decimal.parse(output["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
totalOut += value;
|
totalOut += value;
|
||||||
|
@ -2205,7 +2209,7 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
for (final out in tx["vout"] as List) {
|
for (final out in tx["vout"] as List) {
|
||||||
if (prevOut == out["n"]) {
|
if (prevOut == out["n"]) {
|
||||||
totalIn += (Decimal.parse(out["value"].toString()) *
|
totalIn += (Decimal.parse(out["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -2227,7 +2231,7 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
midSortedTx["amount"] = inputAmtSentFromWallet;
|
midSortedTx["amount"] = inputAmtSentFromWallet;
|
||||||
final String worthNow =
|
final String worthNow =
|
||||||
((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
|
((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2)
|
.toDecimal(scaleOnInfinitePrecision: 2)
|
||||||
.toStringAsFixed(2);
|
.toStringAsFixed(2);
|
||||||
midSortedTx["worthNow"] = worthNow;
|
midSortedTx["worthNow"] = worthNow;
|
||||||
|
@ -2237,7 +2241,7 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
midSortedTx["amount"] = outputAmtAddressedToWallet;
|
midSortedTx["amount"] = outputAmtAddressedToWallet;
|
||||||
final worthNow =
|
final worthNow =
|
||||||
((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
|
((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2)
|
.toDecimal(scaleOnInfinitePrecision: 2)
|
||||||
.toStringAsFixed(2);
|
.toStringAsFixed(2);
|
||||||
midSortedTx["worthNow"] = worthNow;
|
midSortedTx["worthNow"] = worthNow;
|
||||||
|
@ -3050,7 +3054,8 @@ class DogecoinWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
||||||
final available = Format.decimalAmountToSatoshis(await availableBalance);
|
final available =
|
||||||
|
Format.decimalAmountToSatoshis(await availableBalance, coin);
|
||||||
|
|
||||||
if (available == satoshiAmount) {
|
if (available == satoshiAmount) {
|
||||||
return satoshiAmount - sweepAllEstimate(feeRate);
|
return satoshiAmount - sweepAllEstimate(feeRate);
|
||||||
|
|
|
@ -620,7 +620,7 @@ Future<dynamic> isolateCreateJoinSplitTransaction(
|
||||||
"txid": txId,
|
"txid": txId,
|
||||||
"txHex": txHex,
|
"txHex": txHex,
|
||||||
"value": amount,
|
"value": amount,
|
||||||
"fees": Format.satoshisToAmount(fee).toDouble(),
|
"fees": Format.satoshisToAmount(fee, coin: coin).toDouble(),
|
||||||
"fee": fee,
|
"fee": fee,
|
||||||
"vSize": extTx.virtualSize(),
|
"vSize": extTx.virtualSize(),
|
||||||
"jmintValue": changeToMint,
|
"jmintValue": changeToMint,
|
||||||
|
@ -629,11 +629,11 @@ Future<dynamic> isolateCreateJoinSplitTransaction(
|
||||||
"height": locktime,
|
"height": locktime,
|
||||||
"txType": "Sent",
|
"txType": "Sent",
|
||||||
"confirmed_status": false,
|
"confirmed_status": false,
|
||||||
"amount": Format.satoshisToAmount(amount).toDouble(),
|
"amount": Format.satoshisToAmount(amount, coin: coin).toDouble(),
|
||||||
"recipientAmt": amount,
|
"recipientAmt": amount,
|
||||||
"worthNow": Format.localizedStringAsFixed(
|
"worthNow": Format.localizedStringAsFixed(
|
||||||
value: ((Decimal.fromInt(amount) * price) /
|
value: ((Decimal.fromInt(amount) * price) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2),
|
.toDecimal(scaleOnInfinitePrecision: 2),
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
locale: locale),
|
locale: locale),
|
||||||
|
@ -883,7 +883,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
Future<Decimal> get balanceMinusMaxFee async {
|
Future<Decimal> get balanceMinusMaxFee async {
|
||||||
final balances = await this.balances;
|
final balances = await this.balances;
|
||||||
final maxFee = await this.maxFee;
|
final maxFee = await this.maxFee;
|
||||||
return balances[0] - Format.satoshisToAmount(maxFee);
|
return balances[0] - Format.satoshisToAmount(maxFee, coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -919,7 +919,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
final String worthNow = Format.localizedStringAsFixed(
|
final String worthNow = Format.localizedStringAsFixed(
|
||||||
value:
|
value:
|
||||||
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
|
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2),
|
.toDecimal(scaleOnInfinitePrecision: 2),
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
locale: locale!);
|
locale: locale!);
|
||||||
|
@ -1089,8 +1089,8 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
// check for send all
|
// check for send all
|
||||||
bool isSendAll = false;
|
bool isSendAll = false;
|
||||||
final balance =
|
final balance = Format.decimalAmountToSatoshis(
|
||||||
Format.decimalAmountToSatoshis(await availablePublicBalance());
|
await availablePublicBalance(), coin);
|
||||||
if (satoshiAmount == balance) {
|
if (satoshiAmount == balance) {
|
||||||
isSendAll = true;
|
isSendAll = true;
|
||||||
}
|
}
|
||||||
|
@ -1176,7 +1176,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
// check for send all
|
// check for send all
|
||||||
bool isSendAll = false;
|
bool isSendAll = false;
|
||||||
final balance =
|
final balance =
|
||||||
Format.decimalAmountToSatoshis(await availablePrivateBalance());
|
Format.decimalAmountToSatoshis(await availablePrivateBalance(), coin);
|
||||||
if (satoshiAmount == balance) {
|
if (satoshiAmount == balance) {
|
||||||
// print("is send all");
|
// print("is send all");
|
||||||
isSendAll = true;
|
isSendAll = true;
|
||||||
|
@ -1222,7 +1222,8 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
// temporarily update apdate available balance until a full refresh is done
|
// temporarily update apdate available balance until a full refresh is done
|
||||||
|
|
||||||
// TODO: something here causes an exception to be thrown giving user false info that the tx failed
|
// TODO: something here causes an exception to be thrown giving user false info that the tx failed
|
||||||
Decimal sendTotal = Format.satoshisToAmount(txData["value"] as int);
|
Decimal sendTotal =
|
||||||
|
Format.satoshisToAmount(txData["value"] as int, coin: coin);
|
||||||
sendTotal += Decimal.parse(txData["fees"].toString());
|
sendTotal += Decimal.parse(txData["fees"].toString());
|
||||||
final bals = await balances;
|
final bals = await balances;
|
||||||
bals[0] -= sendTotal;
|
bals[0] -= sendTotal;
|
||||||
|
@ -1270,7 +1271,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
// temporarily update apdate available balance until a full refresh is done
|
// temporarily update apdate available balance until a full refresh is done
|
||||||
Decimal sendTotal =
|
Decimal sendTotal =
|
||||||
Format.satoshisToAmount(txHexOrError["value"] as int);
|
Format.satoshisToAmount(txHexOrError["value"] as int, coin: coin);
|
||||||
sendTotal += Decimal.parse(txHexOrError["fees"].toString());
|
sendTotal += Decimal.parse(txHexOrError["fees"].toString());
|
||||||
final bals = await balances;
|
final bals = await balances;
|
||||||
bals[0] -= sendTotal;
|
bals[0] -= sendTotal;
|
||||||
|
@ -2333,8 +2334,9 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
Future<int> _fetchMaxFee() async {
|
Future<int> _fetchMaxFee() async {
|
||||||
final balance = await availableBalance;
|
final balance = await availableBalance;
|
||||||
int spendAmount =
|
int spendAmount = (balance * Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
(balance * Decimal.fromInt(Constants.satsPerCoin)).toBigInt().toInt();
|
.toBigInt()
|
||||||
|
.toInt();
|
||||||
int fee = await estimateJoinSplitFee(spendAmount);
|
int fee = await estimateJoinSplitFee(spendAmount);
|
||||||
return fee;
|
return fee;
|
||||||
}
|
}
|
||||||
|
@ -2480,18 +2482,20 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
final int utxosIntValue = utxos.satoshiBalance;
|
final int utxosIntValue = utxos.satoshiBalance;
|
||||||
final Decimal utxosValue = Format.satoshisToAmount(utxosIntValue);
|
final Decimal utxosValue =
|
||||||
|
Format.satoshisToAmount(utxosIntValue, coin: coin);
|
||||||
|
|
||||||
List<Decimal> balances = List.empty(growable: true);
|
List<Decimal> balances = List.empty(growable: true);
|
||||||
|
|
||||||
Decimal lelantusBalance = Format.satoshisToAmount(intLelantusBalance);
|
Decimal lelantusBalance =
|
||||||
|
Format.satoshisToAmount(intLelantusBalance, coin: coin);
|
||||||
|
|
||||||
balances.add(lelantusBalance);
|
balances.add(lelantusBalance);
|
||||||
|
|
||||||
balances.add(lelantusBalance * price);
|
balances.add(lelantusBalance * price);
|
||||||
|
|
||||||
Decimal _unconfirmedLelantusBalance =
|
Decimal _unconfirmedLelantusBalance =
|
||||||
Format.satoshisToAmount(unconfirmedLelantusBalance);
|
Format.satoshisToAmount(unconfirmedLelantusBalance, coin: coin);
|
||||||
|
|
||||||
balances.add(lelantusBalance + utxosValue + _unconfirmedLelantusBalance);
|
balances.add(lelantusBalance + utxosValue + _unconfirmedLelantusBalance);
|
||||||
|
|
||||||
|
@ -2503,7 +2507,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
if (availableSats < 0) {
|
if (availableSats < 0) {
|
||||||
availableSats = 0;
|
availableSats = 0;
|
||||||
}
|
}
|
||||||
balances.add(Format.satoshisToAmount(availableSats));
|
balances.add(Format.satoshisToAmount(availableSats, coin: coin));
|
||||||
|
|
||||||
Logging.instance.log("balances $balances", level: LogLevel.Info);
|
Logging.instance.log("balances $balances", level: LogLevel.Info);
|
||||||
await DB.instance.put<dynamic>(
|
await DB.instance.put<dynamic>(
|
||||||
|
@ -2601,7 +2605,8 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
final feesObject = await fees;
|
final feesObject = await fees;
|
||||||
|
|
||||||
final Decimal fastFee = Format.satoshisToAmount(feesObject.fast);
|
final Decimal fastFee =
|
||||||
|
Format.satoshisToAmount(feesObject.fast, coin: coin);
|
||||||
int firoFee =
|
int firoFee =
|
||||||
(dvsize * fastFee * Decimal.fromInt(100000)).toDouble().ceil();
|
(dvsize * fastFee * Decimal.fromInt(100000)).toDouble().ceil();
|
||||||
// int firoFee = (vsize * feesObject.fast * (1 / 1000.0) * 100000000).ceil();
|
// int firoFee = (vsize * feesObject.fast * (1 / 1000.0) * 100000000).ceil();
|
||||||
|
@ -2789,15 +2794,15 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
"txid": txId,
|
"txid": txId,
|
||||||
"txHex": txHex,
|
"txHex": txHex,
|
||||||
"value": amount - fee,
|
"value": amount - fee,
|
||||||
"fees": Format.satoshisToAmount(fee).toDouble(),
|
"fees": Format.satoshisToAmount(fee, coin: coin).toDouble(),
|
||||||
"publicCoin": "",
|
"publicCoin": "",
|
||||||
"height": height,
|
"height": height,
|
||||||
"txType": "Sent",
|
"txType": "Sent",
|
||||||
"confirmed_status": false,
|
"confirmed_status": false,
|
||||||
"amount": Format.satoshisToAmount(amount).toDouble(),
|
"amount": Format.satoshisToAmount(amount, coin: coin).toDouble(),
|
||||||
"worthNow": Format.localizedStringAsFixed(
|
"worthNow": Format.localizedStringAsFixed(
|
||||||
value: ((Decimal.fromInt(amount) * price) /
|
value: ((Decimal.fromInt(amount) * price) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2),
|
.toDecimal(scaleOnInfinitePrecision: 2),
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
locale: locale!),
|
locale: locale!),
|
||||||
|
@ -3040,9 +3045,9 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
numberOfBlocksFast: f,
|
numberOfBlocksFast: f,
|
||||||
numberOfBlocksAverage: m,
|
numberOfBlocksAverage: m,
|
||||||
numberOfBlocksSlow: s,
|
numberOfBlocksSlow: s,
|
||||||
fast: Format.decimalAmountToSatoshis(fast),
|
fast: Format.decimalAmountToSatoshis(fast, coin),
|
||||||
medium: Format.decimalAmountToSatoshis(medium),
|
medium: Format.decimalAmountToSatoshis(medium, coin),
|
||||||
slow: Format.decimalAmountToSatoshis(slow),
|
slow: Format.decimalAmountToSatoshis(slow, coin),
|
||||||
);
|
);
|
||||||
|
|
||||||
Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
|
Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
|
||||||
|
@ -3328,7 +3333,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
if (nFees != null) {
|
if (nFees != null) {
|
||||||
nFeesUsed = true;
|
nFeesUsed = true;
|
||||||
fees = (Decimal.parse(nFees.toString()) *
|
fees = (Decimal.parse(nFees.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -3353,7 +3358,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
if (changeAddresses.contains(address)) {
|
if (changeAddresses.contains(address)) {
|
||||||
inputAmtSentFromWallet -= (Decimal.parse(value.toString()) *
|
inputAmtSentFromWallet -= (Decimal.parse(value.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
} else {
|
} else {
|
||||||
|
@ -3363,7 +3368,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
}
|
}
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
outAmount += (Decimal.parse(value.toString()) *
|
outAmount += (Decimal.parse(value.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -3376,7 +3381,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
final nFees = input["nFees"];
|
final nFees = input["nFees"];
|
||||||
if (nFees != null) {
|
if (nFees != null) {
|
||||||
fees += (Decimal.parse(nFees.toString()) *
|
fees += (Decimal.parse(nFees.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -3391,7 +3396,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
if (allAddresses.contains(address)) {
|
if (allAddresses.contains(address)) {
|
||||||
outputAmtAddressedToWallet += (Decimal.parse(value.toString()) *
|
outputAmtAddressedToWallet += (Decimal.parse(value.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
outAddress = address;
|
outAddress = address;
|
||||||
|
@ -3413,7 +3418,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
midSortedTx["amount"] = inputAmtSentFromWallet;
|
midSortedTx["amount"] = inputAmtSentFromWallet;
|
||||||
final String worthNow = Format.localizedStringAsFixed(
|
final String worthNow = Format.localizedStringAsFixed(
|
||||||
value: ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
|
value: ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2),
|
.toDecimal(scaleOnInfinitePrecision: 2),
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
locale: locale!);
|
locale: locale!);
|
||||||
|
@ -3428,7 +3433,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
final worthNow = Format.localizedStringAsFixed(
|
final worthNow = Format.localizedStringAsFixed(
|
||||||
value:
|
value:
|
||||||
((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
|
((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2),
|
.toDecimal(scaleOnInfinitePrecision: 2),
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
locale: locale!);
|
locale: locale!);
|
||||||
|
@ -3589,7 +3594,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
utxo["status"]["block_time"] = txn["blocktime"];
|
utxo["status"]["block_time"] = txn["blocktime"];
|
||||||
|
|
||||||
final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
|
final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2);
|
.toDecimal(scaleOnInfinitePrecision: 2);
|
||||||
utxo["rawWorth"] = fiatValue;
|
utxo["rawWorth"] = fiatValue;
|
||||||
utxo["fiatWorth"] = fiatValue.toString();
|
utxo["fiatWorth"] = fiatValue.toString();
|
||||||
|
@ -3600,15 +3605,16 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
Decimal currencyBalanceRaw =
|
Decimal currencyBalanceRaw =
|
||||||
((Decimal.fromInt(satoshiBalance) * currentPrice) /
|
((Decimal.fromInt(satoshiBalance) * currentPrice) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2);
|
.toDecimal(scaleOnInfinitePrecision: 2);
|
||||||
|
|
||||||
final Map<String, dynamic> result = {
|
final Map<String, dynamic> result = {
|
||||||
"total_user_currency": currencyBalanceRaw.toString(),
|
"total_user_currency": currencyBalanceRaw.toString(),
|
||||||
"total_sats": satoshiBalance,
|
"total_sats": satoshiBalance,
|
||||||
"total_btc": (Decimal.fromInt(satoshiBalance) /
|
"total_btc": (Decimal.fromInt(satoshiBalance) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
|
.toDecimal(
|
||||||
|
scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin))
|
||||||
.toString(),
|
.toString(),
|
||||||
"outputArray": outputArray,
|
"outputArray": outputArray,
|
||||||
"unconfirmed": satoshiBalancePending,
|
"unconfirmed": satoshiBalancePending,
|
||||||
|
@ -4571,8 +4577,9 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
) async {
|
) async {
|
||||||
var lelantusEntry = await _getLelantusEntry();
|
var lelantusEntry = await _getLelantusEntry();
|
||||||
final balance = await availableBalance;
|
final balance = await availableBalance;
|
||||||
int spendAmount =
|
int spendAmount = (balance * Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
(balance * Decimal.fromInt(Constants.satsPerCoin)).toBigInt().toInt();
|
.toBigInt()
|
||||||
|
.toInt();
|
||||||
if (spendAmount == 0 || lelantusEntry.isEmpty) {
|
if (spendAmount == 0 || lelantusEntry.isEmpty) {
|
||||||
return LelantusFeeData(0, 0, []).fee;
|
return LelantusFeeData(0, 0, []).fee;
|
||||||
}
|
}
|
||||||
|
@ -4633,7 +4640,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
Future<int> estimateFeeForPublic(int satoshiAmount, int feeRate) async {
|
Future<int> estimateFeeForPublic(int satoshiAmount, int feeRate) async {
|
||||||
final available =
|
final available =
|
||||||
Format.decimalAmountToSatoshis(await availablePublicBalance());
|
Format.decimalAmountToSatoshis(await availablePublicBalance(), coin);
|
||||||
|
|
||||||
if (available == satoshiAmount) {
|
if (available == satoshiAmount) {
|
||||||
return satoshiAmount - sweepAllEstimate(feeRate);
|
return satoshiAmount - sweepAllEstimate(feeRate);
|
||||||
|
|
|
@ -200,19 +200,21 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
Future<Decimal> get availableBalance async {
|
Future<Decimal> get availableBalance async {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(
|
return Format.satoshisToAmount(
|
||||||
data.satoshiBalance - data.satoshiBalanceUnconfirmed);
|
data.satoshiBalance - data.satoshiBalanceUnconfirmed,
|
||||||
|
coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Decimal> get pendingBalance async {
|
Future<Decimal> get pendingBalance async {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed);
|
return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Decimal> get balanceMinusMaxFee async =>
|
Future<Decimal> get balanceMinusMaxFee async =>
|
||||||
(await availableBalance) -
|
(await availableBalance) -
|
||||||
(Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
|
(Decimal.fromInt((await maxFee)) /
|
||||||
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal();
|
.toDecimal();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -222,13 +224,13 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
.get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
|
.get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
|
||||||
if (totalBalance == null) {
|
if (totalBalance == null) {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalance);
|
return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
|
||||||
} else {
|
} else {
|
||||||
return Format.satoshisToAmount(totalBalance);
|
return Format.satoshisToAmount(totalBalance, coin: coin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalance);
|
return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -266,7 +268,8 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
@override
|
@override
|
||||||
Future<int> get maxFee async {
|
Future<int> get maxFee async {
|
||||||
final fee = (await fees).fast as String;
|
final fee = (await fees).fast as String;
|
||||||
final satsFee = Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin);
|
final satsFee =
|
||||||
|
Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin(coin));
|
||||||
return satsFee.floor().toBigInt().toInt();
|
return satsFee.floor().toBigInt().toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1095,7 +1098,8 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
// check for send all
|
// check for send all
|
||||||
bool isSendAll = false;
|
bool isSendAll = false;
|
||||||
final balance = Format.decimalAmountToSatoshis(await availableBalance);
|
final balance =
|
||||||
|
Format.decimalAmountToSatoshis(await availableBalance, coin);
|
||||||
if (satoshiAmount == balance) {
|
if (satoshiAmount == balance) {
|
||||||
isSendAll = true;
|
isSendAll = true;
|
||||||
}
|
}
|
||||||
|
@ -1299,7 +1303,7 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
final String worthNow = Format.localizedStringAsFixed(
|
final String worthNow = Format.localizedStringAsFixed(
|
||||||
value:
|
value:
|
||||||
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
|
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2),
|
.toDecimal(scaleOnInfinitePrecision: 2),
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
locale: locale!);
|
locale: locale!);
|
||||||
|
@ -1499,9 +1503,9 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
numberOfBlocksFast: f,
|
numberOfBlocksFast: f,
|
||||||
numberOfBlocksAverage: m,
|
numberOfBlocksAverage: m,
|
||||||
numberOfBlocksSlow: s,
|
numberOfBlocksSlow: s,
|
||||||
fast: Format.decimalAmountToSatoshis(fast),
|
fast: Format.decimalAmountToSatoshis(fast, coin),
|
||||||
medium: Format.decimalAmountToSatoshis(medium),
|
medium: Format.decimalAmountToSatoshis(medium, coin),
|
||||||
slow: Format.decimalAmountToSatoshis(slow),
|
slow: Format.decimalAmountToSatoshis(slow, coin),
|
||||||
);
|
);
|
||||||
|
|
||||||
Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
|
Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
|
||||||
|
@ -1978,7 +1982,7 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
utxo["status"]["block_time"] = txn["blocktime"];
|
utxo["status"]["block_time"] = txn["blocktime"];
|
||||||
|
|
||||||
final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
|
final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2);
|
.toDecimal(scaleOnInfinitePrecision: 2);
|
||||||
utxo["rawWorth"] = fiatValue;
|
utxo["rawWorth"] = fiatValue;
|
||||||
utxo["fiatWorth"] = fiatValue.toString();
|
utxo["fiatWorth"] = fiatValue.toString();
|
||||||
|
@ -1988,15 +1992,16 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
Decimal currencyBalanceRaw =
|
Decimal currencyBalanceRaw =
|
||||||
((Decimal.fromInt(satoshiBalance) * currentPrice) /
|
((Decimal.fromInt(satoshiBalance) * currentPrice) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2);
|
.toDecimal(scaleOnInfinitePrecision: 2);
|
||||||
|
|
||||||
final Map<String, dynamic> result = {
|
final Map<String, dynamic> result = {
|
||||||
"total_user_currency": currencyBalanceRaw.toString(),
|
"total_user_currency": currencyBalanceRaw.toString(),
|
||||||
"total_sats": satoshiBalance,
|
"total_sats": satoshiBalance,
|
||||||
"total_btc": (Decimal.fromInt(satoshiBalance) /
|
"total_btc": (Decimal.fromInt(satoshiBalance) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
|
.toDecimal(
|
||||||
|
scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin))
|
||||||
.toString(),
|
.toString(),
|
||||||
"outputArray": outputArray,
|
"outputArray": outputArray,
|
||||||
"unconfirmed": satoshiBalancePending,
|
"unconfirmed": satoshiBalancePending,
|
||||||
|
@ -2543,7 +2548,7 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
if (prevOut == out["n"]) {
|
if (prevOut == out["n"]) {
|
||||||
inputAmtSentFromWallet +=
|
inputAmtSentFromWallet +=
|
||||||
(Decimal.parse(out["value"]!.toString()) *
|
(Decimal.parse(out["value"]!.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -2557,7 +2562,7 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
output["scriptPubKey"]!["addresses"][0] as String;
|
output["scriptPubKey"]!["addresses"][0] as String;
|
||||||
final value = output["value"]!;
|
final value = output["value"]!;
|
||||||
final _value = (Decimal.parse(value.toString()) *
|
final _value = (Decimal.parse(value.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
totalOutput += _value;
|
totalOutput += _value;
|
||||||
|
@ -2582,7 +2587,7 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
final address = output["scriptPubKey"]["addresses"][0];
|
final address = output["scriptPubKey"]["addresses"][0];
|
||||||
if (address != null) {
|
if (address != null) {
|
||||||
final value = (Decimal.parse(output["value"].toString()) *
|
final value = (Decimal.parse(output["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
totalOut += value;
|
totalOut += value;
|
||||||
|
@ -2605,7 +2610,7 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
for (final out in tx["vout"] as List) {
|
for (final out in tx["vout"] as List) {
|
||||||
if (prevOut == out["n"]) {
|
if (prevOut == out["n"]) {
|
||||||
totalIn += (Decimal.parse(out["value"].toString()) *
|
totalIn += (Decimal.parse(out["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -2627,7 +2632,7 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
midSortedTx["amount"] = inputAmtSentFromWallet;
|
midSortedTx["amount"] = inputAmtSentFromWallet;
|
||||||
final String worthNow =
|
final String worthNow =
|
||||||
((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
|
((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2)
|
.toDecimal(scaleOnInfinitePrecision: 2)
|
||||||
.toStringAsFixed(2);
|
.toStringAsFixed(2);
|
||||||
midSortedTx["worthNow"] = worthNow;
|
midSortedTx["worthNow"] = worthNow;
|
||||||
|
@ -2637,7 +2642,7 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
midSortedTx["amount"] = outputAmtAddressedToWallet;
|
midSortedTx["amount"] = outputAmtAddressedToWallet;
|
||||||
final worthNow =
|
final worthNow =
|
||||||
((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
|
((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2)
|
.toDecimal(scaleOnInfinitePrecision: 2)
|
||||||
.toStringAsFixed(2);
|
.toStringAsFixed(2);
|
||||||
midSortedTx["worthNow"] = worthNow;
|
midSortedTx["worthNow"] = worthNow;
|
||||||
|
@ -3769,7 +3774,8 @@ class LitecoinWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
||||||
final available = Format.decimalAmountToSatoshis(await availableBalance);
|
final available =
|
||||||
|
Format.decimalAmountToSatoshis(await availableBalance, coin);
|
||||||
|
|
||||||
if (available == satoshiAmount) {
|
if (available == satoshiAmount) {
|
||||||
return satoshiAmount - sweepAllEstimate(feeRate);
|
return satoshiAmount - sweepAllEstimate(feeRate);
|
||||||
|
|
|
@ -44,6 +44,7 @@ import 'package:stackwallet/utilities/default_nodes.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
|
import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
|
||||||
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
|
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
|
||||||
|
import 'package:stackwallet/utilities/format.dart';
|
||||||
import 'package:stackwallet/utilities/logger.dart';
|
import 'package:stackwallet/utilities/logger.dart';
|
||||||
import 'package:stackwallet/utilities/prefs.dart';
|
import 'package:stackwallet/utilities/prefs.dart';
|
||||||
import 'package:stackwallet/utilities/stack_file_system.dart';
|
import 'package:stackwallet/utilities/stack_file_system.dart';
|
||||||
|
@ -533,7 +534,8 @@ class MoneroWallet extends CoinServiceAPI {
|
||||||
@override
|
@override
|
||||||
Future<Decimal> get balanceMinusMaxFee async =>
|
Future<Decimal> get balanceMinusMaxFee async =>
|
||||||
(await availableBalance) -
|
(await availableBalance) -
|
||||||
(Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
|
(Decimal.fromInt((await maxFee)) /
|
||||||
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal();
|
.toDecimal();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -542,16 +544,16 @@ class MoneroWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> exit() async {
|
Future<void> exit() async {
|
||||||
await stopSyncPercentTimer();
|
|
||||||
_hasCalledExit = true;
|
_hasCalledExit = true;
|
||||||
isActive = false;
|
stopNetworkAlivePinging();
|
||||||
await walletBase?.save(prioritySave: true);
|
|
||||||
walletBase?.close();
|
|
||||||
moneroAutosaveTimer?.cancel();
|
moneroAutosaveTimer?.cancel();
|
||||||
moneroAutosaveTimer = null;
|
moneroAutosaveTimer = null;
|
||||||
timer?.cancel();
|
timer?.cancel();
|
||||||
timer = null;
|
timer = null;
|
||||||
stopNetworkAlivePinging();
|
await stopSyncPercentTimer();
|
||||||
|
await walletBase?.save(prioritySave: true);
|
||||||
|
walletBase?.close();
|
||||||
|
isActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _hasCalledExit = false;
|
bool _hasCalledExit = false;
|
||||||
|
@ -562,13 +564,15 @@ class MoneroWallet extends CoinServiceAPI {
|
||||||
Future<String>? _currentReceivingAddress;
|
Future<String>? _currentReceivingAddress;
|
||||||
|
|
||||||
Future<FeeObject> _getFees() async {
|
Future<FeeObject> _getFees() async {
|
||||||
|
// TODO: not use random hard coded values here
|
||||||
return FeeObject(
|
return FeeObject(
|
||||||
numberOfBlocksFast: 10,
|
numberOfBlocksFast: 10,
|
||||||
numberOfBlocksAverage: 10,
|
numberOfBlocksAverage: 15,
|
||||||
numberOfBlocksSlow: 10,
|
numberOfBlocksSlow: 20,
|
||||||
fast: 4,
|
fast: MoneroTransactionPriority.fast.raw!,
|
||||||
medium: 2,
|
medium: MoneroTransactionPriority.regular.raw!,
|
||||||
slow: 0);
|
slow: MoneroTransactionPriority.slow.raw!,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -868,8 +872,9 @@ class MoneroWallet extends CoinServiceAPI {
|
||||||
Future<int> get maxFee async {
|
Future<int> get maxFee async {
|
||||||
var bal = await availableBalance;
|
var bal = await availableBalance;
|
||||||
var fee = walletBase!.calculateEstimatedFee(
|
var fee = walletBase!.calculateEstimatedFee(
|
||||||
monero.getDefaultTransactionPriority(), bal.toBigInt().toInt()) ~/
|
monero.getDefaultTransactionPriority(),
|
||||||
10000;
|
Format.decimalAmountToSatoshis(bal, coin),
|
||||||
|
);
|
||||||
|
|
||||||
return fee;
|
return fee;
|
||||||
}
|
}
|
||||||
|
@ -1372,7 +1377,6 @@ class MoneroWallet extends CoinServiceAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// TODO: implement availableBalance
|
|
||||||
Future<Decimal> get availableBalance async {
|
Future<Decimal> get availableBalance async {
|
||||||
var bal = 0;
|
var bal = 0;
|
||||||
for (var element in walletBase!.balance!.entries) {
|
for (var element in walletBase!.balance!.entries) {
|
||||||
|
@ -1421,13 +1425,13 @@ class MoneroWallet extends CoinServiceAPI {
|
||||||
try {
|
try {
|
||||||
final feeRate = args?["feeRate"];
|
final feeRate = args?["feeRate"];
|
||||||
if (feeRate is FeeRateType) {
|
if (feeRate is FeeRateType) {
|
||||||
MoneroTransactionPriority feePriority = MoneroTransactionPriority.slow;
|
MoneroTransactionPriority feePriority;
|
||||||
switch (feeRate) {
|
switch (feeRate) {
|
||||||
case FeeRateType.fast:
|
case FeeRateType.fast:
|
||||||
feePriority = MoneroTransactionPriority.fastest;
|
feePriority = MoneroTransactionPriority.fast;
|
||||||
break;
|
break;
|
||||||
case FeeRateType.average:
|
case FeeRateType.average:
|
||||||
feePriority = MoneroTransactionPriority.medium;
|
feePriority = MoneroTransactionPriority.regular;
|
||||||
break;
|
break;
|
||||||
case FeeRateType.slow:
|
case FeeRateType.slow:
|
||||||
feePriority = MoneroTransactionPriority.slow;
|
feePriority = MoneroTransactionPriority.slow;
|
||||||
|
@ -1440,15 +1444,14 @@ class MoneroWallet extends CoinServiceAPI {
|
||||||
bool isSendAll = false;
|
bool isSendAll = false;
|
||||||
final balance = await availableBalance;
|
final balance = await availableBalance;
|
||||||
final satInDecimal = ((Decimal.fromInt(satoshiAmount) /
|
final satInDecimal = ((Decimal.fromInt(satoshiAmount) /
|
||||||
Decimal.fromInt(Constants.satsPerCoinMonero))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal() *
|
.toDecimal());
|
||||||
Decimal.fromInt(10000));
|
|
||||||
if (satInDecimal == balance) {
|
if (satInDecimal == balance) {
|
||||||
isSendAll = true;
|
isSendAll = true;
|
||||||
}
|
}
|
||||||
Logging.instance
|
Logging.instance
|
||||||
.log("$toAddress $amount $args", level: LogLevel.Info);
|
.log("$toAddress $amount $args", level: LogLevel.Info);
|
||||||
String amountToSend = moneroAmountToString(amount: amount * 10000);
|
String amountToSend = moneroAmountToString(amount: amount);
|
||||||
Logging.instance.log("$amount $amountToSend", level: LogLevel.Info);
|
Logging.instance.log("$amount $amountToSend", level: LogLevel.Info);
|
||||||
|
|
||||||
monero_output.Output output = monero_output.Output(walletBase!);
|
monero_output.Output output = monero_output.Output(walletBase!);
|
||||||
|
@ -1470,10 +1473,9 @@ class MoneroWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
PendingMoneroTransaction pendingMoneroTransaction =
|
PendingMoneroTransaction pendingMoneroTransaction =
|
||||||
await (awaitPendingTransaction!) as PendingMoneroTransaction;
|
await (awaitPendingTransaction!) as PendingMoneroTransaction;
|
||||||
int realfee = (Decimal.parse(pendingMoneroTransaction.feeFormatted) *
|
|
||||||
100000000.toDecimal())
|
int realfee = Format.decimalAmountToSatoshis(
|
||||||
.toBigInt()
|
Decimal.parse(pendingMoneroTransaction.feeFormatted), coin);
|
||||||
.toInt();
|
|
||||||
debugPrint("fee? $realfee");
|
debugPrint("fee? $realfee");
|
||||||
Map<String, dynamic> txData = {
|
Map<String, dynamic> txData = {
|
||||||
"pendingMoneroTransaction": pendingMoneroTransaction,
|
"pendingMoneroTransaction": pendingMoneroTransaction,
|
||||||
|
@ -1506,12 +1508,13 @@ class MoneroWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
||||||
MoneroTransactionPriority? priority;
|
MoneroTransactionPriority priority;
|
||||||
FeeRateType feeRateType = FeeRateType.slow;
|
FeeRateType feeRateType;
|
||||||
|
|
||||||
switch (feeRate) {
|
switch (feeRate) {
|
||||||
case 1:
|
case 1:
|
||||||
priority = MoneroTransactionPriority.regular;
|
priority = MoneroTransactionPriority.regular;
|
||||||
feeRateType = FeeRateType.slow;
|
feeRateType = FeeRateType.average;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
priority = MoneroTransactionPriority.medium;
|
priority = MoneroTransactionPriority.medium;
|
||||||
|
@ -1519,7 +1522,7 @@ class MoneroWallet extends CoinServiceAPI {
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
priority = MoneroTransactionPriority.fast;
|
priority = MoneroTransactionPriority.fast;
|
||||||
feeRateType = FeeRateType.average;
|
feeRateType = FeeRateType.fast;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
priority = MoneroTransactionPriority.fastest;
|
priority = MoneroTransactionPriority.fastest;
|
||||||
|
@ -1531,27 +1534,29 @@ class MoneroWallet extends CoinServiceAPI {
|
||||||
feeRateType = FeeRateType.slow;
|
feeRateType = FeeRateType.slow;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var aprox;
|
// int? aprox;
|
||||||
|
|
||||||
await estimateFeeMutex.protect(() async {
|
// corrupted size vs. prev_size occurs but not sure if related to fees or just generating monero transactions in general
|
||||||
{
|
|
||||||
try {
|
// await estimateFeeMutex.protect(() async {
|
||||||
aprox = (await prepareSend(
|
// {
|
||||||
// This address is only used for getting an approximate fee, never for sending
|
// try {
|
||||||
address:
|
// aprox = (await prepareSend(
|
||||||
"8347huhmj6Ggzr1BpZPJAD5oa96ob5Fe8GtQdGZDYVVYVsCgtUNH3pEEzExDuaAVZdC16D4FkAb24J6wUfsKkcZtC8EPXB7",
|
// // This address is only used for getting an approximate fee, never for sending
|
||||||
satoshiAmount: satoshiAmount,
|
// address:
|
||||||
args: {"feeRate": feeRateType}))['fee'];
|
// "8347huhmj6Ggzr1BpZPJAD5oa96ob5Fe8GtQdGZDYVVYVsCgtUNH3pEEzExDuaAVZdC16D4FkAb24J6wUfsKkcZtC8EPXB7",
|
||||||
await Future.delayed(const Duration(milliseconds: 1000));
|
// satoshiAmount: satoshiAmount,
|
||||||
} catch (e, s) {
|
// args: {"feeRate": feeRateType}))['fee'] as int?;
|
||||||
Logging.instance.log("$feeRateType $e $s", level: LogLevel.Error);
|
// await Future<void>.delayed(const Duration(milliseconds: 1000));
|
||||||
aprox = -9999999999999999;
|
// } catch (e, s) {
|
||||||
}
|
// Logging.instance.log("$feeRateType $e $s", level: LogLevel.Error);
|
||||||
}
|
final aprox = walletBase!.calculateEstimatedFee(priority, satoshiAmount);
|
||||||
});
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
print("this is the aprox fee $aprox for $satoshiAmount");
|
print("this is the aprox fee $aprox for $satoshiAmount");
|
||||||
final fee = (aprox as int);
|
final fee = aprox;
|
||||||
return fee;
|
return fee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,19 +196,21 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
Future<Decimal> get availableBalance async {
|
Future<Decimal> get availableBalance async {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(
|
return Format.satoshisToAmount(
|
||||||
data.satoshiBalance - data.satoshiBalanceUnconfirmed);
|
data.satoshiBalance - data.satoshiBalanceUnconfirmed,
|
||||||
|
coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Decimal> get pendingBalance async {
|
Future<Decimal> get pendingBalance async {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed);
|
return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Decimal> get balanceMinusMaxFee async =>
|
Future<Decimal> get balanceMinusMaxFee async =>
|
||||||
(await availableBalance) -
|
(await availableBalance) -
|
||||||
(Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
|
(Decimal.fromInt((await maxFee)) /
|
||||||
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal();
|
.toDecimal();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -218,13 +220,13 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
.get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
|
.get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
|
||||||
if (totalBalance == null) {
|
if (totalBalance == null) {
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalance);
|
return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
|
||||||
} else {
|
} else {
|
||||||
return Format.satoshisToAmount(totalBalance);
|
return Format.satoshisToAmount(totalBalance, coin: coin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final data = await utxoData;
|
final data = await utxoData;
|
||||||
return Format.satoshisToAmount(data.satoshiBalance);
|
return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -262,7 +264,8 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
@override
|
@override
|
||||||
Future<int> get maxFee async {
|
Future<int> get maxFee async {
|
||||||
final fee = (await fees).fast as String;
|
final fee = (await fees).fast as String;
|
||||||
final satsFee = Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin);
|
final satsFee =
|
||||||
|
Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin(coin));
|
||||||
return satsFee.floor().toBigInt().toInt();
|
return satsFee.floor().toBigInt().toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1086,7 +1089,8 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
// check for send all
|
// check for send all
|
||||||
bool isSendAll = false;
|
bool isSendAll = false;
|
||||||
final balance = Format.decimalAmountToSatoshis(await availableBalance);
|
final balance =
|
||||||
|
Format.decimalAmountToSatoshis(await availableBalance, coin);
|
||||||
if (satoshiAmount == balance) {
|
if (satoshiAmount == balance) {
|
||||||
isSendAll = true;
|
isSendAll = true;
|
||||||
}
|
}
|
||||||
|
@ -1290,7 +1294,7 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
final String worthNow = Format.localizedStringAsFixed(
|
final String worthNow = Format.localizedStringAsFixed(
|
||||||
value:
|
value:
|
||||||
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
|
((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2),
|
.toDecimal(scaleOnInfinitePrecision: 2),
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
locale: locale!);
|
locale: locale!);
|
||||||
|
@ -1490,9 +1494,9 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
numberOfBlocksFast: f,
|
numberOfBlocksFast: f,
|
||||||
numberOfBlocksAverage: m,
|
numberOfBlocksAverage: m,
|
||||||
numberOfBlocksSlow: s,
|
numberOfBlocksSlow: s,
|
||||||
fast: Format.decimalAmountToSatoshis(fast),
|
fast: Format.decimalAmountToSatoshis(fast, coin),
|
||||||
medium: Format.decimalAmountToSatoshis(medium),
|
medium: Format.decimalAmountToSatoshis(medium, coin),
|
||||||
slow: Format.decimalAmountToSatoshis(slow),
|
slow: Format.decimalAmountToSatoshis(slow, coin),
|
||||||
);
|
);
|
||||||
|
|
||||||
Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
|
Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
|
||||||
|
@ -1965,7 +1969,7 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
utxo["status"]["block_time"] = txn["blocktime"];
|
utxo["status"]["block_time"] = txn["blocktime"];
|
||||||
|
|
||||||
final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
|
final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2);
|
.toDecimal(scaleOnInfinitePrecision: 2);
|
||||||
utxo["rawWorth"] = fiatValue;
|
utxo["rawWorth"] = fiatValue;
|
||||||
utxo["fiatWorth"] = fiatValue.toString();
|
utxo["fiatWorth"] = fiatValue.toString();
|
||||||
|
@ -1975,15 +1979,16 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
Decimal currencyBalanceRaw =
|
Decimal currencyBalanceRaw =
|
||||||
((Decimal.fromInt(satoshiBalance) * currentPrice) /
|
((Decimal.fromInt(satoshiBalance) * currentPrice) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2);
|
.toDecimal(scaleOnInfinitePrecision: 2);
|
||||||
|
|
||||||
final Map<String, dynamic> result = {
|
final Map<String, dynamic> result = {
|
||||||
"total_user_currency": currencyBalanceRaw.toString(),
|
"total_user_currency": currencyBalanceRaw.toString(),
|
||||||
"total_sats": satoshiBalance,
|
"total_sats": satoshiBalance,
|
||||||
"total_btc": (Decimal.fromInt(satoshiBalance) /
|
"total_btc": (Decimal.fromInt(satoshiBalance) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
|
.toDecimal(
|
||||||
|
scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin))
|
||||||
.toString(),
|
.toString(),
|
||||||
"outputArray": outputArray,
|
"outputArray": outputArray,
|
||||||
"unconfirmed": satoshiBalancePending,
|
"unconfirmed": satoshiBalancePending,
|
||||||
|
@ -2540,7 +2545,7 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
if (prevOut == out["n"]) {
|
if (prevOut == out["n"]) {
|
||||||
inputAmtSentFromWallet +=
|
inputAmtSentFromWallet +=
|
||||||
(Decimal.parse(out["value"]!.toString()) *
|
(Decimal.parse(out["value"]!.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -2554,7 +2559,7 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
final address = output["scriptPubKey"]["address"];
|
final address = output["scriptPubKey"]["address"];
|
||||||
final value = output["value"];
|
final value = output["value"];
|
||||||
final _value = (Decimal.parse(value.toString()) *
|
final _value = (Decimal.parse(value.toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
totalOutput += _value;
|
totalOutput += _value;
|
||||||
|
@ -2582,7 +2587,7 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
}
|
}
|
||||||
if (address != null) {
|
if (address != null) {
|
||||||
final value = (Decimal.parse(output["value"].toString()) *
|
final value = (Decimal.parse(output["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
totalOut += value;
|
totalOut += value;
|
||||||
|
@ -2605,7 +2610,7 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
for (final out in tx["vout"] as List) {
|
for (final out in tx["vout"] as List) {
|
||||||
if (prevOut == out["n"]) {
|
if (prevOut == out["n"]) {
|
||||||
totalIn += (Decimal.parse(out["value"].toString()) *
|
totalIn += (Decimal.parse(out["value"].toString()) *
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toBigInt()
|
.toBigInt()
|
||||||
.toInt();
|
.toInt();
|
||||||
}
|
}
|
||||||
|
@ -2627,7 +2632,7 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
midSortedTx["amount"] = inputAmtSentFromWallet;
|
midSortedTx["amount"] = inputAmtSentFromWallet;
|
||||||
final String worthNow =
|
final String worthNow =
|
||||||
((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
|
((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2)
|
.toDecimal(scaleOnInfinitePrecision: 2)
|
||||||
.toStringAsFixed(2);
|
.toStringAsFixed(2);
|
||||||
midSortedTx["worthNow"] = worthNow;
|
midSortedTx["worthNow"] = worthNow;
|
||||||
|
@ -2637,7 +2642,7 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
midSortedTx["amount"] = outputAmtAddressedToWallet;
|
midSortedTx["amount"] = outputAmtAddressedToWallet;
|
||||||
final worthNow =
|
final worthNow =
|
||||||
((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
|
((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
|
||||||
Decimal.fromInt(Constants.satsPerCoin))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal(scaleOnInfinitePrecision: 2)
|
.toDecimal(scaleOnInfinitePrecision: 2)
|
||||||
.toStringAsFixed(2);
|
.toStringAsFixed(2);
|
||||||
midSortedTx["worthNow"] = worthNow;
|
midSortedTx["worthNow"] = worthNow;
|
||||||
|
@ -3772,7 +3777,8 @@ class NamecoinWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
||||||
final available = Format.decimalAmountToSatoshis(await availableBalance);
|
final available =
|
||||||
|
Format.decimalAmountToSatoshis(await availableBalance, coin);
|
||||||
|
|
||||||
if (available == satoshiAmount) {
|
if (available == satoshiAmount) {
|
||||||
return satoshiAmount - sweepAllEstimate(feeRate);
|
return satoshiAmount - sweepAllEstimate(feeRate);
|
||||||
|
|
|
@ -45,6 +45,7 @@ import 'package:stackwallet/utilities/default_nodes.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
|
import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
|
||||||
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
|
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
|
||||||
|
import 'package:stackwallet/utilities/format.dart';
|
||||||
import 'package:stackwallet/utilities/logger.dart';
|
import 'package:stackwallet/utilities/logger.dart';
|
||||||
import 'package:stackwallet/utilities/prefs.dart';
|
import 'package:stackwallet/utilities/prefs.dart';
|
||||||
import 'package:stackwallet/utilities/stack_file_system.dart';
|
import 'package:stackwallet/utilities/stack_file_system.dart';
|
||||||
|
@ -534,8 +535,7 @@ class WowneroWallet extends CoinServiceAPI {
|
||||||
@override
|
@override
|
||||||
Future<Decimal> get balanceMinusMaxFee async =>
|
Future<Decimal> get balanceMinusMaxFee async =>
|
||||||
(await availableBalance) -
|
(await availableBalance) -
|
||||||
(Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
|
Format.satoshisToAmount(await maxFee, coin: Coin.wownero);
|
||||||
.toDecimal();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<String> get currentReceivingAddress =>
|
Future<String> get currentReceivingAddress =>
|
||||||
|
@ -563,13 +563,15 @@ class WowneroWallet extends CoinServiceAPI {
|
||||||
Future<String>? _currentReceivingAddress;
|
Future<String>? _currentReceivingAddress;
|
||||||
|
|
||||||
Future<FeeObject> _getFees() async {
|
Future<FeeObject> _getFees() async {
|
||||||
|
// TODO: not use random hard coded values here
|
||||||
return FeeObject(
|
return FeeObject(
|
||||||
numberOfBlocksFast: 10,
|
numberOfBlocksFast: 10,
|
||||||
numberOfBlocksAverage: 10,
|
numberOfBlocksAverage: 15,
|
||||||
numberOfBlocksSlow: 10,
|
numberOfBlocksSlow: 20,
|
||||||
fast: 4,
|
fast: MoneroTransactionPriority.fast.raw!,
|
||||||
medium: 2,
|
medium: MoneroTransactionPriority.regular.raw!,
|
||||||
slow: 0);
|
slow: MoneroTransactionPriority.slow.raw!,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -873,8 +875,9 @@ class WowneroWallet extends CoinServiceAPI {
|
||||||
Future<int> get maxFee async {
|
Future<int> get maxFee async {
|
||||||
var bal = await availableBalance;
|
var bal = await availableBalance;
|
||||||
var fee = walletBase!.calculateEstimatedFee(
|
var fee = walletBase!.calculateEstimatedFee(
|
||||||
wownero.getDefaultTransactionPriority(), bal.toBigInt().toInt()) ~/
|
wownero.getDefaultTransactionPriority(),
|
||||||
10000;
|
Format.decimalAmountToSatoshis(bal, coin),
|
||||||
|
);
|
||||||
|
|
||||||
return fee;
|
return fee;
|
||||||
}
|
}
|
||||||
|
@ -1446,13 +1449,13 @@ class WowneroWallet extends CoinServiceAPI {
|
||||||
try {
|
try {
|
||||||
final feeRate = args?["feeRate"];
|
final feeRate = args?["feeRate"];
|
||||||
if (feeRate is FeeRateType) {
|
if (feeRate is FeeRateType) {
|
||||||
MoneroTransactionPriority feePriority = MoneroTransactionPriority.slow;
|
MoneroTransactionPriority feePriority;
|
||||||
switch (feeRate) {
|
switch (feeRate) {
|
||||||
case FeeRateType.fast:
|
case FeeRateType.fast:
|
||||||
feePriority = MoneroTransactionPriority.fastest;
|
feePriority = MoneroTransactionPriority.fast;
|
||||||
break;
|
break;
|
||||||
case FeeRateType.average:
|
case FeeRateType.average:
|
||||||
feePriority = MoneroTransactionPriority.medium;
|
feePriority = MoneroTransactionPriority.regular;
|
||||||
break;
|
break;
|
||||||
case FeeRateType.slow:
|
case FeeRateType.slow:
|
||||||
feePriority = MoneroTransactionPriority.slow;
|
feePriority = MoneroTransactionPriority.slow;
|
||||||
|
@ -1465,15 +1468,14 @@ class WowneroWallet extends CoinServiceAPI {
|
||||||
bool isSendAll = false;
|
bool isSendAll = false;
|
||||||
final balance = await availableBalance;
|
final balance = await availableBalance;
|
||||||
final satInDecimal = ((Decimal.fromInt(satoshiAmount) /
|
final satInDecimal = ((Decimal.fromInt(satoshiAmount) /
|
||||||
Decimal.fromInt(Constants.satsPerCoinWownero))
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
.toDecimal() *
|
.toDecimal());
|
||||||
Decimal.fromInt(1000));
|
|
||||||
if (satInDecimal == balance) {
|
if (satInDecimal == balance) {
|
||||||
isSendAll = true;
|
isSendAll = true;
|
||||||
}
|
}
|
||||||
Logging.instance
|
Logging.instance
|
||||||
.log("$toAddress $amount $args", level: LogLevel.Info);
|
.log("$toAddress $amount $args", level: LogLevel.Info);
|
||||||
String amountToSend = wowneroAmountToString(amount: amount * 1000);
|
String amountToSend = wowneroAmountToString(amount: amount);
|
||||||
Logging.instance.log("$amount $amountToSend", level: LogLevel.Info);
|
Logging.instance.log("$amount $amountToSend", level: LogLevel.Info);
|
||||||
|
|
||||||
wownero_output.Output output = wownero_output.Output(walletBase!);
|
wownero_output.Output output = wownero_output.Output(walletBase!);
|
||||||
|
@ -1495,10 +1497,8 @@ class WowneroWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
PendingWowneroTransaction pendingWowneroTransaction =
|
PendingWowneroTransaction pendingWowneroTransaction =
|
||||||
await (awaitPendingTransaction!) as PendingWowneroTransaction;
|
await (awaitPendingTransaction!) as PendingWowneroTransaction;
|
||||||
int realfee = (Decimal.parse(pendingWowneroTransaction.feeFormatted) *
|
int realfee = Format.decimalAmountToSatoshis(
|
||||||
100000000.toDecimal())
|
Decimal.parse(pendingWowneroTransaction.feeFormatted), coin);
|
||||||
.toBigInt()
|
|
||||||
.toInt();
|
|
||||||
debugPrint("fee? $realfee");
|
debugPrint("fee? $realfee");
|
||||||
Map<String, dynamic> txData = {
|
Map<String, dynamic> txData = {
|
||||||
"pendingWowneroTransaction": pendingWowneroTransaction,
|
"pendingWowneroTransaction": pendingWowneroTransaction,
|
||||||
|
@ -1531,12 +1531,12 @@ class WowneroWallet extends CoinServiceAPI {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
|
||||||
MoneroTransactionPriority? priority;
|
MoneroTransactionPriority priority;
|
||||||
FeeRateType feeRateType = FeeRateType.slow;
|
FeeRateType feeRateType = FeeRateType.slow;
|
||||||
switch (feeRate) {
|
switch (feeRate) {
|
||||||
case 1:
|
case 1:
|
||||||
priority = MoneroTransactionPriority.regular;
|
priority = MoneroTransactionPriority.regular;
|
||||||
feeRateType = FeeRateType.slow;
|
feeRateType = FeeRateType.average;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
priority = MoneroTransactionPriority.medium;
|
priority = MoneroTransactionPriority.medium;
|
||||||
|
@ -1544,7 +1544,7 @@ class WowneroWallet extends CoinServiceAPI {
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
priority = MoneroTransactionPriority.fast;
|
priority = MoneroTransactionPriority.fast;
|
||||||
feeRateType = FeeRateType.average;
|
feeRateType = FeeRateType.fast;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
priority = MoneroTransactionPriority.fastest;
|
priority = MoneroTransactionPriority.fastest;
|
||||||
|
@ -1568,7 +1568,7 @@ class WowneroWallet extends CoinServiceAPI {
|
||||||
args: {"feeRate": feeRateType}))['fee'];
|
args: {"feeRate": feeRateType}))['fee'];
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
aprox = -9999999999999999;
|
aprox = walletBase!.calculateEstimatedFee(priority, satoshiAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,12 +23,12 @@ abstract class Constants {
|
||||||
static bool enableExchange = Util.isDesktop || !Platform.isIOS;
|
static bool enableExchange = Util.isDesktop || !Platform.isIOS;
|
||||||
|
|
||||||
//TODO: correct for monero?
|
//TODO: correct for monero?
|
||||||
static const int satsPerCoinMonero = 1000000000000;
|
static const int _satsPerCoinMonero = 1000000000000;
|
||||||
static const int satsPerCoinWownero = 100000000000;
|
static const int _satsPerCoinWownero = 100000000000;
|
||||||
static const int satsPerCoin = 100000000;
|
static const int _satsPerCoin = 100000000;
|
||||||
static const int decimalPlaces = 8;
|
static const int _decimalPlaces = 8;
|
||||||
static const int decimalPlacesWownero = 11;
|
static const int _decimalPlacesWownero = 11;
|
||||||
static const int decimalPlacesMonero = 12;
|
static const int _decimalPlacesMonero = 12;
|
||||||
|
|
||||||
static const int notificationsMax = 0xFFFFFFFF;
|
static const int notificationsMax = 0xFFFFFFFF;
|
||||||
static const Duration networkAliveTimerDuration = Duration(seconds: 10);
|
static const Duration networkAliveTimerDuration = Duration(seconds: 10);
|
||||||
|
@ -40,6 +40,30 @@ abstract class Constants {
|
||||||
|
|
||||||
static const int currentHiveDbVersion = 3;
|
static const int currentHiveDbVersion = 3;
|
||||||
|
|
||||||
|
static int satsPerCoin(Coin coin) {
|
||||||
|
switch (coin) {
|
||||||
|
case Coin.bitcoin:
|
||||||
|
case Coin.litecoin:
|
||||||
|
case Coin.litecoinTestNet:
|
||||||
|
case Coin.bitcoincash:
|
||||||
|
case Coin.bitcoincashTestnet:
|
||||||
|
case Coin.dogecoin:
|
||||||
|
case Coin.firo:
|
||||||
|
case Coin.bitcoinTestNet:
|
||||||
|
case Coin.dogecoinTestNet:
|
||||||
|
case Coin.firoTestNet:
|
||||||
|
case Coin.epicCash:
|
||||||
|
case Coin.namecoin:
|
||||||
|
return _satsPerCoin;
|
||||||
|
|
||||||
|
case Coin.wownero:
|
||||||
|
return _satsPerCoinWownero;
|
||||||
|
|
||||||
|
case Coin.monero:
|
||||||
|
return _satsPerCoinMonero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int decimalPlacesForCoin(Coin coin) {
|
static int decimalPlacesForCoin(Coin coin) {
|
||||||
switch (coin) {
|
switch (coin) {
|
||||||
case Coin.bitcoin:
|
case Coin.bitcoin:
|
||||||
|
@ -54,13 +78,13 @@ abstract class Constants {
|
||||||
case Coin.firoTestNet:
|
case Coin.firoTestNet:
|
||||||
case Coin.epicCash:
|
case Coin.epicCash:
|
||||||
case Coin.namecoin:
|
case Coin.namecoin:
|
||||||
return decimalPlaces;
|
return _decimalPlaces;
|
||||||
|
|
||||||
case Coin.wownero:
|
case Coin.wownero:
|
||||||
return decimalPlacesWownero;
|
return _decimalPlacesWownero;
|
||||||
|
|
||||||
case Coin.monero:
|
case Coin.monero:
|
||||||
return decimalPlacesMonero;
|
return _decimalPlacesMonero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,46 +8,28 @@ import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
|
||||||
abstract class Format {
|
abstract class Format {
|
||||||
static Decimal satoshisToAmount(int sats, {Coin? coin}) {
|
static Decimal satoshisToAmount(int sats, {required Coin coin}) {
|
||||||
late final int satsPerCoin;
|
return (Decimal.fromInt(sats) /
|
||||||
|
Decimal.fromInt(Constants.satsPerCoin(coin)))
|
||||||
switch (coin) {
|
.toDecimal(
|
||||||
case Coin.wownero:
|
scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin));
|
||||||
satsPerCoin = Constants.satsPerCoinWownero;
|
|
||||||
break;
|
|
||||||
case Coin.monero:
|
|
||||||
satsPerCoin = Constants.satsPerCoinMonero;
|
|
||||||
break;
|
|
||||||
case Coin.bitcoin:
|
|
||||||
case Coin.bitcoincash:
|
|
||||||
case Coin.dogecoin:
|
|
||||||
case Coin.epicCash:
|
|
||||||
case Coin.firo:
|
|
||||||
case Coin.litecoin:
|
|
||||||
case Coin.namecoin:
|
|
||||||
case Coin.bitcoinTestNet:
|
|
||||||
case Coin.litecoinTestNet:
|
|
||||||
case Coin.bitcoincashTestnet:
|
|
||||||
case Coin.dogecoinTestNet:
|
|
||||||
case Coin.firoTestNet:
|
|
||||||
default:
|
|
||||||
satsPerCoin = Constants.satsPerCoin;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (Decimal.fromInt(sats) / Decimal.fromInt(satsPerCoin))
|
|
||||||
.toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
static String satoshiAmountToPrettyString(int sats, String locale) {
|
static String satoshiAmountToPrettyString(
|
||||||
final amount = satoshisToAmount(sats);
|
int sats, String locale, Coin coin) {
|
||||||
|
final amount = satoshisToAmount(sats, coin: coin);
|
||||||
return localizedStringAsFixed(
|
return localizedStringAsFixed(
|
||||||
value: amount, locale: locale, decimalPlaces: Constants.decimalPlaces);
|
value: amount,
|
||||||
|
locale: locale,
|
||||||
|
decimalPlaces: Constants.decimalPlacesForCoin(coin),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decimalAmountToSatoshis(Decimal amount) {
|
static int decimalAmountToSatoshis(Decimal amount, Coin coin) {
|
||||||
final value =
|
final value = (Decimal.fromInt(Constants.satsPerCoin(coin)) * amount)
|
||||||
(Decimal.fromInt(Constants.satsPerCoin) * amount).floor().toBigInt();
|
.floor()
|
||||||
|
.toBigInt();
|
||||||
return value.toInt();
|
return value.toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,7 @@ class _ExchangeTextFieldState extends State<ExchangeTextField> {
|
||||||
width: 6,
|
width: 6,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
widget.ticker ?? "-",
|
widget.ticker?.toUpperCase() ?? "-",
|
||||||
style: STextStyles.smallMed14(context).copyWith(
|
style: STextStyles.smallMed14(context).copyWith(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
|
|
|
@ -9,7 +9,6 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_deta
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
|
|
||||||
import 'package:stackwallet/utilities/format.dart';
|
import 'package:stackwallet/utilities/format.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
@ -198,13 +197,9 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
final amount = coin == Coin.monero
|
final amount = _transaction.amount;
|
||||||
? (_transaction.amount ~/ 10000)
|
|
||||||
: coin == Coin.wownero
|
|
||||||
? (_transaction.amount ~/ 1000)
|
|
||||||
: _transaction.amount;
|
|
||||||
return Text(
|
return Text(
|
||||||
"$prefix${Format.satoshiAmountToPrettyString(amount, locale)} ${coin.ticker}",
|
"$prefix${Format.satoshiAmountToPrettyString(amount, locale, coin)} ${coin.ticker}",
|
||||||
style:
|
style:
|
||||||
STextStyles.itemSubtitle12_600(context),
|
STextStyles.itemSubtitle12_600(context),
|
||||||
);
|
);
|
||||||
|
@ -242,17 +237,12 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
// TODO: modify Format.<functions> to take optional Coin parameter so this type oif check isn't done in ui
|
|
||||||
int value = _transaction.amount;
|
int value = _transaction.amount;
|
||||||
if (coin == Coin.monero) {
|
|
||||||
value = (value ~/ 10000);
|
|
||||||
} else if (coin == Coin.wownero) {
|
|
||||||
value = (value ~/ 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Text(
|
return Text(
|
||||||
"$prefix${Format.localizedStringAsFixed(
|
"$prefix${Format.localizedStringAsFixed(
|
||||||
value: Format.satoshisToAmount(value) *
|
value: Format.satoshisToAmount(value,
|
||||||
|
coin: coin) *
|
||||||
price,
|
price,
|
||||||
locale: locale,
|
locale: locale,
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
|
|
|
@ -11,7 +11,7 @@ description: Stack Wallet
|
||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.5.18+90
|
version: 1.5.19+91
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.17.0 <3.0.0"
|
sdk: ">=2.17.0 <3.0.0"
|
||||||
|
|
|
@ -1,54 +1,64 @@
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/format.dart';
|
import 'package:stackwallet/utilities/format.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group("satoshisToAmount", () {
|
group("satoshisToAmount", () {
|
||||||
test("12345", () {
|
test("12345", () {
|
||||||
expect(Format.satoshisToAmount(12345), Decimal.parse("0.00012345"));
|
expect(Format.satoshisToAmount(12345, coin: Coin.bitcoin),
|
||||||
|
Decimal.parse("0.00012345"));
|
||||||
});
|
});
|
||||||
|
|
||||||
test("100012345", () {
|
test("100012345", () {
|
||||||
expect(Format.satoshisToAmount(100012345), Decimal.parse("1.00012345"));
|
expect(Format.satoshisToAmount(100012345, coin: Coin.bitcoin),
|
||||||
|
Decimal.parse("1.00012345"));
|
||||||
});
|
});
|
||||||
|
|
||||||
test("0", () {
|
test("0", () {
|
||||||
expect(Format.satoshisToAmount(0), Decimal.zero);
|
expect(Format.satoshisToAmount(0, coin: Coin.bitcoin), Decimal.zero);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("1000000000", () {
|
test("1000000000", () {
|
||||||
expect(Format.satoshisToAmount(1000000000), Decimal.parse("10"));
|
expect(Format.satoshisToAmount(1000000000, coin: Coin.bitcoin),
|
||||||
|
Decimal.parse("10"));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group("satoshiAmountToPrettyString", () {
|
group("satoshiAmountToPrettyString", () {
|
||||||
const locale = "en_US";
|
const locale = "en_US";
|
||||||
test("12345", () {
|
test("12345", () {
|
||||||
expect(Format.satoshiAmountToPrettyString(12345, locale), "0.00012345");
|
expect(Format.satoshiAmountToPrettyString(12345, locale, Coin.bitcoin),
|
||||||
|
"0.00012345");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("100012345", () {
|
test("100012345", () {
|
||||||
expect(
|
expect(
|
||||||
Format.satoshiAmountToPrettyString(100012345, locale), "1.00012345");
|
Format.satoshiAmountToPrettyString(100012345, locale, Coin.bitcoin),
|
||||||
|
"1.00012345");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("123450000", () {
|
test("123450000", () {
|
||||||
expect(
|
expect(
|
||||||
Format.satoshiAmountToPrettyString(123450000, locale), "1.23450000");
|
Format.satoshiAmountToPrettyString(123450000, locale, Coin.bitcoin),
|
||||||
|
"1.23450000");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("1230045000", () {
|
test("1230045000", () {
|
||||||
expect(Format.satoshiAmountToPrettyString(1230045000, locale),
|
expect(
|
||||||
|
Format.satoshiAmountToPrettyString(1230045000, locale, Coin.bitcoin),
|
||||||
"12.30045000");
|
"12.30045000");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("1000000000", () {
|
test("1000000000", () {
|
||||||
expect(Format.satoshiAmountToPrettyString(1000000000, locale),
|
expect(
|
||||||
|
Format.satoshiAmountToPrettyString(1000000000, locale, Coin.bitcoin),
|
||||||
"10.00000000");
|
"10.00000000");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("0", () {
|
test("0", () {
|
||||||
expect(Format.satoshiAmountToPrettyString(0, locale), "0.00000000");
|
expect(Format.satoshiAmountToPrettyString(0, locale, Coin.bitcoin),
|
||||||
|
"0.00000000");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue