mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 09:47:37 +00:00
Merge branch 'ba_nano_fixes' into ui-fixes
This commit is contained in:
commit
ed120f552a
7 changed files with 176 additions and 106 deletions
|
@ -73,12 +73,6 @@ class _NewWalletRecoveryPhraseWarningViewState
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
debugPrint("BUILD: $runtimeType");
|
debugPrint("BUILD: $runtimeType");
|
||||||
|
|
||||||
final _numberOfPhraseWords = coin == Coin.monero
|
|
||||||
? Constants.seedPhraseWordCountMonero
|
|
||||||
: coin == Coin.wownero
|
|
||||||
? 14
|
|
||||||
: Constants.seedPhraseWordCountBip39;
|
|
||||||
|
|
||||||
return MasterScaffold(
|
return MasterScaffold(
|
||||||
isDesktop: isDesktop,
|
isDesktop: isDesktop,
|
||||||
appBar: isDesktop
|
appBar: isDesktop
|
||||||
|
@ -177,7 +171,15 @@ class _NewWalletRecoveryPhraseWarningViewState
|
||||||
width: isDesktop ? 480 : null,
|
width: isDesktop ? 480 : null,
|
||||||
child: isDesktop
|
child: isDesktop
|
||||||
? Text(
|
? 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
|
style: isDesktop
|
||||||
? STextStyles.desktopTextMediumRegular(context)
|
? STextStyles.desktopTextMediumRegular(context)
|
||||||
: STextStyles.subtitle(context).copyWith(
|
: STextStyles.subtitle(context).copyWith(
|
||||||
|
@ -214,7 +216,9 @@ class _NewWalletRecoveryPhraseWarningViewState
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: "$_numberOfPhraseWords words",
|
text:
|
||||||
|
"${Constants.defaultSeedPhraseLengthFor(coin: coin)}"
|
||||||
|
" words",
|
||||||
style: STextStyles.desktopH3(context).copyWith(
|
style: STextStyles.desktopH3(context).copyWith(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
|
|
|
@ -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(
|
const SizedBox(
|
||||||
height: 12,
|
height: 12,
|
||||||
),
|
),
|
||||||
if (coin != Coin.epicCash && coin != Coin.ethereum)
|
if (coin != Coin.epicCash &&
|
||||||
|
coin != Coin.ethereum &&
|
||||||
|
coin != Coin.banano &&
|
||||||
|
coin != Coin.nano)
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: generateNewAddress,
|
onPressed: generateNewAddress,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
|
|
|
@ -148,8 +148,7 @@ class _TransactionDetailsViewState
|
||||||
if (_transaction.numberOfMessages == 1) {
|
if (_transaction.numberOfMessages == 1) {
|
||||||
return "Receiving (waiting for sender)";
|
return "Receiving (waiting for sender)";
|
||||||
} else if ((_transaction.numberOfMessages ?? 0) > 1) {
|
} else if ((_transaction.numberOfMessages ?? 0) > 1) {
|
||||||
return
|
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)
|
||||||
"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 {
|
} else {
|
||||||
return "Receiving";
|
return "Receiving";
|
||||||
}
|
}
|
||||||
|
@ -963,94 +962,99 @@ class _TransactionDetailsViewState
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
isDesktop
|
if (coin != Coin.banano && coin != Coin.nano)
|
||||||
? const _Divider()
|
isDesktop
|
||||||
: const SizedBox(
|
? const _Divider()
|
||||||
height: 12,
|
: const SizedBox(
|
||||||
),
|
height: 12,
|
||||||
RoundedWhiteContainer(
|
),
|
||||||
padding: isDesktop
|
if (coin != Coin.banano && coin != Coin.nano)
|
||||||
? const EdgeInsets.all(16)
|
RoundedWhiteContainer(
|
||||||
: const EdgeInsets.all(12),
|
padding: isDesktop
|
||||||
child: Builder(builder: (context) {
|
? const EdgeInsets.all(16)
|
||||||
String feeString = showFeePending
|
: const EdgeInsets.all(12),
|
||||||
? _transaction.isConfirmed(
|
child: Builder(builder: (context) {
|
||||||
currentHeight,
|
String feeString = showFeePending
|
||||||
coin.requiredConfirmations,
|
? _transaction.isConfirmed(
|
||||||
)
|
currentHeight,
|
||||||
? ref
|
coin.requiredConfirmations,
|
||||||
.watch(pAmountFormatter(coin))
|
)
|
||||||
.format(
|
? ref
|
||||||
fee,
|
.watch(pAmountFormatter(coin))
|
||||||
withUnitName: isTokenTx,
|
.format(
|
||||||
)
|
fee,
|
||||||
: "Pending"
|
withUnitName: isTokenTx,
|
||||||
: ref.watch(pAmountFormatter(coin)).format(
|
)
|
||||||
fee,
|
: "Pending"
|
||||||
withUnitName: isTokenTx,
|
: ref
|
||||||
);
|
.watch(pAmountFormatter(coin))
|
||||||
|
.format(
|
||||||
|
fee,
|
||||||
|
withUnitName: isTokenTx,
|
||||||
|
);
|
||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment:
|
mainAxisAlignment:
|
||||||
MainAxisAlignment.spaceBetween,
|
MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment:
|
||||||
children: [
|
CrossAxisAlignment.start,
|
||||||
Column(
|
children: [
|
||||||
crossAxisAlignment:
|
Column(
|
||||||
CrossAxisAlignment.start,
|
crossAxisAlignment:
|
||||||
children: [
|
CrossAxisAlignment.start,
|
||||||
Text(
|
children: [
|
||||||
"Transaction fee",
|
Text(
|
||||||
style: isDesktop
|
"Transaction fee",
|
||||||
? STextStyles
|
|
||||||
.desktopTextExtraExtraSmall(
|
|
||||||
context)
|
|
||||||
: STextStyles.itemSubtitle(
|
|
||||||
context),
|
|
||||||
),
|
|
||||||
if (isDesktop)
|
|
||||||
const SizedBox(
|
|
||||||
height: 2,
|
|
||||||
),
|
|
||||||
if (isDesktop)
|
|
||||||
SelectableText(
|
|
||||||
feeString,
|
|
||||||
style: isDesktop
|
style: isDesktop
|
||||||
? STextStyles
|
? STextStyles
|
||||||
.desktopTextExtraExtraSmall(
|
|
||||||
context)
|
|
||||||
.copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<
|
|
||||||
StackColors>()!
|
|
||||||
.textDark,
|
|
||||||
)
|
|
||||||
: STextStyles.itemSubtitle12(
|
|
||||||
context),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (!isDesktop)
|
|
||||||
SelectableText(
|
|
||||||
feeString,
|
|
||||||
style: isDesktop
|
|
||||||
? STextStyles
|
|
||||||
.desktopTextExtraExtraSmall(
|
.desktopTextExtraExtraSmall(
|
||||||
context)
|
context)
|
||||||
.copyWith(
|
: STextStyles.itemSubtitle(
|
||||||
color: Theme.of(context)
|
context),
|
||||||
.extension<StackColors>()!
|
),
|
||||||
.textDark,
|
if (isDesktop)
|
||||||
)
|
const SizedBox(
|
||||||
: STextStyles.itemSubtitle12(
|
height: 2,
|
||||||
context),
|
),
|
||||||
|
if (isDesktop)
|
||||||
|
SelectableText(
|
||||||
|
feeString,
|
||||||
|
style: isDesktop
|
||||||
|
? STextStyles
|
||||||
|
.desktopTextExtraExtraSmall(
|
||||||
|
context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<
|
||||||
|
StackColors>()!
|
||||||
|
.textDark,
|
||||||
|
)
|
||||||
|
: STextStyles.itemSubtitle12(
|
||||||
|
context),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
if (isDesktop)
|
if (!isDesktop)
|
||||||
IconCopyButton(data: feeString)
|
SelectableText(
|
||||||
],
|
feeString,
|
||||||
);
|
style: isDesktop
|
||||||
}),
|
? STextStyles
|
||||||
),
|
.desktopTextExtraExtraSmall(
|
||||||
|
context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textDark,
|
||||||
|
)
|
||||||
|
: STextStyles.itemSubtitle12(
|
||||||
|
context),
|
||||||
|
),
|
||||||
|
if (isDesktop)
|
||||||
|
IconCopyButton(data: feeString)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
isDesktop
|
isDesktop
|
||||||
? const _Divider()
|
? const _Divider()
|
||||||
: const SizedBox(
|
: const SizedBox(
|
||||||
|
|
|
@ -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(
|
const SizedBox(
|
||||||
height: 20,
|
height: 20,
|
||||||
),
|
),
|
||||||
if (coin != Coin.epicCash && coin != Coin.ethereum)
|
if (coin != Coin.epicCash &&
|
||||||
|
coin != Coin.ethereum &&
|
||||||
|
coin != Coin.banano &&
|
||||||
|
coin != Coin.nano)
|
||||||
SecondaryButton(
|
SecondaryButton(
|
||||||
buttonHeight: ButtonHeight.l,
|
buttonHeight: ButtonHeight.l,
|
||||||
onPressed: generateNewAddress,
|
onPressed: generateNewAddress,
|
||||||
|
|
|
@ -293,7 +293,11 @@ class BananoWallet extends CoinServiceAPI
|
||||||
Future<Amount> estimateFeeFor(Amount amount, int feeRate) {
|
Future<Amount> estimateFeeFor(Amount amount, int feeRate) {
|
||||||
// fees are always 0 :)
|
// fees are always 0 :)
|
||||||
return Future.value(
|
return Future.value(
|
||||||
Amount(rawValue: BigInt.from(0), fractionDigits: coin.decimals));
|
Amount(
|
||||||
|
rawValue: BigInt.from(0),
|
||||||
|
fractionDigits: coin.decimals,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -302,8 +306,15 @@ class BananoWallet extends CoinServiceAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// TODO: implement fees
|
// Banano 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 {
|
Future<void> updateBalance() async {
|
||||||
final body = jsonEncode({
|
final body = jsonEncode({
|
||||||
|
@ -744,7 +755,7 @@ class BananoWallet extends CoinServiceAPI
|
||||||
);
|
);
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log(
|
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,
|
level: LogLevel.Warning,
|
||||||
);
|
);
|
||||||
GlobalEventBus.instance.fire(
|
GlobalEventBus.instance.fire(
|
||||||
|
|
|
@ -313,7 +313,14 @@ class NanoWallet extends CoinServiceAPI
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// Nano has no fees
|
// 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 {
|
Future<void> updateBalance() async {
|
||||||
final body = jsonEncode({
|
final body = jsonEncode({
|
||||||
|
@ -754,7 +761,11 @@ class NanoWallet extends CoinServiceAPI
|
||||||
coin,
|
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(
|
GlobalEventBus.instance.fire(
|
||||||
WalletSyncStatusChangedEvent(
|
WalletSyncStatusChangedEvent(
|
||||||
WalletSyncStatus.unableToSync,
|
WalletSyncStatus.unableToSync,
|
||||||
|
|
|
@ -40,9 +40,9 @@ abstract class Constants {
|
||||||
static final BigInt _satsPerCoinMonero = BigInt.from(1000000000000);
|
static final BigInt _satsPerCoinMonero = BigInt.from(1000000000000);
|
||||||
static final BigInt _satsPerCoinWownero = BigInt.from(100000000000);
|
static final BigInt _satsPerCoinWownero = BigInt.from(100000000000);
|
||||||
static final BigInt _satsPerCoinNano =
|
static final BigInt _satsPerCoinNano =
|
||||||
BigInt.parse("1000000000000000000000000000000");// 1*10^30
|
BigInt.parse("1000000000000000000000000000000"); // 1*10^30
|
||||||
static final BigInt _satsPerCoinBanano =
|
static final BigInt _satsPerCoinBanano =
|
||||||
BigInt.parse("100000000000000000000000000000");// 1*10^29
|
BigInt.parse("100000000000000000000000000000"); // 1*10^29
|
||||||
static final BigInt _satsPerCoin = BigInt.from(100000000);
|
static final BigInt _satsPerCoin = BigInt.from(100000000);
|
||||||
static const int _decimalPlaces = 8;
|
static const int _decimalPlaces = 8;
|
||||||
static const int _decimalPlacesNano = 30;
|
static const int _decimalPlacesNano = 30;
|
||||||
|
@ -217,8 +217,36 @@ abstract class Constants {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int seedPhraseWordCountBip39 = 12;
|
static int defaultSeedPhraseLengthFor({required Coin coin}) {
|
||||||
static const int seedPhraseWordCountMonero = 25;
|
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 = {
|
static const Map<int, String> monthMapShort = {
|
||||||
1: 'Jan',
|
1: 'Jan',
|
||||||
|
|
Loading…
Reference in a new issue