Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions app/lib/helpers/transaction_helpers.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import 'package:decimal/decimal.dart';
// ignore: depend_on_referenced_packages
import 'package:intl/intl.dart';

String formatAmount(String amount) {
double parsedAmount = double.parse(amount);

double parsedAmount = roundAmount(amount).toDouble();
String formattedAmount = NumberFormat('#,##0.##').format(parsedAmount);

return formattedAmount;
}

Decimal roundAmount(String amount) {
Decimal parsedAmount = Decimal.parse(amount).shift(2).floor().shift(-2);
return parsedAmount;
}
62 changes: 45 additions & 17 deletions app/lib/screens/wallets/bridge.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:threebotlogin/helpers/globals.dart';
Expand Down Expand Up @@ -28,9 +29,11 @@ class _WalletBridgeScreenState extends State<WalletBridgeScreen> {
final amountController = TextEditingController();
BridgeOperation transactionType = BridgeOperation.Withdraw;
bool isWithdraw = true;
Decimal fee = Decimal.parse('1.01');
String? toAddressError;
String? amountError;
bool reloadBalance = true;
List percentages = [25, 50, 75, 100];

@override
void initState() {
Expand Down Expand Up @@ -86,6 +89,7 @@ class _WalletBridgeScreenState extends State<WalletBridgeScreen> {
toController.text = '';
toAddressError = null;
amountError = null;
fee = isWithdraw ? Decimal.parse('1.01') : Decimal.parse('1.1');
setState(() {});
}

Expand Down Expand Up @@ -139,22 +143,16 @@ class _WalletBridgeScreenState extends State<WalletBridgeScreen> {
amountError = 'Amount should have numeric values only';
return false;
}
if (double.parse(amount) < 2) {
if (Decimal.parse(amount) < Decimal.fromInt(2)) {
amountError = "Amount can't be less than 2";
return false;
}
if (isWithdraw) {
if (double.parse(amount) > double.parse(widget.wallet.tfchainBalance)) {
amountError = "Amount shouldn't be more than the wallet balance";
return false;
}
}

if (!isWithdraw) {
if (double.parse(amount) > double.parse(widget.wallet.stellarBalance)) {
amountError = "Amount shouldn't be more than the wallet balance";
return false;
}
final balance = roundAmount(isWithdraw
? widget.wallet.tfchainBalance
: widget.wallet.stellarBalance);
if (balance - Decimal.parse(amount) - fee < Decimal.zero) {
amountError = 'Balance is not enough';
return false;
}
return true;
}
Expand All @@ -173,15 +171,16 @@ class _WalletBridgeScreenState extends State<WalletBridgeScreen> {

@override
Widget build(BuildContext context) {
String balance = isWithdraw
? widget.wallet.tfchainBalance
: widget.wallet.stellarBalance;
final bool disableDeposit = widget.wallet.stellarBalance == '-1';

if (disableDeposit && !isWithdraw) {
onTransactionChange(BridgeOperation.Withdraw);
}

String balance = isWithdraw
? widget.wallet.tfchainBalance
: widget.wallet.stellarBalance;
final isBiggerThanFee = roundAmount(balance) > fee;

return Scaffold(
appBar: AppBar(title: const Text('Bridge')),
body: SingleChildScrollView(
Expand Down Expand Up @@ -252,6 +251,26 @@ class _WalletBridgeScreenState extends State<WalletBridgeScreen> {
subtitle: Text('Max Fee: ${!isWithdraw ? 1.1 : 1.01} TFT'),
),
const SizedBox(height: 10),
if (isBiggerThanFee)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: percentages
.map(
(percentage) => OutlinedButton(
style: OutlinedButton.styleFrom(
shape: const RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(5)))),
onPressed: () => calculateAmount(percentage),
child: Text('$percentage%'),
),
)
.toList(),
),
),
const SizedBox(height: 30),
Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 10),
child: ElevatedButton(
Expand Down Expand Up @@ -279,6 +298,15 @@ class _WalletBridgeScreenState extends State<WalletBridgeScreen> {
);
}

calculateAmount(int percentage) {
final amount = (Decimal.parse(isWithdraw
? widget.wallet.tfchainBalance
: widget.wallet.stellarBalance) -
fee) *
(Decimal.fromInt(percentage).shift(-2));
amountController.text = roundAmount(amount.toString()).toString();
}

_bridge_confirmation() async {
final memoText =
!isWithdraw ? await TFChain.getMemo(toController.text.trim()) : null;
Expand Down
63 changes: 25 additions & 38 deletions app/lib/screens/wallets/send.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
Expand Down Expand Up @@ -32,7 +33,7 @@ class _WalletSendScreenState extends State<WalletSendScreen> {
final amountController = TextEditingController();
final memoController = TextEditingController();
ChainType chainType = ChainType.Stellar;
double fee = 0.1;
Decimal fee = Decimal.one.shift(-1); // 0.1
String? toAddressError;
String? amountError;
bool reloadBalance = true;
Expand Down Expand Up @@ -90,9 +91,12 @@ class _WalletSendScreenState extends State<WalletSendScreen> {
? widget.wallet.stellarAddress
: widget.wallet.tfchainAddress;
chainType = type;
fee = chainType == ChainType.Stellar
? double.parse('0.1')
: double.parse('.01');
toController.text = '';
toAddressError = null;
amountController.text = '';
amountError = null;
fee = Decimal.one
Comment thread
zaelgohary marked this conversation as resolved.
.shift(chainType == ChainType.Stellar ? -1 : -2); // 0.1 : 0.01
setState(() {});
}

Expand Down Expand Up @@ -153,29 +157,14 @@ class _WalletSendScreenState extends State<WalletSendScreen> {
amountError = 'Amount should have numeric values only';
return false;
}
if (double.parse(amount) < fee) {
amountError = "Amount can't be less than $fee";
final balance = roundAmount(chainType == ChainType.TFChain
? widget.wallet.tfchainBalance
: widget.wallet.stellarBalance);

if (balance - Decimal.parse(amount) - fee < Decimal.zero) {
amountError = 'Balance is not enough';
return false;
}
if (chainType == ChainType.TFChain) {
// Used epsilon as a tolerance
if (double.parse(widget.wallet.tfchainBalance) -
double.parse(amount) -
fee <
-1e-10) {
amountError = "Amount shouldn't be more than the wallet balance";
return false;
}
}
if (chainType == ChainType.Stellar) {
if (double.parse(widget.wallet.stellarBalance) -
double.parse(amount) -
0.1 <
-1e-10) {
amountError = "Amount shouldn't be more than the wallet balance";
return false;
}
}
return true;
}

Expand All @@ -193,16 +182,14 @@ class _WalletSendScreenState extends State<WalletSendScreen> {

@override
Widget build(BuildContext context) {
String balance = chainType == ChainType.Stellar
? widget.wallet.stellarBalance
: widget.wallet.tfchainBalance;
final isBiggerThanFee =
percentages.every((p) => double.parse(balance) * p / 100 > fee);

final bool hideStellar = widget.wallet.stellarBalance == '-1';
if (hideStellar) {
if (hideStellar && chainType == ChainType.Stellar) {
onChangeChain(ChainType.TFChain);
}
String balance = chainType == ChainType.Stellar
? widget.wallet.stellarBalance
: widget.wallet.tfchainBalance;
final isBiggerThanFee = roundAmount(balance) > fee;

return Scaffold(
appBar: AppBar(title: const Text('Send')),
Expand Down Expand Up @@ -315,7 +302,7 @@ class _WalletSendScreenState extends State<WalletSendScreen> {
child: Text('Max Fee: $fee TFT')),
),
const SizedBox(height: 10),
if (double.parse(balance) > fee && isBiggerThanFee)
if (isBiggerThanFee)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Row(
Expand Down Expand Up @@ -410,12 +397,12 @@ class _WalletSendScreenState extends State<WalletSendScreen> {
}

calculateAmount(int percentage) {
final amount = double.parse(chainType == ChainType.TFChain
final amount = (Decimal.parse(chainType == ChainType.TFChain
? widget.wallet.tfchainBalance
: widget.wallet.stellarBalance) *
(percentage / 100) -
fee;
amountController.text = amount.toStringAsFixed(2);
: widget.wallet.stellarBalance) -
fee) *
(Decimal.fromInt(percentage).shift(-2));
amountController.text = roundAmount(amount.toString()).toString();
}

_send_confirmation() async {
Expand Down
35 changes: 33 additions & 2 deletions app/lib/widgets/wallets/bridge_confirmation.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:threebotlogin/helpers/globals.dart';
import 'package:threebotlogin/helpers/transaction_helpers.dart';
import 'package:threebotlogin/models/wallet.dart';
import 'package:threebotlogin/services/stellar_service.dart' as Stellar;
import 'package:threebotlogin/services/tfchain_service.dart' as TFChain;
Expand Down Expand Up @@ -34,13 +35,16 @@ class _BridgeConfirmationWidgetState extends State<BridgeConfirmationWidget> {
final fromController = TextEditingController();
final toController = TextEditingController();
final amountController = TextEditingController();
final feeController = TextEditingController();
bool loading = false;

@override
void initState() {
fromController.text = widget.from;
toController.text = widget.to;
amountController.text = widget.amount;
feeController.text =
widget.bridgeOperation == BridgeOperation.Deposit ? '1.1' : '1.01';
super.initState();
}

Expand Down Expand Up @@ -98,9 +102,36 @@ class _BridgeConfirmationWidgetState extends State<BridgeConfirmationWidget> {
controller: amountController,
decoration: const InputDecoration(
labelText: 'Amount', hintText: '100', suffixText: 'TFT')),
subtitle: Text(
'Max Fee: ${widget.bridgeOperation == BridgeOperation.Deposit ? 1.1 : 1.01} TFT'),
),
const SizedBox(height: 10),
ListTile(
title: TextField(
readOnly: true,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurface,
),
keyboardType: TextInputType.number,
controller: feeController,
decoration:
const InputDecoration(labelText: 'Fee', suffixText: 'TFT')),
),
const SizedBox(height: 30),
ListTile(
leading: Text(
'Total',
style: Theme.of(context).textTheme.titleLarge!.copyWith(
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.bold),
),
trailing: Text(
(roundAmount(amountController.text) +
roundAmount(feeController.text))
.toString() +
' TFT',
style: Theme.of(context).textTheme.titleLarge!.copyWith(
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.bold),
)),
const SizedBox(height: 30),
Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 10),
Expand Down
33 changes: 31 additions & 2 deletions app/lib/widgets/wallets/send_confirmation.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:threebotlogin/helpers/transaction_helpers.dart';
import 'package:threebotlogin/models/wallet.dart';
import 'package:threebotlogin/services/stellar_service.dart' as Stellar;
import 'package:threebotlogin/services/tfchain_service.dart' as TFChain;
Expand Down Expand Up @@ -32,6 +33,7 @@ class _SendConfirmationWidgetState extends State<SendConfirmationWidget> {
final fromController = TextEditingController();
final toController = TextEditingController();
final amountController = TextEditingController();
final feeController = TextEditingController();
final memoController = TextEditingController();
bool loading = false;

Expand All @@ -40,6 +42,7 @@ class _SendConfirmationWidgetState extends State<SendConfirmationWidget> {
fromController.text = widget.from;
toController.text = widget.to;
amountController.text = widget.amount;
feeController.text = widget.chainType == ChainType.Stellar ? '0.1' : '0.01';
memoController.text = widget.memo;
super.initState();
}
Expand Down Expand Up @@ -99,8 +102,18 @@ class _SendConfirmationWidgetState extends State<SendConfirmationWidget> {
controller: amountController,
decoration: const InputDecoration(
labelText: 'Amount', hintText: '100', suffixText: 'TFT')),
subtitle: Text(
'Max Fee: ${widget.chainType == ChainType.Stellar ? 0.1 : 0.01} TFT'),
),
const SizedBox(height: 10),
ListTile(
title: TextField(
readOnly: true,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurface,
),
keyboardType: TextInputType.number,
controller: feeController,
decoration:
const InputDecoration(labelText: 'Fee', suffixText: 'TFT')),
),
const SizedBox(height: 10),
if (widget.chainType == ChainType.Stellar)
Expand All @@ -116,6 +129,22 @@ class _SendConfirmationWidgetState extends State<SendConfirmationWidget> {
)),
),
const SizedBox(height: 30),
ListTile(
leading: Text(
'Total',
style: Theme.of(context).textTheme.titleLarge!.copyWith(
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.bold),
),
trailing: Text(
(roundAmount(amountController.text) +
roundAmount(feeController.text))
.toString() +
' TFT',
style: Theme.of(context).textTheme.titleLarge!.copyWith(
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.bold),
)),
Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 10),
child: SizedBox(
Expand Down
6 changes: 3 additions & 3 deletions app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -314,13 +314,13 @@ packages:
source: hosted
version: "0.7.10"
decimal:
dependency: transitive
dependency: "direct main"
description:
name: decimal
sha256: "4140a688f9e443e2f4de3a1162387bf25e1ac6d51e24c9da263f245210f41440"
sha256: da8f65df568345f2738cc8b0de74971c86d2d93ce5fc8c4ec094f6b7c5d48eb5
url: "https://pub.dev"
source: hosted
version: "3.0.2"
version: "3.1.0"
device_info_plus:
dependency: "direct main"
description:
Expand Down
Loading