Skip to content

Commit

Permalink
Merge pull request #3 from x100111010/dev
Browse files Browse the repository at this point in the history
update: support 12 word standard derivation path wallets and bip39 passphrase
  • Loading branch information
x100111010 authored Sep 29, 2024
2 parents 72446ba + b351952 commit 88642ec
Show file tree
Hide file tree
Showing 164 changed files with 8,123 additions and 16,915 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
run: dart run build_runner build

- name: Check Dart Code Formatting
run: dart format --output=none --set-exit-if-changed .
run: dart format --output=none .

- name: Analyze Dart Code
run: dart analyze
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
uses: subosito/flutter-action@v2
with:
channel: stable
flutter-version: 3.22.3
flutter-version: 3.24.0
- run: flutter --version

- name: Set up JDK 17
Expand Down
65 changes: 5 additions & 60 deletions lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,17 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_displaymode/flutter_displaymode.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_portal/flutter_portal.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:oktoast/oktoast.dart';

import 'app_constants.dart';
import 'app_providers.dart';
import 'app_router.dart';
import 'app_styles.dart';
import 'l10n/l10n.dart';
import 'screens/home_screen.dart';
import 'screens/intro_screen.dart';
import 'screens/lock_screen.dart';
import 'screens/logout_screen.dart';
import 'screens/password_lock_screen.dart';
import 'screens/setup_wallet_screen.dart';
import 'screens/splash_screen.dart';
import 'screens/privacy_screen.dart';
import 'themes/themes.dart';
import 'util/platform.dart';
import 'util/routes.dart';

class App extends HookConsumerWidget {
const App({Key? key}) : super(key: key);
Expand Down Expand Up @@ -66,7 +59,7 @@ class App extends HookConsumerWidget {
minHeight: 480,
maxWidth: 720,
),
child: Portal(
child: PrivacyScreen(
child: OKToast(
position: ToastPosition(align: Alignment.topCenter, offset: 40),
textStyle: styles.textStyleSnackbar,
Expand Down Expand Up @@ -104,56 +97,8 @@ class App extends HookConsumerWidget {
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
locale: language.getLocale(),
initialRoute: '/',
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case '/intro':
return NoTransitionRoute(
builder: (_) => const IntroScreen(),
settings: settings,
);
case '/home':
return NoTransitionRoute(
builder: (_) => const HomeScreen(),
settings: settings,
);
// case '/home_transition':
// return NoPopTransitionRoute(
// builder: (_) => const HomeScreen(),
// settings: settings,
// );
case '/lock_screen':
return NoTransitionRoute(
builder: (_) => const LockScreen(),
settings: settings,
);
case '/lock_screen_transition':
return MaterialPageRoute(
builder: (_) => const LockScreen(),
settings: settings,
);
case '/password_lock_screen':
return NoTransitionRoute(
builder: (_) => const PasswordLockScreen(),
settings: settings,
);
case '/logout':
return NoTransitionRoute(
builder: (_) => const LogoutScreen(),
settings: settings,
);
case '/wallet_setup':
return NoTransitionRoute(
builder: (_) => const SetupWalletScreen(),
settings: settings,
);
default:
return NoTransitionRoute(
builder: (_) => const SplashScreen(),
settings: settings,
);
}
},
initialRoute: appRouter.initialRoute,
onGenerateRoute: appRouter.onGenerateRoute,
),
),
),
Expand Down
121 changes: 121 additions & 0 deletions lib/app_router.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import 'package:flutter/material.dart';

import 'screens/screens.dart';
import 'util/routes.dart';

final appRouter = AppRouter();

class _AppScreens {
static const splash = '/';
static const intro = '/intro';
static const wallet = '/wallet';
static const locked = '/locked';
static const lockedWithTransition = '/locked_with_transition';
static const passwordLocked = '/password_locked';
static const logout = '/logout';
static const setupWallet = '/setup_wallet';
}

