sca treezor login fixes
This commit is contained in:
@@ -2,7 +2,17 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>fr.antelop.alertLoggingEnabled</key>
|
||||
<string>The Antelop SDK is logging.</string>
|
||||
<key>fr.antelop.applicationGroupIdentifier</key>
|
||||
<string>group.com.savefamily.app</string>
|
||||
<key>fr.antelop.initialConnectionTimeout</key>
|
||||
<integer>60</integer>
|
||||
<key>fr.antelop.application_id</key>
|
||||
<integer>4713640103500149457</integer>
|
||||
<key>fr.antelop.issuer_id</key>
|
||||
<string>treezor</string>
|
||||
<key>fr.antelop.teamIdentifier</key>
|
||||
<string>YC6P64GJ93</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
@@ -18,6 +19,9 @@ import 'package:fonts/fonts.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.portraitUp,
|
||||
]);
|
||||
navigationModule();
|
||||
scaTreezorModule();
|
||||
configureAppRouter();
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
abstract class SessionLocalDatasource {
|
||||
Future<void> savePaymentProfileId(String id);
|
||||
Future<String?> getPaymentProfileId();
|
||||
|
||||
Future<bool> isProvisioned();
|
||||
Future<void> setProvisioned(bool value);
|
||||
|
||||
Future<bool> isFirstConnectionDone();
|
||||
Future<void> setFirstConnectionDone(bool value);
|
||||
|
||||
Future<void> clearSession();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import 'session_local_datasource.dart';
|
||||
|
||||
class SessionLocalDatasourceImpl implements SessionLocalDatasource {
|
||||
static const _paymentProfileIdKey = 'session_payment_profile_id';
|
||||
static const _isProvisionedKey = 'treezor.isProvisioned';
|
||||
static const _isFirstConnectionDoneKey = 'treezor.isFirstConnectionDone';
|
||||
|
||||
@override
|
||||
Future<void> savePaymentProfileId(String id) async {
|
||||
@@ -17,9 +19,35 @@ class SessionLocalDatasourceImpl implements SessionLocalDatasource {
|
||||
return prefs.getString(_paymentProfileIdKey);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> isProvisioned() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getBool(_isProvisionedKey) ?? false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setProvisioned(bool value) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setBool(_isProvisionedKey, value);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> isFirstConnectionDone() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getBool(_isFirstConnectionDoneKey) ?? false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setFirstConnectionDone(bool value) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setBool(_isFirstConnectionDoneKey, value);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> clearSession() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove(_paymentProfileIdKey);
|
||||
await prefs.remove(_isProvisionedKey);
|
||||
await prefs.remove(_isFirstConnectionDoneKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,14 +182,15 @@ class _ScaPinScreen extends ConsumerWidget {
|
||||
body: SafeArea(
|
||||
child: Center(
|
||||
child: ScaPinView(
|
||||
title: 'Introduce tu PIN para firmar',
|
||||
title: context.translate(I18n.scaPinEnter),
|
||||
pin: state.pin,
|
||||
isProcessing: state.isSigning || state.isLoading,
|
||||
processingText: state.isSigning
|
||||
? 'Firmando...'
|
||||
: 'Creando perfil...',
|
||||
? context.translate(I18n.scaSigning)
|
||||
: context.translate(I18n.deviceSetupCreatingProfile),
|
||||
canSubmit: vm.canSubmitPin && !state.isSigning && !state.isLoading,
|
||||
submitText: 'Confirmar',
|
||||
submitText: context.translate(I18n.deviceSetupConfirm),
|
||||
clearPinText: context.translate(I18n.scaClearPin),
|
||||
onDigitPressed: vm.onDigitPressed,
|
||||
onBackspacePressed: vm.onBackspacePressed,
|
||||
onClearPin: vm.clearPin,
|
||||
|
||||
@@ -169,7 +169,9 @@ class DeviceSetupViewModel extends Notifier<DeviceSetupViewState> {
|
||||
await getUserInfo();
|
||||
final firstName = state.firstName.trim();
|
||||
final lastName = state.lastName.trim();
|
||||
final bornAt = state.bornAt!.millisecondsSinceEpoch;
|
||||
final birth = state.bornAt!;
|
||||
final bornAt = DateTime.utc(birth.year, birth.month, birth.day)
|
||||
.millisecondsSinceEpoch;
|
||||
final address = state.address.trim();
|
||||
final genrer = state.genrer.trim();
|
||||
final relationType = state.relationType.trim();
|
||||
|
||||
@@ -13,6 +13,7 @@ class ScaPinView extends StatelessWidget {
|
||||
final VoidCallback onBackspacePressed;
|
||||
final VoidCallback onClearPin;
|
||||
final VoidCallback onSubmit;
|
||||
final String clearPinText;
|
||||
final String? errorMessage;
|
||||
|
||||
const ScaPinView({
|
||||
@@ -20,13 +21,14 @@ class ScaPinView extends StatelessWidget {
|
||||
required this.title,
|
||||
required this.pin,
|
||||
required this.isProcessing,
|
||||
this.processingText = 'Procesando...',
|
||||
required this.processingText,
|
||||
required this.canSubmit,
|
||||
this.submitText = 'Confirmar',
|
||||
required this.submitText,
|
||||
required this.onDigitPressed,
|
||||
required this.onBackspacePressed,
|
||||
required this.onClearPin,
|
||||
required this.onSubmit,
|
||||
required this.clearPinText,
|
||||
this.errorMessage,
|
||||
});
|
||||
|
||||
@@ -107,7 +109,7 @@ class ScaPinView extends StatelessWidget {
|
||||
const SizedBox(height: 10),
|
||||
TextButton(
|
||||
onPressed: pin.isEmpty ? null : onClearPin,
|
||||
child: const Text('Borrar PIN'),
|
||||
child: Text(clearPinText),
|
||||
),
|
||||
if (errorMessage != null && errorMessage!.isNotEmpty) ...[
|
||||
const SizedBox(height: 8),
|
||||
|
||||
@@ -40,35 +40,55 @@ class SCATreezorScreen extends ConsumerWidget {
|
||||
child: state.isLoading
|
||||
? const CircularProgressIndicator()
|
||||
: state.isProvisioned
|
||||
? ScaPinView(
|
||||
title: state.isFirstConnectionDone
|
||||
? context.translate(I18n.scaPinEnter)
|
||||
: state.isConfirmingPin
|
||||
? context.translate(I18n.scaPinConfirm)
|
||||
: context.translate(I18n.scaPinCreate),
|
||||
pin: state.pin,
|
||||
isProcessing: state.isConnecting || state.isSigning,
|
||||
processingText: state.isConnecting
|
||||
? 'Conectando...'
|
||||
: 'Firmando...',
|
||||
canSubmit: vm.canSubmitPin && !state.isConnecting,
|
||||
submitText: 'Conectar',
|
||||
onDigitPressed: vm.onDigitPressed,
|
||||
onBackspacePressed: vm.onBackspacePressed,
|
||||
onClearPin: vm.clearPin,
|
||||
onSubmit: () async {
|
||||
final success = await vm.connectAndSignJwtSca();
|
||||
if (!context.mounted) return;
|
||||
if (success) {
|
||||
final hasChildren = await vm.hasChildren();
|
||||
if (!context.mounted) return;
|
||||
if (hasChildren) {
|
||||
navigationContract.goTo(AppRoutes.dashboardHome);
|
||||
} else {
|
||||
navigationContract.goTo(AppRoutes.deviceSetup);
|
||||
}
|
||||
}
|
||||
},
|
||||
? Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ScaPinView(
|
||||
title: state.isFirstConnectionDone
|
||||
? context.translate(I18n.scaPinEnter)
|
||||
: state.isConfirmingPin
|
||||
? context.translate(I18n.scaPinConfirm)
|
||||
: context.translate(I18n.scaPinCreate),
|
||||
pin: state.pin,
|
||||
isProcessing: state.isConnecting || state.isSigning,
|
||||
processingText: state.isConnecting
|
||||
? context.translate(I18n.scaConnecting)
|
||||
: context.translate(I18n.scaSigning),
|
||||
canSubmit: vm.canSubmitPin && !state.isProcessing,
|
||||
submitText: context.translate(I18n.scaConnect),
|
||||
clearPinText: context.translate(I18n.scaClearPin),
|
||||
onDigitPressed: vm.onDigitPressed,
|
||||
onBackspacePressed: vm.onBackspacePressed,
|
||||
onClearPin: vm.clearPin,
|
||||
onSubmit: () async {
|
||||
final success = await vm.connectAndSignJwtSca();
|
||||
if (!context.mounted) return;
|
||||
if (success) {
|
||||
final hasChildren = await vm.hasChildren();
|
||||
if (!context.mounted) return;
|
||||
if (hasChildren) {
|
||||
navigationContract.goTo(AppRoutes.dashboardHome);
|
||||
} else {
|
||||
navigationContract.goTo(AppRoutes.deviceSetup);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
if (state.showRetryProvisioning) ...[
|
||||
const SizedBox(height: 12),
|
||||
TextButton(
|
||||
onPressed:
|
||||
state.isProcessing ? null : vm.retryProvisioning,
|
||||
child: Text(
|
||||
context.translate(I18n.scaProvisioningRetry),
|
||||
style: const TextStyle(
|
||||
color: Colors.orange,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
)
|
||||
: _ProvisioningBody(state: state, vm: vm),
|
||||
),
|
||||
@@ -88,13 +108,13 @@ class _ProvisioningBody extends ConsumerWidget {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
if (state.isProvisioning) {
|
||||
return const Column(
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(height: 16),
|
||||
CircularProgressIndicator(),
|
||||
SizedBox(height: 8),
|
||||
Text('Provisionando...'),
|
||||
const SizedBox(height: 16),
|
||||
const CircularProgressIndicator(),
|
||||
const SizedBox(height: 8),
|
||||
Text(context.translate(I18n.scaProvisioning)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import 'package:get_it/get_it.dart';
|
||||
import 'package:sca_treezor/sca_treezor.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:auth/src/core/data/datasource/session_local_datasource.dart';
|
||||
import 'package:auth/src/core/providers/session_local_datasource_provider.dart';
|
||||
|
||||
@@ -21,9 +20,6 @@ final scaTreezorViewModelProvider =
|
||||
);
|
||||
|
||||
class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
static const _kIsProvisionedKey = 'treezor.isProvisioned';
|
||||
static const _kIsFirstConnectionDoneKey = 'treezor.isFirstConnectionDone';
|
||||
|
||||
static const int _pinLength = 6;
|
||||
|
||||
late final ScaWalletsUseCase _scaWalletsUseCase;
|
||||
@@ -36,15 +32,12 @@ class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
late final GetUserInfoUseCase _getUserInfoUseCase;
|
||||
late final SessionLocalDatasource _sessionLocal;
|
||||
|
||||
late final TextEditingController codeController;
|
||||
|
||||
bool _started = false;
|
||||
bool _syncingController = false;
|
||||
|
||||
@override
|
||||
SCATreezorViewState build() {
|
||||
Future.microtask(_initAsync);
|
||||
return const SCATreezorViewState(isLoading: true);
|
||||
return const SCATreezorViewState();
|
||||
}
|
||||
|
||||
Future<void> _initAsync() async {
|
||||
@@ -57,10 +50,6 @@ class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
_getPaymentProfileUseCase = ref.read(getPaymentProfileUseCaseProvider);
|
||||
_getUserInfoUseCase = ref.read(getUserInfoUseCaseProvider);
|
||||
_sessionLocal = ref.read(sessionLocalDatasourceProvider);
|
||||
codeController = TextEditingController();
|
||||
codeController.addListener(_onCodeChanged);
|
||||
|
||||
ref.onDispose(_disposeControllers);
|
||||
|
||||
if (!_started) {
|
||||
_started = true;
|
||||
@@ -68,80 +57,110 @@ class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
}
|
||||
}
|
||||
|
||||
void _disposeControllers() {
|
||||
codeController.removeListener(_onCodeChanged);
|
||||
codeController.dispose();
|
||||
}
|
||||
|
||||
void _onCodeChanged() {
|
||||
if (_syncingController) return;
|
||||
|
||||
state = state.copyWith(
|
||||
activationCode: codeController.text,
|
||||
errorMessage: '',
|
||||
success: false,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _bootstrap() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final alreadyProvisioned = await _sessionLocal.isProvisioned();
|
||||
final firstConnectionDone = await _sessionLocal.isFirstConnectionDone();
|
||||
|
||||
final alreadyProvisioned = prefs.getBool(_kIsProvisionedKey) ?? false;
|
||||
final firstConnectionDone =
|
||||
prefs.getBool(_kIsFirstConnectionDoneKey) ?? false;
|
||||
if (!ref.mounted) return;
|
||||
|
||||
if (alreadyProvisioned) {
|
||||
final needsReprovisioning = await _checkBackendWalletStatus();
|
||||
if (!ref.mounted) return;
|
||||
|
||||
if (needsReprovisioning) {
|
||||
await _loadActivationCode();
|
||||
if (!ref.mounted) return;
|
||||
|
||||
final code = state.activationCode.trim();
|
||||
if (code.isEmpty) {
|
||||
state = state.copyWith(process: ScaProcess.idle);
|
||||
return;
|
||||
}
|
||||
|
||||
await _provisionWallet();
|
||||
return;
|
||||
}
|
||||
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
process: ScaProcess.idle,
|
||||
isProvisioned: true,
|
||||
isFirstConnectionDone: firstConnectionDone,
|
||||
errorMessage: '',
|
||||
success: true,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await _loadActivationCode();
|
||||
if (!ref.mounted) return;
|
||||
|
||||
final code = state.activationCode.trim();
|
||||
if (code.isEmpty) {
|
||||
state = state.copyWith(isLoading: false, provisioningFailed: true);
|
||||
state = state.copyWith(process: ScaProcess.idle);
|
||||
return;
|
||||
}
|
||||
|
||||
await provisionWallet();
|
||||
await _provisionWallet();
|
||||
}
|
||||
|
||||
Future<bool> _checkBackendWalletStatus() async {
|
||||
try {
|
||||
final treezorRepo = ref.read(treezorRepositoryProvider);
|
||||
final wallets = await treezorRepo.getScaWallets();
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
final hasActiveWallet = wallets.any((w) => w.status == 'ACTIVE');
|
||||
if (hasActiveWallet) return false;
|
||||
|
||||
// No active wallet — delete non-deleted ones and re-provision
|
||||
for (final wallet in wallets) {
|
||||
if (wallet.status == 'DELETED') continue;
|
||||
try {
|
||||
await treezorRepo.deleteScaWallet(scaWalletId: wallet.id);
|
||||
} catch (_) {}
|
||||
}
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
await clearLocalFlags();
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
await treezorRepo.resetScaWallets();
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
return true;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadActivationCode() async {
|
||||
state = state.copyWith(errorMessage: '', isLoading: true, success: false);
|
||||
state = state.copyWith(errorMessage: '', process: ScaProcess.loading);
|
||||
|
||||
try {
|
||||
final ScaWalletsResponseEntity response = await _scaWalletsUseCase
|
||||
.scaWallets();
|
||||
if (!ref.mounted) return;
|
||||
|
||||
final rawCode = response.item.activationCode;
|
||||
final sanitized = _sanitizeActivationCode(rawCode);
|
||||
|
||||
_syncingController = true;
|
||||
codeController.text = sanitized;
|
||||
_syncingController = false;
|
||||
|
||||
state = state.copyWith(
|
||||
activationCode: sanitized,
|
||||
errorMessage: '',
|
||||
isCreated: response.isCreated,
|
||||
isLoading: false,
|
||||
process: ScaProcess.idle,
|
||||
walletId: response.item.id,
|
||||
walletStatus: response.item.status,
|
||||
);
|
||||
} catch (e) {
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(
|
||||
errorMessage: '❌ Error obteniendo activationCode: $e',
|
||||
isLoading: false,
|
||||
errorMessage: I18n.scaErrorLoadingActivationCode,
|
||||
process: ScaProcess.idle,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> provisionWallet() async {
|
||||
Future<void> _provisionWallet() async {
|
||||
if (state.isProvisioning) return;
|
||||
|
||||
final activationCode = state.activationCode.trim();
|
||||
@@ -150,46 +169,35 @@ class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
return;
|
||||
}
|
||||
|
||||
state = state.copyWith(
|
||||
errorMessage: '',
|
||||
isProvisioning: true,
|
||||
success: false,
|
||||
);
|
||||
state = state.copyWith(errorMessage: '', process: ScaProcess.provisioning);
|
||||
|
||||
try {
|
||||
await _provisioningService.provisionWallet(
|
||||
activationCode: activationCode,
|
||||
);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setBool(_kIsProvisionedKey, true);
|
||||
|
||||
await prefs.setBool(_kIsFirstConnectionDoneKey, false);
|
||||
await _sessionLocal.setProvisioned(true);
|
||||
await _sessionLocal.setFirstConnectionDone(false);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
state = state.copyWith(
|
||||
isProvisioning: false,
|
||||
process: ScaProcess.idle,
|
||||
isProvisioned: true,
|
||||
isFirstConnectionDone: false,
|
||||
success: true,
|
||||
isLoading: false,
|
||||
errorMessage: '',
|
||||
);
|
||||
} catch (e) {
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(
|
||||
isProvisioning: false,
|
||||
provisioningFailed: true,
|
||||
success: false,
|
||||
errorMessage: e.toString(),
|
||||
process: ScaProcess.idle,
|
||||
errorMessage: I18n.scaErrorProvisioning,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> retryProvisioning() async {
|
||||
state = state.copyWith(
|
||||
isLoading: true,
|
||||
provisioningFailed: false,
|
||||
errorMessage: '',
|
||||
);
|
||||
state = state.copyWith(process: ScaProcess.loading, errorMessage: '');
|
||||
|
||||
try {
|
||||
final treezorRepo = ref.read(treezorRepositoryProvider);
|
||||
@@ -206,6 +214,8 @@ class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
if (!ref.mounted) return;
|
||||
|
||||
await clearLocalFlags();
|
||||
if (!ref.mounted) return;
|
||||
|
||||
await treezorRepo.resetScaWallets();
|
||||
if (!ref.mounted) return;
|
||||
|
||||
@@ -213,147 +223,44 @@ class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
} catch (e) {
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
provisioningFailed: true,
|
||||
errorMessage: e.toString(),
|
||||
process: ScaProcess.idle,
|
||||
errorMessage: I18n.scaErrorProvisioning,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ──────────────────── PIN input ────────────────────
|
||||
|
||||
void onDigitPressed(String digit) {
|
||||
if (state.isConnecting) return;
|
||||
if (state.isProcessing) return;
|
||||
if (state.pin.length >= _pinLength) return;
|
||||
|
||||
state = state.copyWith(
|
||||
pin: '${state.pin}$digit',
|
||||
errorMessage: '',
|
||||
success: false,
|
||||
);
|
||||
state = state.copyWith(pin: '${state.pin}$digit', errorMessage: '');
|
||||
}
|
||||
|
||||
void onBackspacePressed() {
|
||||
if (state.isConnecting) return;
|
||||
if (state.isProcessing) return;
|
||||
if (state.pin.isEmpty) return;
|
||||
|
||||
state = state.copyWith(
|
||||
pin: state.pin.substring(0, state.pin.length - 1),
|
||||
errorMessage: '',
|
||||
success: false,
|
||||
);
|
||||
}
|
||||
|
||||
void clearPin() {
|
||||
if (state.isConnecting) return;
|
||||
state = state.copyWith(pin: '', errorMessage: '', success: false);
|
||||
if (state.isProcessing) return;
|
||||
state = state.copyWith(pin: '', errorMessage: '');
|
||||
}
|
||||
|
||||
bool get canSubmitPin => state.pin.length == _pinLength;
|
||||
|
||||
Future<bool> connectWithPin() async {
|
||||
if (state.isConnecting) return false;
|
||||
|
||||
if (!state.isProvisioned) {
|
||||
state = state.copyWith(errorMessage: I18n.errorWalletNotProvisioned);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!canSubmitPin) {
|
||||
state = state.copyWith(errorMessage: I18n.errorPinRequired);
|
||||
return false;
|
||||
}
|
||||
|
||||
state = state.copyWith(
|
||||
isConnecting: true,
|
||||
errorMessage: '',
|
||||
success: false,
|
||||
);
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final firstConnectionDone =
|
||||
prefs.getBool(_kIsFirstConnectionDoneKey) ?? false;
|
||||
|
||||
try {
|
||||
if (!firstConnectionDone) {
|
||||
await _connectionService.connectFirstTime(newPin: state.pin);
|
||||
await prefs.setBool(_kIsFirstConnectionDoneKey, true);
|
||||
|
||||
state = state.copyWith(isFirstConnectionDone: true);
|
||||
} else {
|
||||
await _connectionService.connectWithPin(loginPin: state.pin);
|
||||
}
|
||||
state = state.copyWith(
|
||||
isConnecting: false,
|
||||
isConnected: true,
|
||||
success: true,
|
||||
errorMessage: '',
|
||||
);
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
state = state.copyWith(
|
||||
isConnecting: false,
|
||||
isConnected: false,
|
||||
success: false,
|
||||
errorMessage: '❌ Error conectando wallet: $e',
|
||||
pin: '',
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> retry() async {
|
||||
state = const SCATreezorViewState(isLoading: true);
|
||||
await _bootstrap();
|
||||
}
|
||||
|
||||
Future<void> signJwtSca() async {
|
||||
if (state.isSigning) return;
|
||||
|
||||
if (state.isConnected == false) {
|
||||
state = state.copyWith(errorMessage: I18n.errorWalletConnectFirst);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canSubmitPin) {
|
||||
state = state.copyWith(errorMessage: I18n.errorPinRequired);
|
||||
return;
|
||||
}
|
||||
|
||||
state = state.copyWith(
|
||||
errorMessage: '',
|
||||
isSigning: true,
|
||||
success: false,
|
||||
lastSignature: '',
|
||||
);
|
||||
|
||||
try {
|
||||
final signature = await _signatureService.generateJwsWithPin(
|
||||
message: 'JWT sesion',
|
||||
input: '',
|
||||
pin: state.pin,
|
||||
);
|
||||
await _sendJWSSesionUseCase.sendJWSSesion(jws: signature);
|
||||
|
||||
state = state.copyWith(
|
||||
isSigning: false,
|
||||
success: true,
|
||||
lastSignature: signature,
|
||||
errorMessage: '',
|
||||
pin: '',
|
||||
);
|
||||
} catch (e) {
|
||||
state = state.copyWith(
|
||||
isSigning: false,
|
||||
success: false,
|
||||
errorMessage: '❌ Error firmando JWT SCA: $e',
|
||||
pin: '',
|
||||
);
|
||||
}
|
||||
}
|
||||
// ──────────────────── Connect + Sign ────────────────────
|
||||
|
||||
Future<bool> connectAndSignJwtSca() async {
|
||||
if (state.isConnecting || state.isSigning) return false;
|
||||
if (state.isProcessing) return false;
|
||||
|
||||
// PIN confirmation on first-time creation
|
||||
if (!state.isFirstConnectionDone && !state.isConfirmingPin) {
|
||||
state = state.copyWith(
|
||||
firstPin: state.pin,
|
||||
@@ -376,28 +283,137 @@ class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
}
|
||||
}
|
||||
|
||||
final connected = await connectWithPin();
|
||||
final connected = await _connectWithPin();
|
||||
if (!connected) return false;
|
||||
|
||||
await signJwtSca();
|
||||
final user = await _getUserInfoUseCase.getUserInfo();
|
||||
final paymentProfile = await _getPaymentProfileUseCase.getPaymentProfile(
|
||||
userId: user.id,
|
||||
);
|
||||
debugPrint(
|
||||
'[connectWithPin] paymentWalletId => ${paymentProfile.paymentWalletId}',
|
||||
);
|
||||
await _signJwtSca();
|
||||
if (!ref.mounted) return false;
|
||||
if (state.lastSignature.isEmpty) return false;
|
||||
|
||||
if (paymentProfile.paymentWalletId == null ||
|
||||
paymentProfile.paymentWalletId!.isEmpty) {
|
||||
await _authRepository.createWallet();
|
||||
await _sessionLocal.savePaymentProfileId(paymentProfile.paymentWalletId!);
|
||||
// Payment profile
|
||||
try {
|
||||
final user = await _getUserInfoUseCase.getUserInfo();
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
final paymentProfile = await _getPaymentProfileUseCase.getPaymentProfile(
|
||||
userId: user.id,
|
||||
);
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
debugPrint(
|
||||
'[connectAndSignJwtSca] paymentWalletId => ${paymentProfile.paymentWalletId}',
|
||||
);
|
||||
|
||||
if (paymentProfile.paymentWalletId == null ||
|
||||
paymentProfile.paymentWalletId!.isEmpty) {
|
||||
await _authRepository.createWallet();
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
final updated = await _getPaymentProfileUseCase.getPaymentProfile(
|
||||
userId: user.id,
|
||||
);
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
if (updated.paymentWalletId != null &&
|
||||
updated.paymentWalletId!.isNotEmpty) {
|
||||
await _sessionLocal.savePaymentProfileId(updated.paymentWalletId!);
|
||||
}
|
||||
} else {
|
||||
await _sessionLocal.savePaymentProfileId(
|
||||
paymentProfile.paymentWalletId!,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
if (!ref.mounted) return false;
|
||||
state = state.copyWith(errorMessage: I18n.scaErrorPaymentProfile);
|
||||
return false;
|
||||
}
|
||||
await _sessionLocal.savePaymentProfileId(paymentProfile.paymentWalletId!);
|
||||
|
||||
return state.lastSignature.isNotEmpty;
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<bool> _connectWithPin() async {
|
||||
if (!state.isProvisioned) {
|
||||
state = state.copyWith(errorMessage: I18n.errorWalletNotProvisioned);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!canSubmitPin) {
|
||||
state = state.copyWith(errorMessage: I18n.errorPinRequired);
|
||||
return false;
|
||||
}
|
||||
|
||||
state = state.copyWith(process: ScaProcess.connecting, errorMessage: '');
|
||||
|
||||
try {
|
||||
final firstConnectionDone = await _sessionLocal.isFirstConnectionDone();
|
||||
|
||||
if (!firstConnectionDone) {
|
||||
await _connectionService.connectFirstTime(newPin: state.pin);
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
await _sessionLocal.setFirstConnectionDone(true);
|
||||
state = state.copyWith(isFirstConnectionDone: true);
|
||||
} else {
|
||||
await _connectionService.connectWithPin(loginPin: state.pin);
|
||||
}
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
state = state.copyWith(
|
||||
process: ScaProcess.idle,
|
||||
isConnected: true,
|
||||
errorMessage: '',
|
||||
);
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (!ref.mounted) return false;
|
||||
state = state.copyWith(
|
||||
process: ScaProcess.idle,
|
||||
isConnected: false,
|
||||
errorMessage: I18n.scaErrorConnecting,
|
||||
showRetryProvisioning: true,
|
||||
pin: '',
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _signJwtSca() async {
|
||||
state = state.copyWith(
|
||||
errorMessage: '',
|
||||
process: ScaProcess.signing,
|
||||
lastSignature: '',
|
||||
);
|
||||
|
||||
try {
|
||||
final signature = await _signatureService.generateJwsWithPin(
|
||||
message: 'JWT sesion',
|
||||
input: '',
|
||||
pin: state.pin,
|
||||
);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
await _sendJWSSesionUseCase.sendJWSSesion(jws: signature);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
state = state.copyWith(
|
||||
process: ScaProcess.idle,
|
||||
lastSignature: signature,
|
||||
errorMessage: '',
|
||||
pin: '',
|
||||
);
|
||||
} catch (e) {
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(
|
||||
process: ScaProcess.idle,
|
||||
errorMessage: I18n.scaErrorSigning,
|
||||
pin: '',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ──────────────────── Helpers ────────────────────
|
||||
|
||||
Future<bool> hasChildren() async {
|
||||
try {
|
||||
final userRepository = ref.read(userRepositoryProvider);
|
||||
@@ -414,16 +430,15 @@ class SCATreezorViewModel extends Notifier<SCATreezorViewState> {
|
||||
}
|
||||
|
||||
Future<void> clearLocalFlags() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove(_kIsProvisionedKey);
|
||||
await prefs.remove(_kIsFirstConnectionDoneKey);
|
||||
await _sessionLocal.clearSession();
|
||||
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(
|
||||
isProvisioned: false,
|
||||
isFirstConnectionDone: false,
|
||||
isConnected: false,
|
||||
showRetryProvisioning: false,
|
||||
pin: '',
|
||||
success: false,
|
||||
errorMessage: '',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'sca_treezor_view_state.freezed.dart';
|
||||
|
||||
enum ScaProcess { idle, loading, provisioning, connecting, signing }
|
||||
|
||||
@freezed
|
||||
abstract class SCATreezorViewState with _$SCATreezorViewState {
|
||||
const SCATreezorViewState._();
|
||||
@@ -10,25 +12,27 @@ abstract class SCATreezorViewState with _$SCATreezorViewState {
|
||||
@Default('') String activationCode,
|
||||
@Default('') String errorMessage,
|
||||
@Default(false) bool isCreated,
|
||||
@Default(false) bool isLoading,
|
||||
@Default(ScaProcess.loading) ScaProcess process,
|
||||
|
||||
@Default(false) bool isProvisioning,
|
||||
@Default(false) bool isProvisioned,
|
||||
@Default(false) bool provisioningFailed,
|
||||
|
||||
@Default(false) bool isFirstConnectionDone,
|
||||
@Default(false) bool isConfirmingPin,
|
||||
@Default('') String firstPin,
|
||||
@Default(false) bool isConnecting,
|
||||
@Default(false) bool isConnected,
|
||||
@Default('') String pin,
|
||||
@Default(false) bool isSigning,
|
||||
@Default('') String lastSignature,
|
||||
|
||||
@Default(false) bool success,
|
||||
@Default('') String walletId,
|
||||
@Default('') String walletStatus,
|
||||
@Default(false) bool showRetryProvisioning,
|
||||
}) = _SCATreezorViewState;
|
||||
|
||||
bool get isIdle => process == ScaProcess.idle;
|
||||
bool get isLoading => process == ScaProcess.loading;
|
||||
bool get isProvisioning => process == ScaProcess.provisioning;
|
||||
bool get isConnecting => process == ScaProcess.connecting;
|
||||
bool get isSigning => process == ScaProcess.signing;
|
||||
bool get isProcessing => process != ScaProcess.idle;
|
||||
bool get hasError => errorMessage.isNotEmpty;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$SCATreezorViewState {
|
||||
|
||||
String get activationCode; String get errorMessage; bool get isCreated; bool get isLoading; bool get isProvisioning; bool get isProvisioned; bool get provisioningFailed; bool get isFirstConnectionDone; bool get isConfirmingPin; String get firstPin; bool get isConnecting; bool get isConnected; String get pin; bool get isSigning; String get lastSignature; bool get success; String get walletId; String get walletStatus;
|
||||
String get activationCode; String get errorMessage; bool get isCreated; ScaProcess get process; bool get isProvisioned; bool get isFirstConnectionDone; bool get isConfirmingPin; String get firstPin; bool get isConnected; String get pin; String get lastSignature; String get walletId; String get walletStatus; bool get showRetryProvisioning;
|
||||
/// Create a copy of SCATreezorViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -25,16 +25,16 @@ $SCATreezorViewStateCopyWith<SCATreezorViewState> get copyWith => _$SCATreezorVi
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SCATreezorViewState&&(identical(other.activationCode, activationCode) || other.activationCode == activationCode)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isProvisioning, isProvisioning) || other.isProvisioning == isProvisioning)&&(identical(other.isProvisioned, isProvisioned) || other.isProvisioned == isProvisioned)&&(identical(other.provisioningFailed, provisioningFailed) || other.provisioningFailed == provisioningFailed)&&(identical(other.isFirstConnectionDone, isFirstConnectionDone) || other.isFirstConnectionDone == isFirstConnectionDone)&&(identical(other.isConfirmingPin, isConfirmingPin) || other.isConfirmingPin == isConfirmingPin)&&(identical(other.firstPin, firstPin) || other.firstPin == firstPin)&&(identical(other.isConnecting, isConnecting) || other.isConnecting == isConnecting)&&(identical(other.isConnected, isConnected) || other.isConnected == isConnected)&&(identical(other.pin, pin) || other.pin == pin)&&(identical(other.isSigning, isSigning) || other.isSigning == isSigning)&&(identical(other.lastSignature, lastSignature) || other.lastSignature == lastSignature)&&(identical(other.success, success) || other.success == success)&&(identical(other.walletId, walletId) || other.walletId == walletId)&&(identical(other.walletStatus, walletStatus) || other.walletStatus == walletStatus));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SCATreezorViewState&&(identical(other.activationCode, activationCode) || other.activationCode == activationCode)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.process, process) || other.process == process)&&(identical(other.isProvisioned, isProvisioned) || other.isProvisioned == isProvisioned)&&(identical(other.isFirstConnectionDone, isFirstConnectionDone) || other.isFirstConnectionDone == isFirstConnectionDone)&&(identical(other.isConfirmingPin, isConfirmingPin) || other.isConfirmingPin == isConfirmingPin)&&(identical(other.firstPin, firstPin) || other.firstPin == firstPin)&&(identical(other.isConnected, isConnected) || other.isConnected == isConnected)&&(identical(other.pin, pin) || other.pin == pin)&&(identical(other.lastSignature, lastSignature) || other.lastSignature == lastSignature)&&(identical(other.walletId, walletId) || other.walletId == walletId)&&(identical(other.walletStatus, walletStatus) || other.walletStatus == walletStatus)&&(identical(other.showRetryProvisioning, showRetryProvisioning) || other.showRetryProvisioning == showRetryProvisioning));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,activationCode,errorMessage,isCreated,isLoading,isProvisioning,isProvisioned,provisioningFailed,isFirstConnectionDone,isConfirmingPin,firstPin,isConnecting,isConnected,pin,isSigning,lastSignature,success,walletId,walletStatus);
|
||||
int get hashCode => Object.hash(runtimeType,activationCode,errorMessage,isCreated,process,isProvisioned,isFirstConnectionDone,isConfirmingPin,firstPin,isConnected,pin,lastSignature,walletId,walletStatus,showRetryProvisioning);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SCATreezorViewState(activationCode: $activationCode, errorMessage: $errorMessage, isCreated: $isCreated, isLoading: $isLoading, isProvisioning: $isProvisioning, isProvisioned: $isProvisioned, provisioningFailed: $provisioningFailed, isFirstConnectionDone: $isFirstConnectionDone, isConfirmingPin: $isConfirmingPin, firstPin: $firstPin, isConnecting: $isConnecting, isConnected: $isConnected, pin: $pin, isSigning: $isSigning, lastSignature: $lastSignature, success: $success, walletId: $walletId, walletStatus: $walletStatus)';
|
||||
return 'SCATreezorViewState(activationCode: $activationCode, errorMessage: $errorMessage, isCreated: $isCreated, process: $process, isProvisioned: $isProvisioned, isFirstConnectionDone: $isFirstConnectionDone, isConfirmingPin: $isConfirmingPin, firstPin: $firstPin, isConnected: $isConnected, pin: $pin, lastSignature: $lastSignature, walletId: $walletId, walletStatus: $walletStatus, showRetryProvisioning: $showRetryProvisioning)';
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ abstract mixin class $SCATreezorViewStateCopyWith<$Res> {
|
||||
factory $SCATreezorViewStateCopyWith(SCATreezorViewState value, $Res Function(SCATreezorViewState) _then) = _$SCATreezorViewStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String activationCode, String errorMessage, bool isCreated, bool isLoading, bool isProvisioning, bool isProvisioned, bool provisioningFailed, bool isFirstConnectionDone, bool isConfirmingPin, String firstPin, bool isConnecting, bool isConnected, String pin, bool isSigning, String lastSignature, bool success, String walletId, String walletStatus
|
||||
String activationCode, String errorMessage, bool isCreated, ScaProcess process, bool isProvisioned, bool isFirstConnectionDone, bool isConfirmingPin, String firstPin, bool isConnected, String pin, String lastSignature, String walletId, String walletStatus, bool showRetryProvisioning
|
||||
});
|
||||
|
||||
|
||||
@@ -62,27 +62,23 @@ class _$SCATreezorViewStateCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of SCATreezorViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? activationCode = null,Object? errorMessage = null,Object? isCreated = null,Object? isLoading = null,Object? isProvisioning = null,Object? isProvisioned = null,Object? provisioningFailed = null,Object? isFirstConnectionDone = null,Object? isConfirmingPin = null,Object? firstPin = null,Object? isConnecting = null,Object? isConnected = null,Object? pin = null,Object? isSigning = null,Object? lastSignature = null,Object? success = null,Object? walletId = null,Object? walletStatus = null,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? activationCode = null,Object? errorMessage = null,Object? isCreated = null,Object? process = null,Object? isProvisioned = null,Object? isFirstConnectionDone = null,Object? isConfirmingPin = null,Object? firstPin = null,Object? isConnected = null,Object? pin = null,Object? lastSignature = null,Object? walletId = null,Object? walletStatus = null,Object? showRetryProvisioning = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
activationCode: null == activationCode ? _self.activationCode : activationCode // ignore: cast_nullable_to_non_nullable
|
||||
as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String,isCreated: null == isCreated ? _self.isCreated : isCreated // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isProvisioning: null == isProvisioning ? _self.isProvisioning : isProvisioning // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isProvisioned: null == isProvisioned ? _self.isProvisioned : isProvisioned // ignore: cast_nullable_to_non_nullable
|
||||
as bool,provisioningFailed: null == provisioningFailed ? _self.provisioningFailed : provisioningFailed // ignore: cast_nullable_to_non_nullable
|
||||
as bool,process: null == process ? _self.process : process // ignore: cast_nullable_to_non_nullable
|
||||
as ScaProcess,isProvisioned: null == isProvisioned ? _self.isProvisioned : isProvisioned // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isFirstConnectionDone: null == isFirstConnectionDone ? _self.isFirstConnectionDone : isFirstConnectionDone // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isConfirmingPin: null == isConfirmingPin ? _self.isConfirmingPin : isConfirmingPin // ignore: cast_nullable_to_non_nullable
|
||||
as bool,firstPin: null == firstPin ? _self.firstPin : firstPin // ignore: cast_nullable_to_non_nullable
|
||||
as String,isConnecting: null == isConnecting ? _self.isConnecting : isConnecting // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isConnected: null == isConnected ? _self.isConnected : isConnected // ignore: cast_nullable_to_non_nullable
|
||||
as String,isConnected: null == isConnected ? _self.isConnected : isConnected // ignore: cast_nullable_to_non_nullable
|
||||
as bool,pin: null == pin ? _self.pin : pin // ignore: cast_nullable_to_non_nullable
|
||||
as String,isSigning: null == isSigning ? _self.isSigning : isSigning // ignore: cast_nullable_to_non_nullable
|
||||
as bool,lastSignature: null == lastSignature ? _self.lastSignature : lastSignature // ignore: cast_nullable_to_non_nullable
|
||||
as String,success: null == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
|
||||
as bool,walletId: null == walletId ? _self.walletId : walletId // ignore: cast_nullable_to_non_nullable
|
||||
as String,lastSignature: null == lastSignature ? _self.lastSignature : lastSignature // ignore: cast_nullable_to_non_nullable
|
||||
as String,walletId: null == walletId ? _self.walletId : walletId // ignore: cast_nullable_to_non_nullable
|
||||
as String,walletStatus: null == walletStatus ? _self.walletStatus : walletStatus // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as String,showRetryProvisioning: null == showRetryProvisioning ? _self.showRetryProvisioning : showRetryProvisioning // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -167,10 +163,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String activationCode, String errorMessage, bool isCreated, bool isLoading, bool isProvisioning, bool isProvisioned, bool provisioningFailed, bool isFirstConnectionDone, bool isConfirmingPin, String firstPin, bool isConnecting, bool isConnected, String pin, bool isSigning, String lastSignature, bool success, String walletId, String walletStatus)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String activationCode, String errorMessage, bool isCreated, ScaProcess process, bool isProvisioned, bool isFirstConnectionDone, bool isConfirmingPin, String firstPin, bool isConnected, String pin, String lastSignature, String walletId, String walletStatus, bool showRetryProvisioning)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SCATreezorViewState() when $default != null:
|
||||
return $default(_that.activationCode,_that.errorMessage,_that.isCreated,_that.isLoading,_that.isProvisioning,_that.isProvisioned,_that.provisioningFailed,_that.isFirstConnectionDone,_that.isConfirmingPin,_that.firstPin,_that.isConnecting,_that.isConnected,_that.pin,_that.isSigning,_that.lastSignature,_that.success,_that.walletId,_that.walletStatus);case _:
|
||||
return $default(_that.activationCode,_that.errorMessage,_that.isCreated,_that.process,_that.isProvisioned,_that.isFirstConnectionDone,_that.isConfirmingPin,_that.firstPin,_that.isConnected,_that.pin,_that.lastSignature,_that.walletId,_that.walletStatus,_that.showRetryProvisioning);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -188,10 +184,10 @@ return $default(_that.activationCode,_that.errorMessage,_that.isCreated,_that.is
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String activationCode, String errorMessage, bool isCreated, bool isLoading, bool isProvisioning, bool isProvisioned, bool provisioningFailed, bool isFirstConnectionDone, bool isConfirmingPin, String firstPin, bool isConnecting, bool isConnected, String pin, bool isSigning, String lastSignature, bool success, String walletId, String walletStatus) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String activationCode, String errorMessage, bool isCreated, ScaProcess process, bool isProvisioned, bool isFirstConnectionDone, bool isConfirmingPin, String firstPin, bool isConnected, String pin, String lastSignature, String walletId, String walletStatus, bool showRetryProvisioning) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SCATreezorViewState():
|
||||
return $default(_that.activationCode,_that.errorMessage,_that.isCreated,_that.isLoading,_that.isProvisioning,_that.isProvisioned,_that.provisioningFailed,_that.isFirstConnectionDone,_that.isConfirmingPin,_that.firstPin,_that.isConnecting,_that.isConnected,_that.pin,_that.isSigning,_that.lastSignature,_that.success,_that.walletId,_that.walletStatus);case _:
|
||||
return $default(_that.activationCode,_that.errorMessage,_that.isCreated,_that.process,_that.isProvisioned,_that.isFirstConnectionDone,_that.isConfirmingPin,_that.firstPin,_that.isConnected,_that.pin,_that.lastSignature,_that.walletId,_that.walletStatus,_that.showRetryProvisioning);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -208,10 +204,10 @@ return $default(_that.activationCode,_that.errorMessage,_that.isCreated,_that.is
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String activationCode, String errorMessage, bool isCreated, bool isLoading, bool isProvisioning, bool isProvisioned, bool provisioningFailed, bool isFirstConnectionDone, bool isConfirmingPin, String firstPin, bool isConnecting, bool isConnected, String pin, bool isSigning, String lastSignature, bool success, String walletId, String walletStatus)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String activationCode, String errorMessage, bool isCreated, ScaProcess process, bool isProvisioned, bool isFirstConnectionDone, bool isConfirmingPin, String firstPin, bool isConnected, String pin, String lastSignature, String walletId, String walletStatus, bool showRetryProvisioning)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _SCATreezorViewState() when $default != null:
|
||||
return $default(_that.activationCode,_that.errorMessage,_that.isCreated,_that.isLoading,_that.isProvisioning,_that.isProvisioned,_that.provisioningFailed,_that.isFirstConnectionDone,_that.isConfirmingPin,_that.firstPin,_that.isConnecting,_that.isConnected,_that.pin,_that.isSigning,_that.lastSignature,_that.success,_that.walletId,_that.walletStatus);case _:
|
||||
return $default(_that.activationCode,_that.errorMessage,_that.isCreated,_that.process,_that.isProvisioned,_that.isFirstConnectionDone,_that.isConfirmingPin,_that.firstPin,_that.isConnected,_that.pin,_that.lastSignature,_that.walletId,_that.walletStatus,_that.showRetryProvisioning);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -223,27 +219,23 @@ return $default(_that.activationCode,_that.errorMessage,_that.isCreated,_that.is
|
||||
|
||||
|
||||
class _SCATreezorViewState extends SCATreezorViewState {
|
||||
const _SCATreezorViewState({this.activationCode = '', this.errorMessage = '', this.isCreated = false, this.isLoading = false, this.isProvisioning = false, this.isProvisioned = false, this.provisioningFailed = false, this.isFirstConnectionDone = false, this.isConfirmingPin = false, this.firstPin = '', this.isConnecting = false, this.isConnected = false, this.pin = '', this.isSigning = false, this.lastSignature = '', this.success = false, this.walletId = '', this.walletStatus = ''}): super._();
|
||||
const _SCATreezorViewState({this.activationCode = '', this.errorMessage = '', this.isCreated = false, this.process = ScaProcess.loading, this.isProvisioned = false, this.isFirstConnectionDone = false, this.isConfirmingPin = false, this.firstPin = '', this.isConnected = false, this.pin = '', this.lastSignature = '', this.walletId = '', this.walletStatus = '', this.showRetryProvisioning = false}): super._();
|
||||
|
||||
|
||||
@override@JsonKey() final String activationCode;
|
||||
@override@JsonKey() final String errorMessage;
|
||||
@override@JsonKey() final bool isCreated;
|
||||
@override@JsonKey() final bool isLoading;
|
||||
@override@JsonKey() final bool isProvisioning;
|
||||
@override@JsonKey() final ScaProcess process;
|
||||
@override@JsonKey() final bool isProvisioned;
|
||||
@override@JsonKey() final bool provisioningFailed;
|
||||
@override@JsonKey() final bool isFirstConnectionDone;
|
||||
@override@JsonKey() final bool isConfirmingPin;
|
||||
@override@JsonKey() final String firstPin;
|
||||
@override@JsonKey() final bool isConnecting;
|
||||
@override@JsonKey() final bool isConnected;
|
||||
@override@JsonKey() final String pin;
|
||||
@override@JsonKey() final bool isSigning;
|
||||
@override@JsonKey() final String lastSignature;
|
||||
@override@JsonKey() final bool success;
|
||||
@override@JsonKey() final String walletId;
|
||||
@override@JsonKey() final String walletStatus;
|
||||
@override@JsonKey() final bool showRetryProvisioning;
|
||||
|
||||
/// Create a copy of SCATreezorViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -255,16 +247,16 @@ _$SCATreezorViewStateCopyWith<_SCATreezorViewState> get copyWith => __$SCATreezo
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SCATreezorViewState&&(identical(other.activationCode, activationCode) || other.activationCode == activationCode)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isProvisioning, isProvisioning) || other.isProvisioning == isProvisioning)&&(identical(other.isProvisioned, isProvisioned) || other.isProvisioned == isProvisioned)&&(identical(other.provisioningFailed, provisioningFailed) || other.provisioningFailed == provisioningFailed)&&(identical(other.isFirstConnectionDone, isFirstConnectionDone) || other.isFirstConnectionDone == isFirstConnectionDone)&&(identical(other.isConfirmingPin, isConfirmingPin) || other.isConfirmingPin == isConfirmingPin)&&(identical(other.firstPin, firstPin) || other.firstPin == firstPin)&&(identical(other.isConnecting, isConnecting) || other.isConnecting == isConnecting)&&(identical(other.isConnected, isConnected) || other.isConnected == isConnected)&&(identical(other.pin, pin) || other.pin == pin)&&(identical(other.isSigning, isSigning) || other.isSigning == isSigning)&&(identical(other.lastSignature, lastSignature) || other.lastSignature == lastSignature)&&(identical(other.success, success) || other.success == success)&&(identical(other.walletId, walletId) || other.walletId == walletId)&&(identical(other.walletStatus, walletStatus) || other.walletStatus == walletStatus));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SCATreezorViewState&&(identical(other.activationCode, activationCode) || other.activationCode == activationCode)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.isCreated, isCreated) || other.isCreated == isCreated)&&(identical(other.process, process) || other.process == process)&&(identical(other.isProvisioned, isProvisioned) || other.isProvisioned == isProvisioned)&&(identical(other.isFirstConnectionDone, isFirstConnectionDone) || other.isFirstConnectionDone == isFirstConnectionDone)&&(identical(other.isConfirmingPin, isConfirmingPin) || other.isConfirmingPin == isConfirmingPin)&&(identical(other.firstPin, firstPin) || other.firstPin == firstPin)&&(identical(other.isConnected, isConnected) || other.isConnected == isConnected)&&(identical(other.pin, pin) || other.pin == pin)&&(identical(other.lastSignature, lastSignature) || other.lastSignature == lastSignature)&&(identical(other.walletId, walletId) || other.walletId == walletId)&&(identical(other.walletStatus, walletStatus) || other.walletStatus == walletStatus)&&(identical(other.showRetryProvisioning, showRetryProvisioning) || other.showRetryProvisioning == showRetryProvisioning));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,activationCode,errorMessage,isCreated,isLoading,isProvisioning,isProvisioned,provisioningFailed,isFirstConnectionDone,isConfirmingPin,firstPin,isConnecting,isConnected,pin,isSigning,lastSignature,success,walletId,walletStatus);
|
||||
int get hashCode => Object.hash(runtimeType,activationCode,errorMessage,isCreated,process,isProvisioned,isFirstConnectionDone,isConfirmingPin,firstPin,isConnected,pin,lastSignature,walletId,walletStatus,showRetryProvisioning);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SCATreezorViewState(activationCode: $activationCode, errorMessage: $errorMessage, isCreated: $isCreated, isLoading: $isLoading, isProvisioning: $isProvisioning, isProvisioned: $isProvisioned, provisioningFailed: $provisioningFailed, isFirstConnectionDone: $isFirstConnectionDone, isConfirmingPin: $isConfirmingPin, firstPin: $firstPin, isConnecting: $isConnecting, isConnected: $isConnected, pin: $pin, isSigning: $isSigning, lastSignature: $lastSignature, success: $success, walletId: $walletId, walletStatus: $walletStatus)';
|
||||
return 'SCATreezorViewState(activationCode: $activationCode, errorMessage: $errorMessage, isCreated: $isCreated, process: $process, isProvisioned: $isProvisioned, isFirstConnectionDone: $isFirstConnectionDone, isConfirmingPin: $isConfirmingPin, firstPin: $firstPin, isConnected: $isConnected, pin: $pin, lastSignature: $lastSignature, walletId: $walletId, walletStatus: $walletStatus, showRetryProvisioning: $showRetryProvisioning)';
|
||||
}
|
||||
|
||||
|
||||
@@ -275,7 +267,7 @@ abstract mixin class _$SCATreezorViewStateCopyWith<$Res> implements $SCATreezorV
|
||||
factory _$SCATreezorViewStateCopyWith(_SCATreezorViewState value, $Res Function(_SCATreezorViewState) _then) = __$SCATreezorViewStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String activationCode, String errorMessage, bool isCreated, bool isLoading, bool isProvisioning, bool isProvisioned, bool provisioningFailed, bool isFirstConnectionDone, bool isConfirmingPin, String firstPin, bool isConnecting, bool isConnected, String pin, bool isSigning, String lastSignature, bool success, String walletId, String walletStatus
|
||||
String activationCode, String errorMessage, bool isCreated, ScaProcess process, bool isProvisioned, bool isFirstConnectionDone, bool isConfirmingPin, String firstPin, bool isConnected, String pin, String lastSignature, String walletId, String walletStatus, bool showRetryProvisioning
|
||||
});
|
||||
|
||||
|
||||
@@ -292,27 +284,23 @@ class __$SCATreezorViewStateCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of SCATreezorViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? activationCode = null,Object? errorMessage = null,Object? isCreated = null,Object? isLoading = null,Object? isProvisioning = null,Object? isProvisioned = null,Object? provisioningFailed = null,Object? isFirstConnectionDone = null,Object? isConfirmingPin = null,Object? firstPin = null,Object? isConnecting = null,Object? isConnected = null,Object? pin = null,Object? isSigning = null,Object? lastSignature = null,Object? success = null,Object? walletId = null,Object? walletStatus = null,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? activationCode = null,Object? errorMessage = null,Object? isCreated = null,Object? process = null,Object? isProvisioned = null,Object? isFirstConnectionDone = null,Object? isConfirmingPin = null,Object? firstPin = null,Object? isConnected = null,Object? pin = null,Object? lastSignature = null,Object? walletId = null,Object? walletStatus = null,Object? showRetryProvisioning = null,}) {
|
||||
return _then(_SCATreezorViewState(
|
||||
activationCode: null == activationCode ? _self.activationCode : activationCode // ignore: cast_nullable_to_non_nullable
|
||||
as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String,isCreated: null == isCreated ? _self.isCreated : isCreated // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isProvisioning: null == isProvisioning ? _self.isProvisioning : isProvisioning // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isProvisioned: null == isProvisioned ? _self.isProvisioned : isProvisioned // ignore: cast_nullable_to_non_nullable
|
||||
as bool,provisioningFailed: null == provisioningFailed ? _self.provisioningFailed : provisioningFailed // ignore: cast_nullable_to_non_nullable
|
||||
as bool,process: null == process ? _self.process : process // ignore: cast_nullable_to_non_nullable
|
||||
as ScaProcess,isProvisioned: null == isProvisioned ? _self.isProvisioned : isProvisioned // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isFirstConnectionDone: null == isFirstConnectionDone ? _self.isFirstConnectionDone : isFirstConnectionDone // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isConfirmingPin: null == isConfirmingPin ? _self.isConfirmingPin : isConfirmingPin // ignore: cast_nullable_to_non_nullable
|
||||
as bool,firstPin: null == firstPin ? _self.firstPin : firstPin // ignore: cast_nullable_to_non_nullable
|
||||
as String,isConnecting: null == isConnecting ? _self.isConnecting : isConnecting // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isConnected: null == isConnected ? _self.isConnected : isConnected // ignore: cast_nullable_to_non_nullable
|
||||
as String,isConnected: null == isConnected ? _self.isConnected : isConnected // ignore: cast_nullable_to_non_nullable
|
||||
as bool,pin: null == pin ? _self.pin : pin // ignore: cast_nullable_to_non_nullable
|
||||
as String,isSigning: null == isSigning ? _self.isSigning : isSigning // ignore: cast_nullable_to_non_nullable
|
||||
as bool,lastSignature: null == lastSignature ? _self.lastSignature : lastSignature // ignore: cast_nullable_to_non_nullable
|
||||
as String,success: null == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
|
||||
as bool,walletId: null == walletId ? _self.walletId : walletId // ignore: cast_nullable_to_non_nullable
|
||||
as String,lastSignature: null == lastSignature ? _self.lastSignature : lastSignature // ignore: cast_nullable_to_non_nullable
|
||||
as String,walletId: null == walletId ? _self.walletId : walletId // ignore: cast_nullable_to_non_nullable
|
||||
as String,walletStatus: null == walletStatus ? _self.walletStatus : walletStatus // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as String,showRetryProvisioning: null == showRetryProvisioning ? _self.showRetryProvisioning : showRetryProvisioning // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -56,9 +56,7 @@ class SignUpViewModel extends Notifier<SignUpViewState> {
|
||||
|
||||
static final RegExp _phoneRegex = RegExp(r'^\+?\d{6,15}$');
|
||||
|
||||
static final RegExp _nameRegex = RegExp(
|
||||
r"^[a-zA-ZÀ-ÿ\s\-']+$",
|
||||
);
|
||||
static final RegExp _nameRegex = RegExp(r"^[a-zA-ZÀ-ÿ\s\-']+$");
|
||||
|
||||
@override
|
||||
SignUpViewState build() {
|
||||
@@ -568,7 +566,11 @@ class SignUpViewModel extends Notifier<SignUpViewState> {
|
||||
phone: state.dialCode.trim() + state.phone.trim(),
|
||||
language: state.language.trim().isEmpty ? 'es' : state.language.trim(),
|
||||
password: state.password,
|
||||
bornAt: bornAt.millisecondsSinceEpoch,
|
||||
bornAt: DateTime.utc(
|
||||
bornAt.year,
|
||||
bornAt.month,
|
||||
bornAt.day,
|
||||
).millisecondsSinceEpoch,
|
||||
placeOfBirth: state.placeOfBirth.trim(),
|
||||
birthCountry: state.birthCountryCode.trim(),
|
||||
addresses: <AddressEntity>[_toAddressEntity(state.address)],
|
||||
|
||||
@@ -68,7 +68,10 @@ class ChildWalletScreen extends ConsumerWidget {
|
||||
pin: viewState.pin,
|
||||
isProcessing:
|
||||
viewState.isSigning || viewState.isUpdatingCard,
|
||||
processingText: context.translate(I18n.scaSigning),
|
||||
canSubmit: viewModel.canSubmitPin,
|
||||
submitText: context.translate(I18n.scaConnect),
|
||||
clearPinText: context.translate(I18n.scaClearPin),
|
||||
onDigitPressed: viewModel.onDigitPressed,
|
||||
onBackspacePressed: viewModel.onBackspacePressed,
|
||||
onClearPin: viewModel.onClearPin,
|
||||
|
||||
@@ -82,7 +82,10 @@ class LockCardScreen extends ConsumerWidget {
|
||||
title: context.translate(I18n.lockCardPinTitle),
|
||||
pin: viewState.pin,
|
||||
isProcessing: viewState.isSigning || viewState.isSubmitting,
|
||||
processingText: context.translate(I18n.scaSigning),
|
||||
canSubmit: viewModel.canSubmitPin,
|
||||
submitText: context.translate(I18n.scaConnect),
|
||||
clearPinText: context.translate(I18n.scaClearPin),
|
||||
onDigitPressed: viewModel.onDigitPressed,
|
||||
onBackspacePressed: viewModel.onBackspacePressed,
|
||||
onClearPin: viewModel.onClearPin,
|
||||
|
||||
@@ -416,7 +416,10 @@ class PayoutScreen extends ConsumerWidget {
|
||||
title: context.translate(I18n.payoutPinTitle),
|
||||
pin: viewState.pin,
|
||||
isProcessing: viewState.isSigning,
|
||||
processingText: context.translate(I18n.scaSigning),
|
||||
canSubmit: viewModel.canSubmitPin,
|
||||
submitText: context.translate(I18n.deviceSetupConfirm),
|
||||
clearPinText: context.translate(I18n.scaClearPin),
|
||||
onDigitPressed: viewModel.onDigitPressed,
|
||||
onBackspacePressed: viewModel.onBackspacePressed,
|
||||
onClearPin: viewModel.onClearPin,
|
||||
|
||||
@@ -41,7 +41,7 @@ class _SplashScreenState extends State<SplashScreen> {
|
||||
case InitialRoute.login:
|
||||
widget.navigationContract.goTo(AppRoutes.login);
|
||||
case InitialRoute.deviceSetup:
|
||||
widget.navigationContract.goTo(AppRoutes.deviceSetup);
|
||||
widget.navigationContract.goTo(AppRoutes.login);
|
||||
case InitialRoute.home:
|
||||
widget.navigationContract.goTo(AppRoutes.login);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
<versions>
|
||||
<version>2.6.4</version>
|
||||
</versions>
|
||||
<lastUpdated>20260219000000</lastUpdated>
|
||||
<lastUpdated>20260224000000</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
||||
|
||||
@@ -1 +1 @@
|
||||
d23803d2649c8b4a6df651aa4cfb8ffb
|
||||
2c321972b90055bcdf1c2015d5df1d47
|
||||
@@ -1 +1 @@
|
||||
b31ec93b3eddc91940c6dd58979739a17238a442
|
||||
fd6452bd1ecfb9dec5bc975bef3263b0453f1660
|
||||
@@ -196,6 +196,18 @@
|
||||
"scaProvisioningFailed": "Aktivierung fehlgeschlagen",
|
||||
"scaProvisioningWarning": "Beim erneuten Versuch wird der Zugang auf anderen Geräten deaktiviert. Nur ein Zugang pro Benutzer ist erlaubt.",
|
||||
"scaProvisioningRetry": "Aktivierung erneut versuchen",
|
||||
"scaProvisioning": "Aktivierung läuft...",
|
||||
"scaConnecting": "Verbindung wird hergestellt...",
|
||||
"scaSigning": "Signatur wird erstellt...",
|
||||
"scaConnect": "Verbinden",
|
||||
"scaClearPin": "PIN löschen",
|
||||
"scaErrorLoadingActivationCode": "Fehler beim Laden des Aktivierungscodes",
|
||||
"scaErrorProvisioning": "Fehler bei der Wallet-Aktivierung",
|
||||
"scaErrorConnecting": "Fehler bei der Wallet-Verbindung",
|
||||
"scaErrorSigning": "Fehler beim Signieren der Sitzung",
|
||||
"scaErrorPaymentProfile": "Fehler beim Einrichten des Zahlungsprofils",
|
||||
"deviceSetupCreatingProfile": "Profil wird erstellt...",
|
||||
"deviceSetupConfirm": "Bestätigen",
|
||||
|
||||
"errorLoadingData": "Fehler beim Laden der Daten",
|
||||
"retry": "Erneut versuchen",
|
||||
|
||||
@@ -196,6 +196,18 @@
|
||||
"scaProvisioningFailed": "Activation failed",
|
||||
"scaProvisioningWarning": "Retrying will disable access on any other device. Only one access per user is allowed.",
|
||||
"scaProvisioningRetry": "Retry activation",
|
||||
"scaProvisioning": "Activating...",
|
||||
"scaConnecting": "Connecting...",
|
||||
"scaSigning": "Signing...",
|
||||
"scaConnect": "Connect",
|
||||
"scaClearPin": "Clear PIN",
|
||||
"scaErrorLoadingActivationCode": "Error loading activation code",
|
||||
"scaErrorProvisioning": "Error activating wallet",
|
||||
"scaErrorConnecting": "Error connecting wallet",
|
||||
"scaErrorSigning": "Error signing session",
|
||||
"scaErrorPaymentProfile": "Error setting up payment profile",
|
||||
"deviceSetupCreatingProfile": "Creating profile...",
|
||||
"deviceSetupConfirm": "Confirm",
|
||||
|
||||
"errorLoadingData": "Error loading data",
|
||||
"retry": "Retry",
|
||||
|
||||
@@ -196,6 +196,18 @@
|
||||
"scaProvisioningFailed": "Error en la activación",
|
||||
"scaProvisioningWarning": "Al reintentar se desactivará el acceso en cualquier otro dispositivo. Solo se permite un acceso por usuario.",
|
||||
"scaProvisioningRetry": "Reintentar activación",
|
||||
"scaProvisioning": "Activando...",
|
||||
"scaConnecting": "Conectando...",
|
||||
"scaSigning": "Firmando...",
|
||||
"scaConnect": "Conectar",
|
||||
"scaClearPin": "Borrar PIN",
|
||||
"scaErrorLoadingActivationCode": "Error al obtener el código de activación",
|
||||
"scaErrorProvisioning": "Error al activar la billetera",
|
||||
"scaErrorConnecting": "Error al conectar la billetera",
|
||||
"scaErrorSigning": "Error al firmar la sesión",
|
||||
"scaErrorPaymentProfile": "Error al configurar el perfil de pago",
|
||||
"deviceSetupCreatingProfile": "Creando perfil...",
|
||||
"deviceSetupConfirm": "Confirmar",
|
||||
|
||||
"errorLoadingData": "Error al cargar datos",
|
||||
"retry": "Reintentar",
|
||||
|
||||
@@ -196,6 +196,18 @@
|
||||
"scaProvisioningFailed": "Échec de l'activation",
|
||||
"scaProvisioningWarning": "En réessayant, l'accès sera désactivé sur tout autre appareil. Un seul accès par utilisateur est autorisé.",
|
||||
"scaProvisioningRetry": "Réessayer l'activation",
|
||||
"scaProvisioning": "Activation en cours...",
|
||||
"scaConnecting": "Connexion en cours...",
|
||||
"scaSigning": "Signature en cours...",
|
||||
"scaConnect": "Connecter",
|
||||
"scaClearPin": "Effacer le PIN",
|
||||
"scaErrorLoadingActivationCode": "Erreur lors du chargement du code d'activation",
|
||||
"scaErrorProvisioning": "Erreur lors de l'activation du portefeuille",
|
||||
"scaErrorConnecting": "Erreur lors de la connexion du portefeuille",
|
||||
"scaErrorSigning": "Erreur lors de la signature de la session",
|
||||
"scaErrorPaymentProfile": "Erreur lors de la configuration du profil de paiement",
|
||||
"deviceSetupCreatingProfile": "Création du profil...",
|
||||
"deviceSetupConfirm": "Confirmer",
|
||||
|
||||
"errorLoadingData": "Erreur lors du chargement des données",
|
||||
"retry": "Réessayer",
|
||||
|
||||
@@ -196,6 +196,18 @@
|
||||
"scaProvisioningFailed": "Attivazione fallita",
|
||||
"scaProvisioningWarning": "Riprovando si disattiverà l'accesso su qualsiasi altro dispositivo. È consentito un solo accesso per utente.",
|
||||
"scaProvisioningRetry": "Riprova attivazione",
|
||||
"scaProvisioning": "Attivazione in corso...",
|
||||
"scaConnecting": "Connessione in corso...",
|
||||
"scaSigning": "Firma in corso...",
|
||||
"scaConnect": "Connetti",
|
||||
"scaClearPin": "Cancella PIN",
|
||||
"scaErrorLoadingActivationCode": "Errore nel caricamento del codice di attivazione",
|
||||
"scaErrorProvisioning": "Errore nell'attivazione del portafoglio",
|
||||
"scaErrorConnecting": "Errore nella connessione del portafoglio",
|
||||
"scaErrorSigning": "Errore nella firma della sessione",
|
||||
"scaErrorPaymentProfile": "Errore nella configurazione del profilo di pagamento",
|
||||
"deviceSetupCreatingProfile": "Creazione profilo...",
|
||||
"deviceSetupConfirm": "Conferma",
|
||||
|
||||
"errorLoadingData": "Errore durante il caricamento dei dati",
|
||||
"retry": "Riprova",
|
||||
|
||||
@@ -196,6 +196,18 @@
|
||||
"scaProvisioningFailed": "Falha na ativação",
|
||||
"scaProvisioningWarning": "Ao tentar novamente, o acesso será desativado em qualquer outro dispositivo. Apenas um acesso por utilizador é permitido.",
|
||||
"scaProvisioningRetry": "Tentar ativação novamente",
|
||||
"scaProvisioning": "A ativar...",
|
||||
"scaConnecting": "A conectar...",
|
||||
"scaSigning": "A assinar...",
|
||||
"scaConnect": "Conectar",
|
||||
"scaClearPin": "Apagar PIN",
|
||||
"scaErrorLoadingActivationCode": "Erro ao obter o código de ativação",
|
||||
"scaErrorProvisioning": "Erro ao ativar a carteira",
|
||||
"scaErrorConnecting": "Erro ao conectar a carteira",
|
||||
"scaErrorSigning": "Erro ao assinar a sessão",
|
||||
"scaErrorPaymentProfile": "Erro ao configurar o perfil de pagamento",
|
||||
"deviceSetupCreatingProfile": "A criar perfil...",
|
||||
"deviceSetupConfirm": "Confirmar",
|
||||
|
||||
"errorLoadingData": "Erro ao carregar dados",
|
||||
"retry": "Tentar novamente",
|
||||
|
||||
@@ -241,6 +241,18 @@ class I18n {
|
||||
static const String scaProvisioningFailed = 'scaProvisioningFailed';
|
||||
static const String scaProvisioningWarning = 'scaProvisioningWarning';
|
||||
static const String scaProvisioningRetry = 'scaProvisioningRetry';
|
||||
static const String scaProvisioning = 'scaProvisioning';
|
||||
static const String scaConnecting = 'scaConnecting';
|
||||
static const String scaSigning = 'scaSigning';
|
||||
static const String scaConnect = 'scaConnect';
|
||||
static const String scaClearPin = 'scaClearPin';
|
||||
static const String scaErrorLoadingActivationCode = 'scaErrorLoadingActivationCode';
|
||||
static const String scaErrorProvisioning = 'scaErrorProvisioning';
|
||||
static const String scaErrorConnecting = 'scaErrorConnecting';
|
||||
static const String scaErrorSigning = 'scaErrorSigning';
|
||||
static const String scaErrorPaymentProfile = 'scaErrorPaymentProfile';
|
||||
static const String deviceSetupCreatingProfile = 'deviceSetupCreatingProfile';
|
||||
static const String deviceSetupConfirm = 'deviceSetupConfirm';
|
||||
static const String errorLoadingData = 'errorLoadingData';
|
||||
static const String retry = 'retry';
|
||||
static const String walletTitle = 'walletTitle';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
import 'package:sf_shared/src/data/datasource/treezor_remote_data_source.dart';
|
||||
import 'package:sf_shared/src/data/datasource/trezzor_remote_data_source_impl.dart';
|
||||
import 'package:sf_shared/src/data/datasource/treezor_remote_data_source_impl.dart';
|
||||
|
||||
final treezorRemoteDatasourceProvider = Provider<TreezorRemoteDatasource>((
|
||||
ref,
|
||||
|
||||
@@ -26,7 +26,11 @@ class _DepositBlockState extends ConsumerState<DepositBlock> {
|
||||
final text = _amountController.text.trim();
|
||||
final amount = double.tryParse(text);
|
||||
if (amount == null || amount <= 0) {
|
||||
showTopSnackbar(context, message: context.translate(I18n.payoutErrorAmountRequired), type: MessageType.warning);
|
||||
showTopSnackbar(
|
||||
context,
|
||||
message: context.translate(I18n.payoutErrorAmountRequired),
|
||||
type: MessageType.warning,
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (amount > widget.max) return;
|
||||
@@ -66,6 +70,7 @@ class _DepositBlockState extends ConsumerState<DepositBlock> {
|
||||
hint: context.translate(I18n.depositAmountHint),
|
||||
keyboardType: TextInputType.number,
|
||||
controller: _amountController,
|
||||
length: 6,
|
||||
),
|
||||
),
|
||||
Align(
|
||||
@@ -88,7 +93,7 @@ class _DepositBlockState extends ConsumerState<DepositBlock> {
|
||||
Text(
|
||||
context.translate(
|
||||
I18n.depositMaxInfo,
|
||||
args: {'amount': '${widget.max}'},
|
||||
args: {'amount': widget.max.toStringAsFixed(2)},
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user