Merge branch 'ba_nano_fixes' into ui-fixes

This commit is contained in:
julian 2023-06-08 11:03:50 -06:00
commit ed120f552a
7 changed files with 176 additions and 106 deletions

View file

@ -73,12 +73,6 @@ class _NewWalletRecoveryPhraseWarningViewState
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
final _numberOfPhraseWords = coin == Coin.monero
? Constants.seedPhraseWordCountMonero
: coin == Coin.wownero
? 14
: Constants.seedPhraseWordCountBip39;
return MasterScaffold(
isDesktop: isDesktop,
appBar: isDesktop
@ -177,7 +171,15 @@ class _NewWalletRecoveryPhraseWarningViewState
width: isDesktop ? 480 : null,
child: isDesktop
? Text(
"On the next screen you will see $_numberOfPhraseWords words that make up your recovery phrase.\n\nPlease write it down. Keep it safe and never share it with anyone. Your recovery phrase is the only way you can access your funds if you forget your PIN, lose your phone, etc.\n\nStack Wallet does not keep nor is able to restore your recover phrase. Only you have access to your wallet.",
"On the next screen you will see "
"${Constants.defaultSeedPhraseLengthFor(coin: coin)} "
"words that make up your recovery phrase.\n\nPlease "
"write it down. Keep it safe and never share it with "
"anyone. Your recovery phrase is the only way you can"
" access your funds if you forget your PIN, lose your"
" phone, etc.\n\nStack Wallet does not keep nor is "
"able to restore your recover phrase. Only you have "
"access to your wallet.",
style: isDesktop
? STextStyles.desktopTextMediumRegular(context)
: STextStyles.subtitle(context).copyWith(
@ -214,7 +216,9 @@ class _NewWalletRecoveryPhraseWarningViewState
),
),
TextSpan(
text: "$_numberOfPhraseWords words",
text:
"${Constants.defaultSeedPhraseLengthFor(coin: coin)}"
" words",
style: STextStyles.desktopH3(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!

View file

@ -303,11 +303,17 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> {
),
),
),
if (coin != Coin.epicCash && coin != Coin.ethereum)
if (coin != Coin.epicCash &&
coin != Coin.ethereum &&
coin != Coin.banano &&
coin != Coin.nano)
const SizedBox(
height: 12,
),
if (coin != Coin.epicCash && coin != Coin.ethereum)
if (coin != Coin.epicCash &&
coin != Coin.ethereum &&
coin != Coin.banano &&
coin != Coin.nano)
TextButton(
onPressed: generateNewAddress,
style: Theme.of(context)

View file

@ -148,8 +148,7 @@ class _TransactionDetailsViewState
if (_transaction.numberOfMessages == 1) {
return "Receiving (waiting for sender)";
} else if ((_transaction.numberOfMessages ?? 0) > 1) {
return
"Receiving (waiting for confirmations)"; // TODO test if the sender still has to open again after the receiver has 2 messages present, ie. sender->receiver->sender->node (yes) vs. sender->receiver->node (no)
return "Receiving (waiting for confirmations)"; // TODO test if the sender still has to open again after the receiver has 2 messages present, ie. sender->receiver->sender->node (yes) vs. sender->receiver->node (no)
} else {
return "Receiving";
}
@ -963,94 +962,99 @@ class _TransactionDetailsViewState
],
),
),
isDesktop
? const _Divider()
: const SizedBox(
height: 12,
),
RoundedWhiteContainer(
padding: isDesktop
? const EdgeInsets.all(16)
: const EdgeInsets.all(12),
child: Builder(builder: (context) {
String feeString = showFeePending
? _transaction.isConfirmed(
currentHeight,
coin.requiredConfirmations,
)
? ref
.watch(pAmountFormatter(coin))
.format(
fee,
withUnitName: isTokenTx,
)
: "Pending"
: ref.watch(pAmountFormatter(coin)).format(
fee,
withUnitName: isTokenTx,
);
if (coin != Coin.banano && coin != Coin.nano)
isDesktop
? const _Divider()
: const SizedBox(
height: 12,
),
if (coin != Coin.banano && coin != Coin.nano)
RoundedWhiteContainer(
padding: isDesktop
? const EdgeInsets.all(16)
: const EdgeInsets.all(12),
child: Builder(builder: (context) {
String feeString = showFeePending
? _transaction.isConfirmed(
currentHeight,
coin.requiredConfirmations,
)
? ref
.watch(pAmountFormatter(coin))
.format(
fee,
withUnitName: isTokenTx,
)
: "Pending"
: ref
.watch(pAmountFormatter(coin))
.format(
fee,
withUnitName: isTokenTx,
);
return Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
"Transaction fee",
style: isDesktop
? STextStyles
.desktopTextExtraExtraSmall(
context)
: STextStyles.itemSubtitle(
context),
),
if (isDesktop)
const SizedBox(
height: 2,
),
if (isDesktop)
SelectableText(
feeString,
return Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
"Transaction fee",
style: isDesktop
? STextStyles
.desktopTextExtraExtraSmall(
context)
.copyWith(
color: Theme.of(context)
.extension<
StackColors>()!
.textDark,
)
: STextStyles.itemSubtitle12(
context),
),
],
),
if (!isDesktop)
SelectableText(
feeString,
style: isDesktop
? STextStyles
.desktopTextExtraExtraSmall(
context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
)
: STextStyles.itemSubtitle12(
context),
: STextStyles.itemSubtitle(
context),
),
if (isDesktop)
const SizedBox(
height: 2,
),
if (isDesktop)
SelectableText(
feeString,
style: isDesktop
? STextStyles
.desktopTextExtraExtraSmall(
context)
.copyWith(
color: Theme.of(context)
.extension<
StackColors>()!
.textDark,
)
: STextStyles.itemSubtitle12(
context),
),
],
),
if (isDesktop)
IconCopyButton(data: feeString)
],
);
}),
),
if (!isDesktop)
SelectableText(
feeString,
style: isDesktop
? STextStyles
.desktopTextExtraExtraSmall(
context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
)
: STextStyles.itemSubtitle12(
context),
),
if (isDesktop)
IconCopyButton(data: feeString)
],
);
}),
),
isDesktop
? const _Divider()
: const SizedBox(

View file

@ -215,11 +215,17 @@ class _DesktopReceiveState extends ConsumerState<DesktopReceive> {
),
),
),
if (coin != Coin.epicCash && coin != Coin.ethereum)
if (coin != Coin.epicCash &&
coin != Coin.ethereum &&
coin != Coin.banano &&
coin != Coin.nano)
const SizedBox(
height: 20,
),
if (coin != Coin.epicCash && coin != Coin.ethereum)
if (coin != Coin.epicCash &&
coin != Coin.ethereum &&
coin != Coin.banano &&
coin != Coin.nano)
SecondaryButton(
buttonHeight: ButtonHeight.l,
onPressed: generateNewAddress,

View file

@ -293,7 +293,11 @@ class BananoWallet extends CoinServiceAPI
Future<Amount> estimateFeeFor(Amount amount, int feeRate) {
// fees are always 0 :)
return Future.value(
Amount(rawValue: BigInt.from(0), fractionDigits: coin.decimals));
Amount(
rawValue: BigInt.from(0),
fractionDigits: coin.decimals,
),
);
}
@override
@ -302,8 +306,15 @@ class BananoWallet extends CoinServiceAPI
}
@override
// TODO: implement fees
Future<FeeObject> get fees => throw UnimplementedError();
// Banano has no fees
Future<FeeObject> get fees async => FeeObject(
numberOfBlocksFast: 1,
numberOfBlocksAverage: 1,
numberOfBlocksSlow: 1,
fast: 0,
medium: 0,
slow: 0,
);
Future<void> updateBalance() async {
final body = jsonEncode({
@ -744,7 +755,7 @@ class BananoWallet extends CoinServiceAPI
);
} catch (e, s) {
Logging.instance.log(
"Failed to refresh banano wallet \'$walletName\': $e\n$s",
"Failed to refresh banano wallet $walletId: '$walletName': $e\n$s",
level: LogLevel.Warning,
);
GlobalEventBus.instance.fire(

View file

@ -313,7 +313,14 @@ class NanoWallet extends CoinServiceAPI
@override
// Nano has no fees
Future<FeeObject> get fees => throw UnimplementedError();
Future<FeeObject> get fees async => FeeObject(
numberOfBlocksFast: 1,
numberOfBlocksAverage: 1,
numberOfBlocksSlow: 1,
fast: 0,
medium: 0,
slow: 0,
);
Future<void> updateBalance() async {
final body = jsonEncode({
@ -754,7 +761,11 @@ class NanoWallet extends CoinServiceAPI
coin,
),
);
} catch (e) {
} catch (e, s) {
Logging.instance.log(
"Failed to refresh nano wallet $walletId: '$walletName': $e\n$s",
level: LogLevel.Warning,
);
GlobalEventBus.instance.fire(
WalletSyncStatusChangedEvent(
WalletSyncStatus.unableToSync,

View file

@ -40,9 +40,9 @@ abstract class Constants {
static final BigInt _satsPerCoinMonero = BigInt.from(1000000000000);
static final BigInt _satsPerCoinWownero = BigInt.from(100000000000);
static final BigInt _satsPerCoinNano =
BigInt.parse("1000000000000000000000000000000");// 1*10^30
BigInt.parse("1000000000000000000000000000000"); // 1*10^30
static final BigInt _satsPerCoinBanano =
BigInt.parse("100000000000000000000000000000");// 1*10^29
BigInt.parse("100000000000000000000000000000"); // 1*10^29
static final BigInt _satsPerCoin = BigInt.from(100000000);
static const int _decimalPlaces = 8;
static const int _decimalPlacesNano = 30;
@ -217,8 +217,36 @@ abstract class Constants {
}
}
static const int seedPhraseWordCountBip39 = 12;
static const int seedPhraseWordCountMonero = 25;
static int defaultSeedPhraseLengthFor({required Coin coin}) {
switch (coin) {
case Coin.bitcoin:
case Coin.bitcoinTestNet:
case Coin.bitcoincash:
case Coin.bitcoincashTestnet:
case Coin.eCash:
case Coin.dogecoin:
case Coin.dogecoinTestNet:
case Coin.litecoin:
case Coin.litecoinTestNet:
case Coin.firo:
case Coin.firoTestNet:
case Coin.epicCash:
case Coin.namecoin:
case Coin.particl:
case Coin.ethereum:
return 12;
case Coin.wownero:
return 14;
case Coin.nano:
case Coin.banano:
return 24;
case Coin.monero:
return 25;
}
}
static const Map<int, String> monthMapShort = {
1: 'Jan',