class AppRouter {
void reload(BuildContext context) =>
_replaceWith(_AppScreens.splash, context);

void startIntro(BuildContext context) =>
_replaceWith(_AppScreens.intro, context);

void setupWallet(BuildContext context) =>
_replaceWith(_AppScreens.setupWallet, context);

void requireUnlock(BuildContext context) =>
_replaceWith(_AppScreens.locked, context);

void lockoutkWithTransition(BuildContext context) =>
_replaceWith(_AppScreens.lockedWithTransition, context);

void requirePassword(BuildContext context) =>
_replaceWith(_AppScreens.passwordLocked, context);

void openWallet(BuildContext context) =>
_replaceWith(_AppScreens.wallet, context);

void logout(BuildContext context) =>
_replaceWith(_AppScreens.logout, context);

bool isTopRoute<T>(BuildContext context) {
bool isTopRoute = false;
Navigator.of(context).popUntil((route) {
isTopRoute = route is T;
return true;
});
return isTopRoute;
}

Future<T?> _replaceWith<T>(String screenName, BuildContext context) {
return Navigator.of(context).pushNamedAndRemoveUntil(
screenName,
(_) => false,
);
}

Future<T?> push<T>(BuildContext context, Route<T> route) {
return Navigator.of(context).push(route);
}

void pop<T>(BuildContext context, {T? withResult = null}) {
Navigator.of(context).pop(withResult);
}

Future<T?> pushAndRemoveUntilHome<T>(BuildContext context, Route<T> route) {
return Navigator.of(context).pushAndRemoveUntil(
route,
RouteUtils.withNameLike(_AppScreens.wallet),
);
}

String initialRoute = _AppScreens.splash;

RouteFactory onGenerateRoute = (RouteSettings settings) {
switch (settings.name) {
case _AppScreens.intro:
return NoTransitionRoute(
builder: (_) => const IntroScreen(),
settings: settings,
);
case _AppScreens.wallet:
return NoTransitionRoute(
builder: (_) => const HomeScreen(),
settings: settings,
);
case _AppScreens.locked:
return BarrierRoute(
builder: (_) => const LockScreen(),
settings: settings,
);
case _AppScreens.lockedWithTransition:
return BarrierRoute(
builder: (_) => const LockScreen(),
settings: settings,
);
case _AppScreens.passwordLocked:
return NoTransitionRoute(
builder: (_) => const PasswordLockScreen(),
settings: settings,
);
case _AppScreens.logout:
return NoTransitionRoute(
builder: (_) => const LogoutScreen(),
settings: settings,
);
case _AppScreens.setupWallet:
return NoTransitionRoute(
builder: (_) => const SetupWalletScreen(),
settings: settings,
);
default:
return NoTransitionRoute(
builder: (_) => const SplashScreen(),
settings: settings,
);
}
};
}
2 changes: 1 addition & 1 deletion lib/chain_state/chain_state.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import '../settings/settings_providers.dart';
import '../settings/settings_repository.dart';
import 'chain_state_types.dart';

export 'chain_state_types.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/coingecko/coingecko_price_notifier.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../app_providers.dart';
import '../settings/settings_repository.dart';
import 'coingecko_types.dart';

const _kCoinGeckoPriceKey = '_coingeckoPriceKey';
Expand Down
12 changes: 7 additions & 5 deletions lib/coingecko/coingecko_providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ final _spectrePriceCacheProvider =
return CoinGeckoPriceNotifier(repository);
});

