Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
7f1734b
feat(auth): migrate to streamed auth and trezor support (#2826)
takenagain Jun 25, 2025
b1ea752
refactor(trezor): migrate trezor blocs to AuthBloc using SDK
takenagain Jun 26, 2025
c16267f
fix(transaction): only remove sender if `to` list has more than 1 entry
takenagain Jun 26, 2025
27cce70
fix(activation): ensure only trezor default coins are activated
takenagain Jun 26, 2025
df8a470
fix(coins-bloc): emit known coins in pre-populate step
takenagain Jul 1, 2025
4cd8b41
fix(price-chart): move assetId mapping to bloc
takenagain Jul 1, 2025
7f8a9c0
Merge remote-tracking branch 'origin/dev' into feat/trezor-sdk-migration
takenagain Jul 1, 2025
755561d
fix(ui): hide error dialog icon in trezor popup
takenagain Jul 2, 2025
1c6da38
chore(deps): bump SDK to a02c4a224 for trezor auth fixes
takenagain Jul 2, 2025
5c029de
fix(coins-manager): remove redundant trezor support coin filter
takenagain Jul 2, 2025
321aae4
fix(trezor): consolidate enabled by default coin lists
takenagain Jul 2, 2025
d5b869c
fix(auth): revert changes to non-trezor sign-in and register methods
takenagain Jul 2, 2025
12d5700
refactor: remove unused imports and log caught exceptions
takenagain Jul 2, 2025
05936a0
Merge remote-tracking branch 'origin/dev' into feat/trezor-sdk-migration
takenagain Jul 2, 2025
3d5bf12
feat(address-creation): use streamed address creation (#2874)
takenagain Jul 6, 2025
f176228
Merge branch 'dev' into feat/trezor-sdk-migration
takenagain Jul 7, 2025
382e393
Merge dev into feat/trezor-sdk-migration
CharlVS Jul 8, 2025
84ac45e
Revert pubspec.lock files to dev state
CharlVS Jul 8, 2025
3ccac1e
fix: re-roll sdk
CharlVS Jul 8, 2025
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
2 changes: 1 addition & 1 deletion assets/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@
"trezorEnterPinHint": "The PIN layout is displayed on your Trezor",
"trezorInProgressTitle": "Looking for your Trezor...",
"trezorInProgressHint": "Please do not disable your Trezor",
"trezorErrorBusy": "Device is busy.\n' Make sure that Trezor Suite is not running in background.",
"trezorErrorBusy": "Device is busy.\nMake sure that Trezor Suite is not running in background.",
"trezorErrorInvalidPin": "Invalid PIN code",
"trezorSelectTitle": "Connect a hardware wallet",
"trezorSelectSubTitle": "Select a hardware wallet you'd like to use with Komodo Wallet",
Expand Down
15 changes: 0 additions & 15 deletions lib/app_config/app_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,6 @@ const Set<String> excludedAssetList = {
'NFT_MATIC',
};

const List<String> excludedAssetListTrezor = [
// https://github.com/KomodoPlatform/atomicDEX-API/issues/1510
'BCH',
// https://github.com/KomodoPlatform/coins/pull/619/files
// Can't use modified config directly, since it includes features,
// not implemented on webdex side yet (e.g. 0.4.2 doesn't have segwit)
'VAL',
];

/// Some coins returned by the Banxa API are returning errors when attempting
/// to create an order. This is a temporary workaround to filter out those coins
/// until the issue is resolved.
Expand Down Expand Up @@ -150,12 +141,6 @@ List<String> get enabledByDefaultCoins => [
if (kDebugMode) 'MARTY',
];

List<String> get enabledByDefaultTrezorCoins => [
'BTC-segwit',
'KMD',
'LTC-segwit',
];

List<String> get coinsWithFaucet => ['RICK', 'MORTY', 'DOC', 'MARTY'];

const String logsDbName = 'logs';
Expand Down
21 changes: 0 additions & 21 deletions lib/bloc/app_bloc_root.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,10 @@ import 'package:web_dex/bloc/taker_form/taker_bloc.dart';
import 'package:web_dex/bloc/trading_status/trading_status_repository.dart';
import 'package:web_dex/bloc/transaction_history/transaction_history_bloc.dart';
import 'package:web_dex/bloc/transaction_history/transaction_history_repo.dart';
import 'package:web_dex/bloc/trezor_bloc/trezor_repo.dart';
import 'package:web_dex/bloc/trezor_connection_bloc/trezor_connection_bloc.dart';
import 'package:web_dex/bloc/trezor_init_bloc/trezor_init_bloc.dart';
import 'package:web_dex/blocs/kmd_rewards_bloc.dart';
import 'package:web_dex/blocs/maker_form_bloc.dart';
import 'package:web_dex/blocs/orderbook_bloc.dart';
import 'package:web_dex/blocs/trading_entities_bloc.dart';
import 'package:web_dex/blocs/trezor_coins_bloc.dart';
import 'package:web_dex/blocs/wallets_repository.dart';
import 'package:web_dex/main.dart';
import 'package:web_dex/mm2/mm2_api/mm2_api.dart';
Expand Down Expand Up @@ -117,8 +113,6 @@ class AppBlocRoot extends StatelessWidget {
myOrdersService,
);
final dexRepository = DexRepository(mm2Api);
final trezorRepo = RepositoryProvider.of<TrezorRepo>(context);
final trezorBloc = RepositoryProvider.of<TrezorCoinsBloc>(context);

final transactionsRepo = performanceMode != null
? MockTransactionHistoryRepo(
Expand Down Expand Up @@ -185,7 +179,6 @@ class AppBlocRoot extends StatelessWidget {
create: (context) => CoinsBloc(
komodoDefiSdk,
coinsRepository,
trezorBloc,
mm2Api,
)..add(CoinsStarted()),
),
Expand Down Expand Up @@ -256,13 +249,6 @@ class AppBlocRoot extends StatelessWidget {
analyticsBloc: BlocProvider.of<AnalyticsBloc>(context),
),
),
BlocProvider(
create: (_) => TrezorConnectionBloc(
trezorRepo: trezorRepo,
kdfSdk: komodoDefiSdk,
),
lazy: false,
),
BlocProvider(
lazy: false,
create: (context) => NftMainBloc(
Expand Down Expand Up @@ -298,13 +284,6 @@ class AppBlocRoot extends StatelessWidget {
create: (_) => SystemHealthBloc(SystemClockRepository(), mm2Api)
..add(SystemHealthPeriodicCheckStarted()),
),
BlocProvider<TrezorInitBloc>(
create: (context) => TrezorInitBloc(
kdfSdk: komodoDefiSdk,
trezorRepo: trezorRepo,
coinsRepository: coinsRepository,
),
),
BlocProvider<CoinsManagerBloc>(
create: (context) => CoinsManagerBloc(
coinsRepo: coinsRepository,
Expand Down
9 changes: 8 additions & 1 deletion lib/bloc/auth_bloc/auth_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:komodo_defi_sdk/komodo_defi_sdk.dart';
import 'package:komodo_defi_types/komodo_defi_types.dart';
import 'package:logging/logging.dart';
import 'package:komodo_defi_rpc_methods/komodo_defi_rpc_methods.dart'
show PrivateKeyPolicy;
import 'package:web_dex/app_config/app_config.dart';
import 'package:web_dex/bloc/settings/settings_repository.dart';
import 'package:web_dex/blocs/wallets_repository.dart';
Expand All @@ -14,10 +16,11 @@ import 'package:web_dex/model/wallet.dart';

part 'auth_bloc_event.dart';
part 'auth_bloc_state.dart';
part 'trezor_auth_mixin.dart';

/// AuthBloc is responsible for managing the authentication state of the
/// application. It handles events such as login and logout changes.
class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> with TrezorAuthMixin {
/// Handles [AuthBlocEvent]s and emits [AuthBlocState]s.
/// [_kdfSdk] is an instance of [KomodoDefiSdk] used for authentication.
AuthBloc(this._kdfSdk, this._walletsRepository, this._settingsRepository)
Expand All @@ -31,6 +34,7 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
on<AuthSeedBackupConfirmed>(_onSeedBackupConfirmed);
on<AuthWalletDownloadRequested>(_onWalletDownloadRequested);
on<AuthLifecycleCheckRequested>(_onLifecycleCheckRequested);
setupTrezorEventHandlers();
}

final KomodoDefiSdk _kdfSdk;
Expand All @@ -39,6 +43,9 @@ class AuthBloc extends Bloc<AuthBlocEvent, AuthBlocState> {
StreamSubscription<KdfUser?>? _authChangesSubscription;
final _log = Logger('AuthBloc');

@override
KomodoDefiSdk get _sdk => _kdfSdk;

@override
Future<void> close() async {
await _authChangesSubscription?.cancel();
Expand Down
20 changes: 20 additions & 0 deletions lib/bloc/auth_bloc/auth_bloc_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ class AuthWalletDownloadRequested extends AuthBlocEvent {
final String password;
}

class AuthTrezorInitAndAuthStarted extends AuthBlocEvent {
const AuthTrezorInitAndAuthStarted();
}

class AuthTrezorPinProvided extends AuthBlocEvent {
const AuthTrezorPinProvided(this.pin);

final String pin;
}

class AuthTrezorPassphraseProvided extends AuthBlocEvent {
const AuthTrezorPassphraseProvided(this.passphrase);

final String passphrase;
}

class AuthTrezorCancelled extends AuthBlocEvent {
const AuthTrezorCancelled();
}

/// Event emitted on app lifecycle changes to check if a user is already signed
/// in and restore the auth state.
class AuthLifecycleCheckRequested extends AuthBlocEvent {
Expand Down
69 changes: 58 additions & 11 deletions lib/bloc/auth_bloc/auth_bloc_state.dart
Original file line number Diff line number Diff line change
@@ -1,41 +1,88 @@
part of 'auth_bloc.dart';

enum AuthStatus { initial, loading, success, failure }

class AuthBlocState extends Equatable {
const AuthBlocState({
required this.mode,
this.currentUser,
this.status = AuthStatus.initial,
this.authenticationState,
this.authError,
});

factory AuthBlocState.initial() =>
const AuthBlocState(mode: AuthorizeMode.noLogin);
factory AuthBlocState.loading() => const AuthBlocState(
mode: AuthorizeMode.noLogin,
status: AuthStatus.loading,
authenticationState:
AuthenticationState(status: AuthenticationStatus.initializing),
);
factory AuthBlocState.error(AuthException authError) => AuthBlocState(
mode: AuthorizeMode.noLogin,
status: AuthStatus.failure,
authError: authError,
authenticationState: AuthenticationState.error(authError.toString()),
);
factory AuthBlocState.loggedIn(KdfUser user) => AuthBlocState(
mode: AuthorizeMode.logIn,
status: AuthStatus.success,
authenticationState: AuthenticationState.completed(user),
currentUser: user,
);
factory AuthBlocState.trezorInitializing({String? message, int? taskId}) =>
AuthBlocState(
mode: AuthorizeMode.noLogin,
authenticationState: AuthenticationState(
status: AuthenticationStatus.initializing,
taskId: taskId,
message: message,
),
);
factory AuthBlocState.trezorAwaitingConfirmation(
{String? message, int? taskId}) =>
AuthBlocState(
mode: AuthorizeMode.noLogin,
authenticationState: AuthenticationState(
status: AuthenticationStatus.waitingForDeviceConfirmation,
taskId: taskId,
message: message,
),
);
factory AuthBlocState.trezorPinRequired(
{String? message, required int taskId}) =>
AuthBlocState(
mode: AuthorizeMode.noLogin,
authenticationState: AuthenticationState(
status: AuthenticationStatus.pinRequired,
taskId: taskId,
message: message,
),
);
factory AuthBlocState.trezorPassphraseRequired(
{String? message, required int taskId}) =>
AuthBlocState(
mode: AuthorizeMode.noLogin,
authenticationState: AuthenticationState(
status: AuthenticationStatus.passphraseRequired,
taskId: taskId,
message: message,
),
);
factory AuthBlocState.trezorReady() => const AuthBlocState(
mode: AuthorizeMode.noLogin,
authenticationState:
AuthenticationState(status: AuthenticationStatus.cancelled),
);

final KdfUser? currentUser;
final AuthorizeMode mode;
final AuthStatus status;
final AuthenticationState? authenticationState;
final AuthException? authError;

AuthenticationStatus? get status => authenticationState?.status;

bool get isSignedIn => currentUser != null;
bool get isLoading => status == AuthStatus.loading;
bool get isError => status == AuthStatus.failure;
bool get isLoading =>
status == AuthenticationStatus.authenticating ||
status == AuthenticationStatus.initializing;
bool get isError => status == AuthenticationStatus.error;

@override
List<Object?> get props => [mode, currentUser, status, authError];
List<Object?> get props =>
[mode, currentUser, status, authError, authenticationState];
}
Loading
Loading