Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
3155dab
feat: add new font families
dewabisma Apr 10, 2026
6c5b673
feat: remove accentPink, add accentOrange, update checksum color
dewabisma Apr 10, 2026
89192a4
feat: update background color
dewabisma Apr 10, 2026
f734185
feat: updated icon button
dewabisma Apr 10, 2026
c57b838
feat: update standard button
dewabisma Apr 10, 2026
e005f88
feat: update send and receive
dewabisma Apr 12, 2026
cb71838
feat: finish updating activity section
dewabisma Apr 12, 2026
f1cba5b
chore: formatting
dewabisma Apr 12, 2026
6642684
chore: ignore linter for secondary font family yet used
dewabisma Apr 12, 2026
01d2e21
feat: revert number format to trailing
dewabisma Apr 12, 2026
d4bfdb3
feat: finish new receive screen
dewabisma Apr 13, 2026
3f26526
feat: standardized circular loader
dewabisma Apr 13, 2026
875ca6e
feat: finish updating toaster and copy button
dewabisma Apr 13, 2026
4b51e4c
feat: improve balance loading
dewabisma Apr 13, 2026
a6cffd6
Merge branch 'beast/redesign-home-screen' into beast/redesign-receive…
dewabisma Apr 13, 2026
9bd0554
Merge branch 'main' of https://github.com/Quantus-Network/quantus-app…
dewabisma Apr 15, 2026
a9f2870
fix: migration dialog button
dewabisma Apr 15, 2026
aeb7e29
feat: address reviews
dewabisma Apr 15, 2026
836d97c
feat: add geist font license
dewabisma Apr 15, 2026
6af5a54
WIP: currency system
dewabisma Apr 15, 2026
7effe0f
feat: finish updating currency display
dewabisma Apr 15, 2026
2c1d741
Merge branch 'beast/redesign-home-screen' of https://github.com/Quant…
dewabisma Apr 15, 2026
60e7353
chore: formatting
dewabisma Apr 15, 2026
584687b
Merge branch 'beast/redesign-home-screen' of https://github.com/Quant…
dewabisma Apr 16, 2026
05b20f4
feat: resolve review issues
dewabisma Apr 16, 2026
3ac7b33
feat: update styling receive screen, add filter buttons
dewabisma Apr 16, 2026
fb11f06
feat: finish integrating filtered history
dewabisma Apr 17, 2026
8fbadde
feat: better loading UX
dewabisma Apr 17, 2026
e20b97c
feat: optimize graphql query performance
dewabisma Apr 17, 2026
9d19fd2
chore: revert print timing
dewabisma Apr 17, 2026
48e6d0b
feat: make tx details respect currency flip and hidden state
dewabisma Apr 17, 2026
4612347
feat: extract text style to theme
dewabisma Apr 17, 2026
cb49301
chore: formatting
dewabisma Apr 17, 2026
7db8d5d
fix: not properly display quan symbol in tx item
dewabisma Apr 17, 2026
53238bf
Merge branch 'feat/v3' of https://github.com/Quantus-Network/quantus-…
dewabisma Apr 20, 2026
71a1999
feat: resolved PR review issues
dewabisma Apr 20, 2026
b462185
Merge branch 'beast/redesign-home-screen' of https://github.com/Quant…
dewabisma Apr 20, 2026
9601a80
feat: remove asset declaration
dewabisma Apr 20, 2026
489c400
!!!erge branch 'beast/redesign-home-screen' of https://github.com/Qua…
dewabisma Apr 20, 2026
7b184ec
feat: resolve PR review issues
dewabisma Apr 20, 2026
53b81c2
Merge branch 'beast/redesign-receive-screen' of https://github.com/Qu…
dewabisma Apr 20, 2026
9fb57b2
feat: resolve PR review issues
dewabisma Apr 20, 2026
e43e9a7
Merge branch 'feat/v3' of https://github.com/Quantus-Network/quantus-…
dewabisma Apr 21, 2026
14629a5
feat: finish initial send and qr scan screens
dewabisma Apr 21, 2026
c552669
feat: finalize initial send screen
dewabisma Apr 21, 2026
158467f
wip: new send flow
dewabisma Apr 21, 2026
2cd84a2
feat: handle clear field on click edit recipient icon
dewabisma Apr 21, 2026
65d4803
feat: finish review send screen
dewabisma Apr 22, 2026
867665a
feat: finish send screen flow redesign
dewabisma Apr 22, 2026
1bd6cb7
chore: formatting
dewabisma Apr 22, 2026
607edba
fix: bad QR pay handling
dewabisma Apr 22, 2026
30b904a
fix: review issues
dewabisma Apr 22, 2026
e97339f
fix: review issues
dewabisma Apr 22, 2026
da36b1b
fix: review issues
dewabisma Apr 22, 2026
116c25c
fix: review issues
dewabisma Apr 22, 2026
e4774df
feat: update scaffold base to support bottom content, also update rec…
dewabisma Apr 23, 2026
39a5f25
feat: finish refactor send flow screens
dewabisma Apr 23, 2026
32f73d4
feat: finish updating button icon styling
dewabisma Apr 24, 2026
8af509c
feat: proper icon button API design
dewabisma Apr 24, 2026
ff608d6
feat: finish updating main button styling
dewabisma Apr 24, 2026
6faacac
feat: finish select accounts button
dewabisma Apr 24, 2026
ab80955
feat: finish account edit flow
dewabisma Apr 24, 2026
bb659c1
wip: account add flow
dewabisma Apr 24, 2026
377b97a
feat: finish account create flow
dewabisma Apr 24, 2026
f96b37b
feat: add recovery phrase menu in account details
dewabisma Apr 24, 2026
121eaa2
feat: glass back button
dewabisma Apr 24, 2026
f00b689
wip: setting screens style update
dewabisma Apr 24, 2026
5d0aabb
feat: finish about screen
dewabisma Apr 24, 2026
97b0a50
feat: finish help and support screen
dewabisma Apr 24, 2026
c5438fd
feat: finish account type screen
dewabisma Apr 24, 2026
063d305
feat: finish preference settings
dewabisma Apr 24, 2026
915d382
feat: finish wallet preference menu
dewabisma Apr 25, 2026
c2be777
feat: handle DRY violation
dewabisma Apr 26, 2026
d9bed25
fix: fixing review issues
dewabisma Apr 26, 2026
c654ce3
fix: review issues
dewabisma Apr 26, 2026
1f15413
fix: review issues
dewabisma Apr 26, 2026
40bc8bc
fix: review issues
dewabisma Apr 26, 2026
a723bd2
fix: review issues
dewabisma Apr 27, 2026
a9bed58
Merge branch 'beast/redesign-send-screen' of https://github.com/Quant…
dewabisma Apr 27, 2026
8f261f9
Merge branch 'beast/improve-scaffold-base' of https://github.com/Quan…
dewabisma Apr 27, 2026
a5d790f
Merge branch 'beast/redesign-account-management' of https://github.co…
dewabisma Apr 27, 2026
c966caf
Merge branch 'feat/v3' of https://github.com/Quantus-Network/quantus-…
dewabisma Apr 28, 2026
6e0efb6
Beast/redesign account management (#461)
dewabisma Apr 28, 2026
d3e7910
Merge branch 'feat/v3' of https://github.com/Quantus-Network/quantus-…
dewabisma Apr 28, 2026
0bbcb87
Merge branch 'beast/improve-scaffold-base' into beast/settings-screen
dewabisma Apr 28, 2026
023f18c
fix: DRY violation, wrong border color
dewabisma Apr 28, 2026
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
4 changes: 4 additions & 0 deletions miner-app/macos/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,9 @@
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>mailto</string>
</array>
</dict>
</plist>
4 changes: 4 additions & 0 deletions mobile-app/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="mailto" />
</intent>

<!-- Add this for url_launcher to work with HTTPS URLs -->
<intent>
Expand Down
Binary file removed mobile-app/assets/v2/glass_104_x_80.png
Binary file not shown.
Binary file removed mobile-app/assets/v2/glass_40.png
Binary file not shown.
Binary file removed mobile-app/assets/v2/glass_border_bg.png
Binary file not shown.
Binary file removed mobile-app/assets/v2/glass_medium_button_bg.png
Binary file not shown.
Binary file removed mobile-app/assets/v2/glass_medium_clear.png
Binary file not shown.
Binary file removed mobile-app/assets/v2/glass_medium_clear_small.png
Binary file not shown.
Binary file removed mobile-app/assets/v2/glass_tiny_button.png
Binary file not shown.
Binary file removed mobile-app/assets/v2/glass_wide_clear.png
Binary file not shown.
Binary file removed mobile-app/assets/v2/receive_button.png
Binary file not shown.
Binary file removed mobile-app/assets/v2/send_button.png
Binary file not shown.
Binary file removed mobile-app/assets/v2/swap_button.png
Binary file not shown.
44 changes: 20 additions & 24 deletions mobile-app/lib/features/components/mnemonic_grid.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:quantus_sdk/quantus_sdk.dart';
import 'package:resonance_network_wallet/shared/extensions/media_query_data_extension.dart';
import 'package:resonance_network_wallet/v2/components/liquid_glass_base.dart';
import 'package:resonance_network_wallet/v2/theme/app_colors.dart';
import 'package:resonance_network_wallet/v2/theme/app_text_styles.dart';

Expand Down Expand Up @@ -47,32 +45,30 @@ class MnemonicGrid extends StatelessWidget {
}

Widget _buildMnemonicWord(int index, String word, bool isRevealed, BuildContext context) {
final padding = const EdgeInsets.symmetric(horizontal: 12);
final padding = const EdgeInsets.symmetric(horizontal: 14);
final double blur = isRevealed ? 0 : 5;
final effectiveWord = isRevealed ? word : 'x' * word.length;

return LiquidGlassBase.rounded(
glassColor: context.colors.surfaceGlass,
child: SizedBox(
height: double.infinity,
width: double.infinity,
child: Padding(
padding: padding,
child: Row(
children: [
Text(
'$index',
textAlign: TextAlign.left,
style: context.themeText.detail?.copyWith(color: context.colors.textPrimary.useOpacity(0.5)),
),
const SizedBox(width: 8),
ImageFiltered(
imageFilter: ImageFilter.blur(sigmaX: blur, sigmaY: blur),
child: Text(effectiveWord, textAlign: TextAlign.left, style: context.themeText.detail),
),
],
return Container(
padding: padding,
decoration: BoxDecoration(color: context.colors.surfaceDeep, borderRadius: BorderRadius.circular(14)),
child: Row(
children: [
Text(
'$index',
textAlign: TextAlign.left,
style: context.themeText.detail?.copyWith(color: context.colors.textTertiary),
),
),
const SizedBox(width: 8),
ImageFiltered(
imageFilter: ImageFilter.blur(sigmaX: blur, sigmaY: blur),
child: Text(
effectiveWord,
textAlign: TextAlign.left,
style: context.themeText.detail?.copyWith(color: context.colors.checksum),
),
),
],
),
);
}
Expand Down
18 changes: 11 additions & 7 deletions mobile-app/lib/models/fiat_currency.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
/// Adding a new currency only requires a new enum case here and a matching
/// rate in [ExchangeRateService]. No widget or provider changes are needed.
enum FiatCurrency {
usd(code: 'USD', symbol: '\$', symbolPosition: SymbolPosition.prefix),
myr(code: 'MYR', symbol: 'RM', symbolPosition: SymbolPosition.prefix),
idr(code: 'IDR', symbol: 'Rp', symbolPosition: SymbolPosition.prefix),
jpy(code: 'JPY', symbol: '¥', symbolPosition: SymbolPosition.prefix),
eur(code: 'EUR', symbol: '€', symbolPosition: SymbolPosition.prefix),
gbp(code: 'GBP', symbol: '£', symbolPosition: SymbolPosition.prefix);
usd(code: 'USD', symbol: '\$', symbolPosition: SymbolPosition.prefix, fullName: 'United States Dollar'),
myr(code: 'MYR', symbol: 'RM', symbolPosition: SymbolPosition.prefix, fullName: 'Malaysian Ringgit'),
idr(code: 'IDR', symbol: 'Rp', symbolPosition: SymbolPosition.prefix, fullName: 'Indonesian Rupiah'),
jpy(code: 'JPY', symbol: '¥', symbolPosition: SymbolPosition.prefix, fullName: 'Japanese Yen'),
eur(code: 'EUR', symbol: '€', symbolPosition: SymbolPosition.prefix, fullName: 'Euro'),
gbp(code: 'GBP', symbol: '£', symbolPosition: SymbolPosition.prefix, fullName: 'British Pound');

const FiatCurrency({required this.code, required this.symbol, required this.symbolPosition});
const FiatCurrency({required this.code, required this.symbol, required this.symbolPosition, required this.fullName});

/// ISO 4217 code, e.g. "USD", "IDR". Used for persistence and display.
final String code;
Expand All @@ -21,6 +21,8 @@ enum FiatCurrency {

final SymbolPosition symbolPosition;

final String fullName;

/// Wraps a pre-formatted numeric [amount] string with this currency's symbol.
///
/// Example:
Expand All @@ -35,6 +37,8 @@ enum FiatCurrency {
static FiatCurrency fromCode(String code, {FiatCurrency fallback = FiatCurrency.usd}) {
return FiatCurrency.values.firstWhere((c) => c.code == code, orElse: () => fallback);
}

String get line => '$code - $fullName ($symbol)';
}

enum SymbolPosition { prefix, suffix }
2 changes: 1 addition & 1 deletion mobile-app/lib/providers/account_providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class AccountsNotifier extends StateNotifier<AsyncValue<List<Account>>> {
state.whenData((accounts) async {
try {
await _accountsService.removeAccount(account);
final newAccounts = accounts.where((a) => a.index != account.index).toList();
final newAccounts = accounts.where((a) => a.accountId != account.accountId).toList();
state = AsyncValue.data(newAccounts);
} catch (e, st) {
print('remove account error $e $st');
Expand Down
24 changes: 24 additions & 0 deletions mobile-app/lib/shared/utils/account_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,27 @@ List<int> getNonHardwareWalletIndices(List<Account> accounts) {
}
return nonHardwareWalletIndices.toList()..sort();
}

/// Smallest non-negative index not used as [Account.walletIndex] by any non-hardware account.
/// Use when importing a new recovery phrase or otherwise adding a distinct software HD wallet.
int nextNonHardwareWalletIndex(List<Account> accounts) {
final used = getNonHardwareWalletIndices(accounts).toSet();
var i = 0;
while (used.contains(i)) {
i++;
}
return i;
}

String getAccountBadgeInitials(String text, {required String separator}) {
if (text.isEmpty) return '?';

final parts = text.split(separator).map((s) => s.trim()).where((s) => s.isNotEmpty).toList();
if (parts.length >= 2) {
final a = parts[0];
final b = parts[1];
return '${a[0]}${b[0]}'.toUpperCase();
}

return text.length >= 2 ? text.substring(0, 2).toUpperCase() : text[0].toUpperCase();
}
29 changes: 29 additions & 0 deletions mobile-app/lib/v2/components/account_badge.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'package:quantus_sdk/quantus_sdk.dart';
import 'package:resonance_network_wallet/shared/utils/account_utils.dart';
import 'package:resonance_network_wallet/v2/theme/app_colors.dart';
import 'package:resonance_network_wallet/v2/theme/app_text_styles.dart';

class AccountBadge extends StatelessWidget {
final Account account;
final bool isActive;
final double size;
final TextStyle? textStyle;

const AccountBadge({super.key, required this.account, this.isActive = false, this.size = 40, this.textStyle});

@override
Widget build(BuildContext context) {
final colors = context.colors;
final label = getAccountBadgeInitials(account.name, separator: ' ');
final effectiveTextStyle = textStyle ?? context.themeText.transactionDetailRowValue?.copyWith(letterSpacing: -0.25);

return Container(
width: size,
height: size,
alignment: Alignment.center,
decoration: BoxDecoration(color: colors.sheetBackground, borderRadius: BorderRadius.circular(size / 2)),
child: Text(label, style: effectiveTextStyle?.copyWith(color: isActive ? colors.accentOrange : colors.textLabel)),
);
}
}
14 changes: 2 additions & 12 deletions mobile-app/lib/v2/components/address_checkphrase_with_initial.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/widgets.dart';
import 'package:quantus_sdk/quantus_sdk.dart';
import 'package:resonance_network_wallet/shared/utils/account_utils.dart';
import 'package:resonance_network_wallet/v2/theme/app_colors.dart';
import 'package:resonance_network_wallet/v2/theme/app_text_styles.dart';

Expand All @@ -9,17 +10,6 @@ class AddressCheckphraseWithInitial extends StatelessWidget {

const AddressCheckphraseWithInitial({super.key, required this.recipientChecksum, required this.recipientAddress});

String _initials(String? checksum) {
if (checksum == null || checksum.isEmpty) return '?';
final parts = checksum.split('-').map((s) => s.trim()).where((s) => s.isNotEmpty).toList();
if (parts.length >= 2) {
final a = parts[0];
final b = parts[1];
return '${a[0]}${b[0]}'.toUpperCase();
}
return checksum.length >= 2 ? checksum.substring(0, 2).toUpperCase() : checksum[0].toUpperCase();
}

@override
Widget build(BuildContext context) {
final colors = context.colors;
Expand All @@ -36,7 +26,7 @@ class AddressCheckphraseWithInitial extends StatelessWidget {
alignment: Alignment.center,
decoration: BoxDecoration(color: colors.sheetBackground, borderRadius: BorderRadius.circular(20)),
child: Text(
_initials(recipientChecksum),
getAccountBadgeInitials(recipientChecksum, separator: '-'),
style: text.transactionDetailRowValue?.copyWith(color: colors.textLabel),
),
),
Expand Down
145 changes: 145 additions & 0 deletions mobile-app/lib/v2/components/address_details_card.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:resonance_network_wallet/shared/extensions/clipboard_extensions.dart';
import 'package:resonance_network_wallet/v2/components/split_card.dart';
import 'package:resonance_network_wallet/v2/theme/app_colors.dart';
import 'package:resonance_network_wallet/v2/theme/app_text_styles.dart';

class AddressDetailsCard extends StatefulWidget {
final String accountId;
final String? checksum;

const AddressDetailsCard({super.key, required this.accountId, this.checksum});

@override
State<AddressDetailsCard> createState() => _AddressDetailsCardState();
}

class _AddressDetailsCardState extends State<AddressDetailsCard> {
bool _addressCopied = false;
bool _checksumCopied = false;
Timer? _resetTimer;

void _copyAddress(BuildContext context) {
context.copyTextWithToaster(widget.accountId);
_triggerCopied(isAddress: true);
}

void _copyChecksum(BuildContext context) {
if (widget.checksum == null) return;

context.copyTextWithToaster(widget.checksum!, message: 'Checkphrase copied');
_triggerCopied(isAddress: false);
}

void _triggerCopied({required bool isAddress}) {
_resetTimer?.cancel();

setState(() {
if (isAddress) {
_addressCopied = true;
_checksumCopied = false;
} else {
_checksumCopied = true;
_addressCopied = false;
}
});

_resetTimer = Timer(const Duration(seconds: 2), () {
if (mounted) {
setState(() {
if (isAddress) {
_addressCopied = false;
} else {
_checksumCopied = false;
}
});
}
});
}

@override
void dispose() {
_resetTimer?.cancel();
super.dispose();
}

@override
Widget build(BuildContext context) {
return SplitCard(
topChild: InkWell(
onTap: () => _copyAddress(context),
child: _buildItem(context, 'ADDRESS', widget.accountId, isCopied: _addressCopied),
),
bottomChild: InkWell(
onTap: () => _copyChecksum(context),
child: _buildItem(
context,
'CHECKPHRASE',
widget.checksum ?? 'Loading...',
isCheckphrase: true,
isCopied: _checksumCopied,
),
),
);
}

Widget _buildItem(
BuildContext context,
String label,
String value, {
bool isCheckphrase = false,
required bool isCopied,
}) {
final valueTextStyle = isCheckphrase
? context.themeText.smallParagraph?.copyWith(color: context.colors.checksum)
: context.themeText.smallParagraph?.copyWith(fontFamily: AppTextTheme.fontFamilySecondary);

return Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(label, style: context.themeText.receiveLabel?.copyWith(color: context.colors.textLabel)),
const SizedBox(height: 16),
Text(value, style: valueTextStyle),
],
),
),

const SizedBox(width: 32),

_copyButton(isCopied: isCopied),
],
);
}

Widget _copyButton({required bool isCopied}) {
final containerSize = 40.0;
final iconSize = 16.0;

return AnimatedContainer(
duration: const Duration(milliseconds: 200),
width: containerSize,
height: containerSize,
decoration: BoxDecoration(
color: isCopied ? context.colors.copyButtonCopiedBg : Colors.transparent,
border: Border.all(
color: isCopied ? context.colors.copyButtonCopiedBorder : context.colors.borderButton,
width: 1,
),
borderRadius: BorderRadius.circular(containerSize / 2),
),
child: Center(
child: Icon(
isCopied ? Icons.check : Icons.copy,
size: iconSize,
color: isCopied ? context.colors.success : context.colors.textPrimary,
),
),
);
}
}
Loading