final _spectrePriceRemoteProvider = FutureProvider<CoinGeckoPrice>((ref) async {
final _spectrePriceRemoteProvider =
FutureProvider.autoDispose<CoinGeckoPrice>((ref) async {
ref.watch(remoteRefreshProvider);
ref.watch(timeProvider);

final currency = ref.watch(currencyProvider);
final fiat = currency.name.toLowerCase();
Expand All @@ -24,9 +26,9 @@ final _spectrePriceRemoteProvider = FutureProvider<CoinGeckoPrice>((ref) async {

// 60 seconds
final maxCacheAge = 60 * 1000;
final nowTimestamp = DateTime.now().millisecondsSinceEpoch;
final timestamp = DateTime.now().millisecondsSinceEpoch;
if (cached.currency == currency.currency &&
nowTimestamp - cached.timestamp < maxCacheAge) {
timestamp - cached.timestamp < maxCacheAge) {
log.d('Using cached CoinGecko exchange rates');
return cached;
}
Expand All @@ -40,7 +42,7 @@ final _spectrePriceRemoteProvider = FutureProvider<CoinGeckoPrice>((ref) async {
return CoinGeckoPrice(
currency: currency.currency,
price: Decimal.parse(price.toString()),
timestamp: nowTimestamp,
timestamp: timestamp,
);
} catch (e, st) {
log.e('Failed to fetch SPR exchange rate', error: e, stackTrace: st);
Expand All @@ -50,7 +52,7 @@ final _spectrePriceRemoteProvider = FutureProvider<CoinGeckoPrice>((ref) async {
return CoinGeckoPrice(
currency: currency.currency,
price: Decimal.zero,
timestamp: nowTimestamp,
timestamp: timestamp,
);
}
});
Expand Down
5 changes: 3 additions & 2 deletions lib/contacts/contact_add_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../app_icons.dart';
import '../app_providers.dart';
import '../app_router.dart';
import '../spectre/spectre.dart';
import '../l10n/l10n.dart';
import '../util/formatters.dart';
Expand Down Expand Up @@ -263,7 +264,7 @@ class _ContactAddSheetState extends ConsumerState<ContactAddSheet> {
const SizedBox(height: 16),
PrimaryOutlineButton(
title: l10n.close,
onPressed: () => Navigator.pop(context),
onPressed: () => appRouter.pop(context),
),
],
),
Expand All @@ -286,7 +287,7 @@ class _ContactAddSheetState extends ConsumerState<ContactAddSheet> {
await contacts.addContact(newContact);
final l10n = l10nOf(context);
UIUtil.showSnackbar(l10n.contactAdded(newContact.name), context);
Navigator.of(context).pop();
appRouter.pop(context);
}

Future<bool> _validateForm() async {
Expand Down
7 changes: 4 additions & 3 deletions lib/contacts/contact_details.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import '../app_providers.dart';
import '../app_router.dart';
import '../l10n/l10n.dart';
import '../send_sheet/send_sheet.dart';
import '../util/ui_util.dart';
Expand Down Expand Up @@ -43,7 +44,7 @@ class ContactDetails extends HookConsumerWidget {
ref.read(contactsProvider).removeContact(contact);
final message = l10n.contactRemoved(contact.name);
UIUtil.showSnackbar(message, context);
Navigator.of(context).pop();
appRouter.pop(context);
}

void confirmDeleteContact() {
Expand All @@ -68,7 +69,7 @@ class ContactDetails extends HookConsumerWidget {
}

void showSendSheet() {
Navigator.of(context).pop();
appRouter.pop(context);
Sheets.showAppHeightNineSheet(
context: context,
theme: theme,
Expand Down Expand Up @@ -213,7 +214,7 @@ class ContactDetails extends HookConsumerWidget {
const SizedBox(height: 16),
PrimaryOutlineButton(
title: l10n.close,
onPressed: () => Navigator.pop(context),
onPressed: () => appRouter.pop(context),
),
]),
),
Expand Down
5 changes: 2 additions & 3 deletions lib/core/core_providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ final sharedPrefsProvider =

final hapticUtilProvider = Provider((ref) => const HapticUtil());
final authUtilProvider = Provider((ref) => AuthUtil(ref));
final biometricUtilProvider = Provider(
(ref) => BiometricUtil(ref.watch(loggerProvider)),
);
final biometricUtilProvider = Provider((ref) => BiometricUtil());
final vaultProvider = Provider((ref) => Vault());
final sharedPrefsUtilProvider = Provider((ref) {
final sharedPrefs = ref.watch(sharedPrefsProvider);
Expand Down Expand Up @@ -178,6 +176,7 @@ final virtualSelectedParentBlueScoreStreamProvider = StreamProvider((ref) {
final remoteRefreshProvider = StateProvider((ref) => 0);

final lockDisabledProvider = StateProvider((ref) => false);
final privacyOverlayDisabledProvider = StateProvider((ref) => false);

final maxSendProvider = Provider.autoDispose((ref) {
final utxos = ref.watch(spendableUtxosProvider);
Expand Down
Loading

0 comments on commit 88642ec

Please sign in to comment.