sca treezor and auth interceptors, some other fixes and lottie animation for app loading added

This commit is contained in:
2026-02-27 12:34:49 +01:00
parent 7849240ff2
commit f185acc3d4
43 changed files with 1189 additions and 113 deletions

View File

@@ -0,0 +1,364 @@
{
"configVersion": 2,
"packages": [
{
"name": "ansi_styles",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/ansi_styles-0.3.2+1",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "args",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/args-2.7.0",
"packageUri": "lib/",
"languageVersion": "3.3"
},
{
"name": "async",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/async-2.13.0",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "characters",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/characters-1.4.0",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "charcode",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/charcode-1.4.0",
"packageUri": "lib/",
"languageVersion": "3.0"
},
{
"name": "checked_yaml",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/checked_yaml-2.0.4",
"packageUri": "lib/",
"languageVersion": "3.8"
},
{
"name": "cli_launcher",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/cli_launcher-0.3.2+1",
"packageUri": "lib/",
"languageVersion": "3.8"
},
{
"name": "cli_util",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/cli_util-0.4.2",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "collection",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/collection-1.19.1",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "conventional_commit",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/conventional_commit-0.6.1+1",
"packageUri": "lib/",
"languageVersion": "3.8"
},
{
"name": "ffi",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/ffi-2.1.4",
"packageUri": "lib/",
"languageVersion": "3.7"
},
{
"name": "file",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/file-7.0.1",
"packageUri": "lib/",
"languageVersion": "3.0"
},
{
"name": "flutter",
"rootUri": "file:///Users/juliandalcalaf/Development/flutter/packages/flutter",
"packageUri": "lib/",
"languageVersion": "3.8"
},
{
"name": "flutter_secure_storage",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "flutter_secure_storage_linux",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.3",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "flutter_secure_storage_macos",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_macos-3.1.3",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "flutter_secure_storage_platform_interface",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_platform_interface-1.1.2",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "flutter_secure_storage_web",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "flutter_secure_storage_windows",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-3.1.2",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "flutter_web_plugins",
"rootUri": "file:///Users/juliandalcalaf/Development/flutter/packages/flutter_web_plugins",
"packageUri": "lib/",
"languageVersion": "3.8"
},
{
"name": "glob",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/glob-2.1.3",
"packageUri": "lib/",
"languageVersion": "3.3"
},
{
"name": "graphs",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/graphs-2.3.2",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "http",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/http-1.5.0",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "http_parser",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/http_parser-4.1.2",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "io",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/io-1.0.5",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "js",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/js-0.6.7",
"packageUri": "lib/",
"languageVersion": "2.19"
},
{
"name": "json_annotation",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/json_annotation-4.9.0",
"packageUri": "lib/",
"languageVersion": "3.0"
},
{
"name": "material_color_utilities",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/material_color_utilities-0.11.1",
"packageUri": "lib/",
"languageVersion": "2.17"
},
{
"name": "melos",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/melos-6.3.3",
"packageUri": "lib/",
"languageVersion": "3.8"
},
{
"name": "meta",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/meta-1.16.0",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "mustache_template",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/mustache_template-2.0.2",
"packageUri": "lib/",
"languageVersion": "3.7"
},
{
"name": "path",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path-1.9.1",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "path_provider",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider-2.1.5",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "path_provider_android",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_android-2.2.20",
"packageUri": "lib/",
"languageVersion": "3.9"
},
{
"name": "path_provider_foundation",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.4.3",
"packageUri": "lib/",
"languageVersion": "3.9"
},
{
"name": "path_provider_linux",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1",
"packageUri": "lib/",
"languageVersion": "2.19"
},
{
"name": "path_provider_platform_interface",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_platform_interface-2.1.2",
"packageUri": "lib/",
"languageVersion": "3.0"
},
{
"name": "path_provider_windows",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0",
"packageUri": "lib/",
"languageVersion": "3.2"
},
{
"name": "platform",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/platform-3.1.6",
"packageUri": "lib/",
"languageVersion": "3.2"
},
{
"name": "plugin_platform_interface",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/plugin_platform_interface-2.1.8",
"packageUri": "lib/",
"languageVersion": "3.0"
},
{
"name": "pool",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/pool-1.5.2",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "process",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/process-5.0.5",
"packageUri": "lib/",
"languageVersion": "3.5"
},
{
"name": "prompts",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/prompts-2.0.0",
"packageUri": "lib/",
"languageVersion": "2.12"
},
{
"name": "pub_semver",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/pub_semver-2.2.0",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "pub_updater",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/pub_updater-0.5.0",
"packageUri": "lib/",
"languageVersion": "3.5"
},
{
"name": "pubspec_parse",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/pubspec_parse-1.5.0",
"packageUri": "lib/",
"languageVersion": "3.6"
},
{
"name": "sky_engine",
"rootUri": "file:///Users/juliandalcalaf/Development/flutter/bin/cache/pkg/sky_engine",
"packageUri": "lib/",
"languageVersion": "3.8"
},
{
"name": "source_span",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/source_span-1.10.1",
"packageUri": "lib/",
"languageVersion": "3.1"
},
{
"name": "stack_trace",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/stack_trace-1.12.1",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "string_scanner",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/string_scanner-1.4.1",
"packageUri": "lib/",
"languageVersion": "3.1"
},
{
"name": "term_glyph",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/term_glyph-1.2.2",
"packageUri": "lib/",
"languageVersion": "3.1"
},
{
"name": "typed_data",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/typed_data-1.4.0",
"packageUri": "lib/",
"languageVersion": "3.5"
},
{
"name": "vector_math",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/vector_math-2.2.0",
"packageUri": "lib/",
"languageVersion": "3.1"
},
{
"name": "web",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/web-1.1.1",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "win32",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/win32-5.15.0",
"packageUri": "lib/",
"languageVersion": "3.8"
},
{
"name": "xdg_directories",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/xdg_directories-1.1.0",
"packageUri": "lib/",
"languageVersion": "3.3"
},
{
"name": "yaml",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/yaml-3.1.3",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "yaml_edit",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/yaml_edit-2.2.2",
"packageUri": "lib/",
"languageVersion": "3.1"
},
{
"name": "sf_app_platform_mono_repo",
"rootUri": "../",
"packageUri": "lib/",
"languageVersion": "3.0"
}
],
"generator": "pub",
"generatorVersion": "3.9.2",
"flutterRoot": "file:///Users/juliandalcalaf/Development/flutter",
"flutterVersion": "3.35.7",
"pubCache": "file:///Users/juliandalcalaf/.pub-cache"
}

View File

@@ -0,0 +1,491 @@
{
"roots": [
"sf_app_platform_mono_repo"
],
"packages": [
{
"name": "sf_app_platform_mono_repo",
"version": "0.0.0",
"dependencies": [
"flutter_secure_storage"
],
"devDependencies": [
"melos"
]
},
{
"name": "flutter_secure_storage",
"version": "9.2.4",
"dependencies": [
"flutter",
"flutter_secure_storage_linux",
"flutter_secure_storage_macos",
"flutter_secure_storage_platform_interface",
"flutter_secure_storage_web",
"flutter_secure_storage_windows",
"meta"
]
},
{
"name": "melos",
"version": "6.3.3",
"dependencies": [
"ansi_styles",
"args",
"async",
"cli_launcher",
"cli_util",
"collection",
"conventional_commit",
"file",
"glob",
"graphs",
"http",
"meta",
"mustache_template",
"path",
"platform",
"pool",
"prompts",
"pub_semver",
"pub_updater",
"pubspec_parse",
"string_scanner",
"yaml",
"yaml_edit"
]
},
{
"name": "meta",
"version": "1.16.0",
"dependencies": []
},
{
"name": "flutter_secure_storage_windows",
"version": "3.1.2",
"dependencies": [
"ffi",
"flutter",
"flutter_secure_storage_platform_interface",
"path",
"path_provider",
"win32"
]
},
{
"name": "flutter_secure_storage_web",
"version": "1.2.1",
"dependencies": [
"flutter",
"flutter_secure_storage_platform_interface",
"flutter_web_plugins",
"js"
]
},
{
"name": "flutter_secure_storage_platform_interface",
"version": "1.1.2",
"dependencies": [
"flutter",
"plugin_platform_interface"
]
},
{
"name": "flutter_secure_storage_macos",
"version": "3.1.3",
"dependencies": [
"flutter",
"flutter_secure_storage_platform_interface"
]
},
{
"name": "flutter_secure_storage_linux",
"version": "1.2.3",
"dependencies": [
"flutter",
"flutter_secure_storage_platform_interface"
]
},
{
"name": "flutter",
"version": "0.0.0",
"dependencies": [
"characters",
"collection",
"material_color_utilities",
"meta",
"sky_engine",
"vector_math"
]
},
{
"name": "yaml_edit",
"version": "2.2.2",
"dependencies": [
"collection",
"meta",
"source_span",
"yaml"
]
},
{
"name": "yaml",
"version": "3.1.3",
"dependencies": [
"collection",
"source_span",
"string_scanner"
]
},
{
"name": "string_scanner",
"version": "1.4.1",
"dependencies": [
"source_span"
]
},
{
"name": "pubspec_parse",
"version": "1.5.0",
"dependencies": [
"checked_yaml",
"collection",
"json_annotation",
"pub_semver",
"yaml"
]
},
{
"name": "pub_updater",
"version": "0.5.0",
"dependencies": [
"http",
"json_annotation",
"process",
"pub_semver"
]
},
{
"name": "pub_semver",
"version": "2.2.0",
"dependencies": [
"collection"
]
},
{
"name": "prompts",
"version": "2.0.0",
"dependencies": [
"charcode",
"io"
]
},
{
"name": "pool",
"version": "1.5.2",
"dependencies": [
"async",
"stack_trace"
]
},
{
"name": "platform",
"version": "3.1.6",
"dependencies": []
},
{
"name": "path",
"version": "1.9.1",
"dependencies": []
},
{
"name": "mustache_template",
"version": "2.0.2",
"dependencies": []
},
{
"name": "http",
"version": "1.5.0",
"dependencies": [
"async",
"http_parser",
"meta",
"web"
]
},
{
"name": "graphs",
"version": "2.3.2",
"dependencies": [
"collection"
]
},
{
"name": "glob",
"version": "2.1.3",
"dependencies": [
"async",
"collection",
"file",
"path",
"string_scanner"
]
},
{
"name": "file",
"version": "7.0.1",
"dependencies": [
"meta",
"path"
]
},
{
"name": "conventional_commit",
"version": "0.6.1+1",
"dependencies": []
},
{
"name": "collection",
"version": "1.19.1",
"dependencies": []
},
{
"name": "cli_util",
"version": "0.4.2",
"dependencies": [
"meta",
"path"
]
},
{
"name": "cli_launcher",
"version": "0.3.2+1",
"dependencies": [
"path",
"yaml"
]
},
{
"name": "async",
"version": "2.13.0",
"dependencies": [
"collection",
"meta"
]
},
{
"name": "args",
"version": "2.7.0",
"dependencies": []
},
{
"name": "ansi_styles",
"version": "0.3.2+1",
"dependencies": []
},
{
"name": "win32",
"version": "5.15.0",
"dependencies": [
"ffi"
]
},
{
"name": "path_provider",
"version": "2.1.5",
"dependencies": [
"flutter",
"path_provider_android",
"path_provider_foundation",
"path_provider_linux",
"path_provider_platform_interface",
"path_provider_windows"
]
},
{
"name": "ffi",
"version": "2.1.4",
"dependencies": []
},
{
"name": "js",
"version": "0.6.7",
"dependencies": [
"meta"
]
},
{
"name": "flutter_web_plugins",
"version": "0.0.0",
"dependencies": [
"flutter"
]
},
{
"name": "plugin_platform_interface",
"version": "2.1.8",
"dependencies": [
"meta"
]
},
{
"name": "sky_engine",
"version": "0.0.0",
"dependencies": []
},
{
"name": "vector_math",
"version": "2.2.0",
"dependencies": []
},
{
"name": "material_color_utilities",
"version": "0.11.1",
"dependencies": [
"collection"
]
},
{
"name": "characters",
"version": "1.4.0",
"dependencies": []
},
{
"name": "source_span",
"version": "1.10.1",
"dependencies": [
"collection",
"path",
"term_glyph"
]
},
{
"name": "json_annotation",
"version": "4.9.0",
"dependencies": [
"meta"
]
},
{
"name": "checked_yaml",
"version": "2.0.4",
"dependencies": [
"json_annotation",
"source_span",
"yaml"
]
},
{
"name": "process",
"version": "5.0.5",
"dependencies": [
"file",
"path",
"platform"
]
},
{
"name": "io",
"version": "1.0.5",
"dependencies": [
"meta",
"path",
"string_scanner"
]
},
{
"name": "charcode",
"version": "1.4.0",
"dependencies": []
},
{
"name": "stack_trace",
"version": "1.12.1",
"dependencies": [
"path"
]
},
{
"name": "web",
"version": "1.1.1",
"dependencies": []
},
{
"name": "http_parser",
"version": "4.1.2",
"dependencies": [
"collection",
"source_span",
"string_scanner",
"typed_data"
]
},
{
"name": "path_provider_windows",
"version": "2.3.0",
"dependencies": [
"ffi",
"flutter",
"path",
"path_provider_platform_interface"
]
},
{
"name": "path_provider_platform_interface",
"version": "2.1.2",
"dependencies": [
"flutter",
"platform",
"plugin_platform_interface"
]
},
{
"name": "path_provider_linux",
"version": "2.2.1",
"dependencies": [
"ffi",
"flutter",
"path",
"path_provider_platform_interface",
"xdg_directories"
]
},
{
"name": "path_provider_foundation",
"version": "2.4.3",
"dependencies": [
"flutter",
"path_provider_platform_interface"
]
},
{
"name": "path_provider_android",
"version": "2.2.20",
"dependencies": [
"flutter",
"path_provider_platform_interface"
]
},
{
"name": "term_glyph",
"version": "1.2.2",
"dependencies": []
},
{
"name": "typed_data",
"version": "1.4.0",
"dependencies": [
"collection"
]
},
{
"name": "xdg_directories",
"version": "1.1.0",
"dependencies": [
"meta",
"path"
]
}
],
"configVersion": 1
}

Binary file not shown.

View File

@@ -1,4 +1,5 @@
import 'package:auth/auth.dart';
import 'package:get_it/get_it.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -6,7 +7,7 @@ import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:design_system/design_system.dart';
import 'package:sca_treezor/sca_treezor_module.dart';
import 'package:sca_treezor/sca_treezor.dart';
import 'package:sf_app_platform/config/env/questia_env_config.dart';
import 'package:sf_app_platform/navigation/app_router.dart';
import 'package:navigation/navigation.dart';
@@ -31,7 +32,14 @@ Future<void> main() async {
await configureDependencies(
QuestiaEnvConfig(),
log: kDebugMode,
onTreezorTokenExpired: () => appRouter.go(AppRoutes.scaTreezor),
onTokenExpired: () => appRouter.go(AppRoutes.scaTreezor),
onUnauthorized: () async {
try {
await GetIt.I<TreezorWalletConnectionService>().logout();
} catch (_) {}
await clearSessionData();
appRouter.go(AppRoutes.login);
},
);
runApp(const ProviderScope(child: PlatformApp()));
@@ -55,6 +63,7 @@ class PlatformAppState extends ConsumerState<PlatformApp>
walletHeartbeat = WalletHeartbeatService(
repository: ref.read(treezorRepositoryProvider),
sessionLocal: SessionLocalDatasourceImpl(),
onError: () => appRouter.go(AppRoutes.scaTreezor),
);
onBeforeSessionCleared = walletHeartbeat.stop;
walletHeartbeat.start();

View File

@@ -1,21 +1,24 @@
import 'dart:async';
import 'package:auth/auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:sf_shared/sf_shared.dart';
class WalletHeartbeatService {
WalletHeartbeatService({
required TreezorRepository repository,
required SessionLocalDatasource sessionLocal,
required void Function() onError,
}) : _repository = repository,
_sessionLocal = sessionLocal;
_sessionLocal = sessionLocal,
_onError = onError;
final TreezorRepository _repository;
final SessionLocalDatasource _sessionLocal;
final void Function() _onError;
Timer? _timer;
static const _interval = Duration(minutes: 4);
static const _interval = Duration(minutes: 3);
void start() {
if (_timer != null) return;
@@ -39,6 +42,8 @@ class WalletHeartbeatService {
debugPrint('[WalletHeartbeat] /wallets/$walletId => OK');
} catch (e) {
debugPrint('[WalletHeartbeat] error: $e');
stop();
_onError();
}
}
}

View File

@@ -654,6 +654,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
lottie:
dependency: transitive
description:
name: lottie
sha256: "8ae0be46dbd9e19641791dc12ee480d34e1fd3f84c749adc05f3ad9342b71b95"
url: "https://pub.dev"
source: hosted
version: "3.3.2"
matcher:
dependency: transitive
description:

View File

@@ -13,6 +13,12 @@
"packageUri": "lib/",
"languageVersion": "3.5"
},
{
"name": "archive",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/archive-4.0.9",
"packageUri": "lib/",
"languageVersion": "3.0"
},
{
"name": "args",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/args-2.7.0",
@@ -385,6 +391,12 @@
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "lottie",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/lottie-3.3.2",
"packageUri": "lib/",
"languageVersion": "3.9"
},
{
"name": "matcher",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/matcher-0.12.17",
@@ -493,6 +505,12 @@
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "posix",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/posix-6.5.0",
"packageUri": "lib/",
"languageVersion": "3.0"
},
{
"name": "pub_semver",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/pub_semver-2.2.0",

View File

@@ -109,6 +109,7 @@
"flutter_riverpod",
"fonts",
"get_it",
"lottie",
"top_snackbar_flutter",
"utils"
]
@@ -1306,6 +1307,34 @@
"args",
"yaml"
]
},
{
"name": "lottie",
"version": "3.3.2",
"dependencies": [
"archive",
"flutter",
"http",
"path",
"vector_math"
]
},
{
"name": "archive",
"version": "4.0.9",
"dependencies": [
"path",
"posix"
]
},
{
"name": "posix",
"version": "6.5.0",
"dependencies": [
"ffi",
"meta",
"path"
]
}
],
"configVersion": 1

View File

@@ -32,7 +32,7 @@ class _ActivityScreenState extends ConsumerState<ActivityScreen> {
ActivityViewState viewState,
) {
if (viewState.isLoading) {
return const Center(child: CircularProgressIndicator());
return const Center(child: AppLoadingIndicator());
}
if (viewState.errorMessage.isNotEmpty && viewState.tabs.isEmpty) {
@@ -166,7 +166,7 @@ class _ActivityScreenState extends ConsumerState<ActivityScreen> {
ActivityViewState viewState,
) {
if (viewState.isLoadingTransactions) {
return const Center(child: CircularProgressIndicator());
return const Center(child: AppLoadingIndicator());
}
if (viewState.errorMessage.isNotEmpty) {
@@ -201,7 +201,7 @@ class _ActivityScreenState extends ConsumerState<ActivityScreen> {
padding: const EdgeInsets.only(bottom: 16),
child: balanceAsync.when(
loading: () =>
const Center(child: CircularProgressIndicator()),
const Center(child: AppLoadingIndicator(size: 48)),
error: (_, __) => const SizedBox.shrink(),
data: (balance) => WalletBalanceBlock(
availableBalance: balance.availableBalance,

View File

@@ -17,6 +17,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "7.7.1"
archive:
dependency: transitive
description:
name: archive
sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff
url: "https://pub.dev"
source: hosted
version: "4.0.9"
args:
dependency: transitive
description:
@@ -501,6 +509,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
lottie:
dependency: transitive
description:
name: lottie
sha256: "8ae0be46dbd9e19641791dc12ee480d34e1fd3f84c749adc05f3ad9342b71b95"
url: "https://pub.dev"
source: hosted
version: "3.3.2"
matcher:
dependency: transitive
description:
@@ -645,6 +661,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.5.2"
posix:
dependency: transitive
description:
name: posix
sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07"
url: "https://pub.dev"
source: hosted
version: "6.5.0"
pub_semver:
dependency: transitive
description:

View File

@@ -1,3 +1,4 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -14,7 +15,7 @@ class LoadingScreen extends StatelessWidget{
children: [
Spacer(flex: 8),
SvgPicture.asset("assets/images/ui/logo_sf.svg"),
CircularProgressIndicator(),
AppLoadingIndicator(),
Spacer(flex: 10)
],
),

View File

@@ -1,3 +1,4 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
class LoadingGoogleScreen extends StatelessWidget {
@@ -16,7 +17,7 @@ class LoadingGoogleScreen extends StatelessWidget {
"Continuar con Google",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
),
CircularProgressIndicator(),
AppLoadingIndicator(),
Text("Redirigiendo a Google"),
Spacer(flex: 10),
],

View File

@@ -125,7 +125,7 @@ class LoginScreen extends ConsumerWidget {
if (!context.mounted) return;
if (verified == true) {
navigationContract.goTo(AppRoutes.scaTreezor);
navigationContract.goTo('${AppRoutes.scaTreezor}?fromLogin=true');
}
}

View File

@@ -10,10 +10,14 @@ class SCATreezorBuilder {
Page<void> buildPage(BuildContext context, GoRouterState state) {
final navigationContract = GetIt.I<NavigationContract>();
final fromLogin = state.uri.queryParameters['fromLogin'] == 'true';
return MaterialPage<void>(
key: state.pageKey,
child: SCATreezorScreen(navigationContract: navigationContract),
child: SCATreezorScreen(
navigationContract: navigationContract,
showCloseButton: fromLogin,
),
);
}
}

View File

@@ -11,8 +11,13 @@ import 'sca_treezor_view_state.dart';
class SCATreezorScreen extends ConsumerWidget {
final NavigationContract navigationContract;
final bool showCloseButton;
const SCATreezorScreen({super.key, required this.navigationContract});
const SCATreezorScreen({
super.key,
required this.navigationContract,
this.showCloseButton = false,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
@@ -37,24 +42,25 @@ class SCATreezorScreen extends ConsumerWidget {
body: SafeArea(
child: Column(
children: [
Align(
alignment: Alignment.topRight,
child: Padding(
padding: const EdgeInsets.only(top: 8, right: 8),
child: IconButton(
onPressed: state.isProcessing
? null
: () => navigationContract.goTo(AppRoutes.login),
icon: const Icon(Icons.close),
if (showCloseButton)
Align(
alignment: Alignment.topRight,
child: Padding(
padding: const EdgeInsets.only(top: 8, right: 8),
child: IconButton(
onPressed: state.isProcessing
? null
: () => navigationContract.goTo(AppRoutes.login),
icon: const Icon(Icons.close),
),
),
),
),
Expanded(
child: Center(
child: Padding(
padding: const EdgeInsets.all(16),
child: state.isLoading
? const CircularProgressIndicator()
? const AppLoadingIndicator()
: state.isProvisioned
? Column(
mainAxisSize: MainAxisSize.min,
@@ -126,7 +132,7 @@ class _ProvisioningBody extends ConsumerWidget {
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(height: 16),
const CircularProgressIndicator(),
const AppLoadingIndicator(),
const SizedBox(height: 8),
Text(context.translate(I18n.scaProvisioning)),
],

View File

@@ -38,7 +38,7 @@ class AllowanceScreen extends ConsumerWidget {
final weekDays = _localizedWeekDays(context);
if (viewState.isLoading) {
return const Scaffold(body: Center(child: CircularProgressIndicator()));
return const Scaffold(body: Center(child: AppLoadingIndicator()));
}
if (viewState.errorMessage.isNotEmpty) {

View File

@@ -96,7 +96,7 @@ class ChildWalletScreen extends ConsumerWidget {
}
if (viewState.isLoading) {
return const Scaffold(body: Center(child: CircularProgressIndicator()));
return const Scaffold(body: Center(child: AppLoadingIndicator()));
}
if (viewState.errorMessage.isNotEmpty) {
@@ -272,7 +272,7 @@ class ChildWalletScreen extends ConsumerWidget {
const Center(
child: Padding(
padding: EdgeInsets.all(24),
child: CircularProgressIndicator(),
child: AppLoadingIndicator(size: 48),
),
)
else if (viewState.transactions.isEmpty)

View File

@@ -46,7 +46,7 @@ class DepositScreen extends ConsumerWidget {
});
if (viewState.isLoading) {
return const Scaffold(body: Center(child: CircularProgressIndicator()));
return const Scaffold(body: Center(child: AppLoadingIndicator()));
}
if (viewState.errorMessage.isNotEmpty && viewState.childProfile == null) {

View File

@@ -37,7 +37,7 @@ class ExtractScreen extends ConsumerWidget {
});
if (viewState.isLoading) {
return const Scaffold(body: Center(child: CircularProgressIndicator()));
return const Scaffold(body: Center(child: AppLoadingIndicator()));
}
if (viewState.errorMessage.isNotEmpty && viewState.childProfile == null) {

View File

@@ -28,7 +28,7 @@ class GoalsScreen extends ConsumerWidget {
final cardStatus = ref.watch(childDataProvider(childId)).cardStatus;
if (viewState.isLoading) {
return const Scaffold(body: Center(child: CircularProgressIndicator()));
return const Scaffold(body: Center(child: AppLoadingIndicator()));
}
if (viewState.errorMessage.isNotEmpty) {

View File

@@ -28,7 +28,7 @@ class LimitsScreen extends ConsumerWidget {
final cardStatus = ref.watch(childDataProvider(childId)).cardStatus;
if (viewState.isLoading) {
return const Scaffold(body: Center(child: CircularProgressIndicator()));
return const Scaffold(body: Center(child: AppLoadingIndicator()));
}
if (viewState.errorMessage.isNotEmpty && viewState.childProfile == null) {
@@ -92,13 +92,20 @@ class _LimitsFooter extends StatelessWidget {
: () async {
final success = await viewModel.saveAll();
if (!context.mounted) return;
showTopSnackbar(
context,
message: success
? context.translate(I18n.limitsSaveSuccess)
: context.translate(I18n.limitsSaveError),
type: success ? MessageType.success : MessageType.error,
);
if (success) {
showTopSnackbar(
context,
message: context.translate(I18n.limitsSaveSuccess),
type: MessageType.success,
);
navigation.goBack();
} else {
showTopSnackbar(
context,
message: context.translate(I18n.limitsSaveError),
type: MessageType.error,
);
}
},
cancelText: context.translate(I18n.cancel),
onCancelPressed: () => navigation.goBack(),
@@ -136,7 +143,7 @@ class _SpendingLimitsSection extends StatelessWidget {
if (viewState.isLoadingLimits)
const Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Center(child: CircularProgressIndicator()),
child: Center(child: AppLoadingIndicator(size: 48)),
)
else
..._limitFields.map((entry) {
@@ -196,7 +203,7 @@ class _BlockedStoresSection extends StatelessWidget {
if (viewState.isLoadingMccGroups)
const Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Center(child: CircularProgressIndicator()),
child: Center(child: AppLoadingIndicator(size: 48)),
)
else
...viewState.mccGroups.map((group) {

View File

@@ -52,7 +52,7 @@ class LockCardScreen extends ConsumerWidget {
});
if (viewState.isLoading) {
return const Scaffold(body: Center(child: CircularProgressIndicator()));
return const Scaffold(body: Center(child: AppLoadingIndicator()));
}
if (viewState.errorMessage.isNotEmpty && viewState.childProfile == null) {

View File

@@ -18,7 +18,7 @@ class HomeScreen extends ConsumerWidget {
final viewState = ref.watch(homeViewModelProvider);
if (viewState.isLoading) {
return const Center(child: CircularProgressIndicator());
return const Center(child: AppLoadingIndicator());
}
if (viewState.errorMessage.isNotEmpty) {

View File

@@ -44,7 +44,7 @@ class PaymentMethodsScreen extends ConsumerWidget {
if (viewState.isDeleting)
Container(
color: Colors.black26,
child: const Center(child: CircularProgressIndicator()),
child: const Center(child: AppLoadingIndicator()),
),
],
);
@@ -57,7 +57,7 @@ class PaymentMethodsScreen extends ConsumerWidget {
PaymentMethodsViewState viewState,
) {
if (viewState.isLoading) {
return const Center(child: CircularProgressIndicator());
return const Center(child: AppLoadingIndicator());
}
if (viewState.errorMessage.isNotEmpty) {

View File

@@ -98,7 +98,7 @@ class PayoutScreen extends ConsumerWidget {
) {
switch (viewState.step) {
case PayoutStep.loading:
return const Center(child: CircularProgressIndicator());
return const Center(child: AppLoadingIndicator());
case PayoutStep.beneficiaryList:
return _buildBeneficiaryList(context, ref, theme, viewState);
case PayoutStep.addBeneficiary:
@@ -126,14 +126,6 @@ class PayoutScreen extends ConsumerWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (viewState.errorMessage.isNotEmpty)
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Text(
viewState.errorMessage,
style: const TextStyle(color: Colors.red, fontSize: 13),
),
),
if (viewState.beneficiaries.isEmpty) ...[
const SizedBox(height: 32),
Icon(
@@ -287,18 +279,9 @@ class PayoutScreen extends ConsumerWidget {
label: context.translate(I18n.payoutHolderNameLabel),
hint: context.translate(I18n.payoutHolderNameHint),
),
const SizedBox(height: 8),
if (viewState.errorMessage.isNotEmpty)
Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Text(
viewState.errorMessage,
style: const TextStyle(color: Colors.red, fontSize: 13),
),
),
const SizedBox(height: 24),
if (viewState.isSubmitting)
const Center(child: CircularProgressIndicator())
const Center(child: AppLoadingIndicator(size: 48))
else ...[
PrimaryButton(
text: context.translate(I18n.payoutAddBeneficiary),
@@ -371,18 +354,9 @@ class PayoutScreen extends ConsumerWidget {
label: context.translate(I18n.payoutAmountLabel),
hint: '0.00',
),
const SizedBox(height: 8),
if (viewState.errorMessage.isNotEmpty)
Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Text(
viewState.errorMessage,
style: const TextStyle(color: Colors.red, fontSize: 13),
),
),
const SizedBox(height: 24),
if (viewState.isSubmitting)
const Center(child: CircularProgressIndicator())
const Center(child: AppLoadingIndicator(size: 48))
else ...[
PrimaryButton(
text: context.translate(I18n.payoutButton),
@@ -438,6 +412,6 @@ class PayoutScreen extends ConsumerWidget {
}
Widget _buildSuccess(BuildContext context, ThemePort theme) {
return const Center(child: CircularProgressIndicator());
return const Center(child: AppLoadingIndicator());
}
}

View File

@@ -286,18 +286,20 @@ class PayoutViewModel extends Notifier<PayoutViewState> {
if (!ref.mounted) return;
final url = 'https://savefamily.sandbox.treezor.co/v1/payouts';
final scaInput = {
'url': url,
'body': {
'walletId': int.parse(state.walletId),
'amount': amount.toStringAsFixed(2),
'currency': 'EUR',
'beneficiaryId': beneficiary.id,
'beneficiaryValidationId': beneficiaryValidationId,
},
};
debugPrint('[Payout] SCA input: ${jsonEncode(scaInput)}');
final scaProof = await _signatureService.generateJwsWithPin(
message: '',
input: jsonEncode({
'url': url,
'body': {
'walletId': state.walletId,
'amount': amount,
'currency': 'EUR',
'beneficiaryId': beneficiary.id,
'beneficiaryValidationId': beneficiaryValidationId,
},
}),
input: jsonEncode(scaInput),
pin: pin,
);

View File

@@ -23,7 +23,7 @@ class ProfileSettingsScreen extends ConsumerWidget {
if (viewState.isLoading) {
return Scaffold(
backgroundColor: theme.getColorFor(ThemeCode.backgroundSecondary),
body: const Center(child: CircularProgressIndicator()),
body: const Center(child: AppLoadingIndicator()),
);
}
@@ -661,7 +661,7 @@ class ProfileSettingsScreen extends ConsumerWidget {
showDialog(
context: context,
barrierDismissible: false,
builder: (_) => const Center(child: CircularProgressIndicator()),
builder: (_) => const Center(child: AppLoadingIndicator()),
);
try {
await ref.read(logoutProvider.future);

View File

@@ -38,7 +38,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
ProfileViewState viewState,
) {
if (viewState.isLoading) {
return const Center(child: CircularProgressIndicator());
return const Center(child: AppLoadingIndicator());
}
if (viewState.errorMessage.isNotEmpty) {

File diff suppressed because one or more lines are too long

View File

@@ -14,3 +14,4 @@ export 'src/dropdowns/country_prefix_picker.dart';
export 'src/containers/section_container.dart';
export 'src/containers/footer_container.dart';
export 'src/rows/editable_row.dart';
export 'src/loading/app_loading_indicator.dart';

View File

@@ -0,0 +1,19 @@
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
class AppLoadingIndicator extends StatelessWidget {
final double size;
const AppLoadingIndicator({super.key, this.size = 96});
@override
Widget build(BuildContext context) {
return SizedBox(
width: size,
height: size,
child: Lottie.asset(
'packages/design_system/assets/animations/smartphone-payment.json',
),
);
}
}

View File

@@ -20,6 +20,7 @@ dependencies:
fonts:
path: ../../packages/fonts
top_snackbar_flutter: ^3.3.0
lottie: ^3.3.1
dev_dependencies:
flutter_test:
@@ -34,6 +35,9 @@ dev_dependencies:
flutter:
uses-material-design: true
assets:
- assets/animations/
# To add assets to your package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg

View File

@@ -7,6 +7,6 @@
<versions>
<version>2.6.4</version>
</versions>
<lastUpdated>20260226000000</lastUpdated>
<lastUpdated>20260227000000</lastUpdated>
</versioning>
</metadata>

View File

@@ -1 +1 @@
7b90ce161fd31b7548cc91c8f2a13ac0
e97fa16e8f35dd6c43c14f3e3999a327

View File

@@ -1 +1 @@
9e11339b7af5cbe6896128c907e1bb1b596c981d
cf2eadb6532811e0584c52dda21baf78631a71d9

View File

@@ -25,6 +25,12 @@
"packageUri": "lib/",
"languageVersion": "3.5"
},
{
"name": "archive",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/archive-4.0.9",
"packageUri": "lib/",
"languageVersion": "3.0"
},
{
"name": "args",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/args-2.7.0",
@@ -337,6 +343,12 @@
"packageUri": "lib/",
"languageVersion": "3.0"
},
{
"name": "http",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/http-1.6.0",
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "http_multi_server",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/http_multi_server-3.2.2",
@@ -409,6 +421,12 @@
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "lottie",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/lottie-3.3.2",
"packageUri": "lib/",
"languageVersion": "3.9"
},
{
"name": "matcher",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/matcher-0.12.17",
@@ -517,6 +535,12 @@
"packageUri": "lib/",
"languageVersion": "3.4"
},
{
"name": "posix",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/posix-6.5.0",
"packageUri": "lib/",
"languageVersion": "3.0"
},
{
"name": "pub_semver",
"rootUri": "file:///Users/juliandalcalaf/.pub-cache/hosted/pub.dev/pub_semver-2.2.0",

View File

@@ -85,6 +85,7 @@
"flutter_riverpod",
"fonts",
"get_it",
"lottie",
"top_snackbar_flutter",
"utils"
]
@@ -1435,6 +1436,44 @@
"args",
"yaml"
]
},
{
"name": "lottie",
"version": "3.3.2",
"dependencies": [
"archive",
"flutter",
"http",
"path",
"vector_math"
]
},
{
"name": "archive",
"version": "4.0.9",
"dependencies": [
"path",
"posix"
]
},
{
"name": "posix",
"version": "6.5.0",
"dependencies": [
"ffi",
"meta",
"path"
]
},
{
"name": "http",
"version": "1.6.0",
"dependencies": [
"async",
"http_parser",
"meta",
"web"
]
}
],
"configVersion": 1

View File

@@ -80,7 +80,7 @@ class _PayinBottomSheetState extends ConsumerState<PayinBottomSheet> {
if (viewState.isLoadingCards)
const Padding(
padding: EdgeInsets.symmetric(vertical: 32),
child: Center(child: CircularProgressIndicator()),
child: Center(child: AppLoadingIndicator(size: 48)),
)
else if (viewState.cards.isEmpty)
_buildNoCards(context, theme)

View File

@@ -76,7 +76,7 @@ class _HiPayWebViewScreenState extends ConsumerState<HiPayWebViewScreen> {
Widget _buildBody(dynamic state, ThemePort theme) {
if (state.isLoading) {
return const Center(child: CircularProgressIndicator());
return const Center(child: AppLoadingIndicator());
}
if (state.errorMessage.isNotEmpty) {

View File

@@ -33,6 +33,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.13.4"
archive:
dependency: transitive
description:
name: archive
sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff
url: "https://pub.dev"
source: hosted
version: "4.0.9"
args:
dependency: transitive
description:
@@ -438,6 +446,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.3.0"
http:
dependency: transitive
description:
name: http
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
url: "https://pub.dev"
source: hosted
version: "1.6.0"
http_multi_server:
dependency: transitive
description:
@@ -534,6 +550,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
lottie:
dependency: transitive
description:
name: lottie
sha256: "8ae0be46dbd9e19641791dc12ee480d34e1fd3f84c749adc05f3ad9342b71b95"
url: "https://pub.dev"
source: hosted
version: "3.3.2"
matcher:
dependency: transitive
description:
@@ -677,6 +701,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.5.2"
posix:
dependency: transitive
description:
name: posix
sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07"
url: "https://pub.dev"
source: hosted
version: "6.5.0"
pub_semver:
dependency: transitive
description:

View File

@@ -17,7 +17,8 @@ final getIt = GetIt.instance;
Future<void> configureDependencies(
EnvConfig env, {
bool log = false,
void Function()? onTreezorTokenExpired,
void Function()? onTokenExpired,
void Function()? onUnauthorized,
}) async {
final cookieJar = await buildPersistCookieJar();
@@ -28,9 +29,12 @@ Future<void> configureDependencies(
cookieJar: cookieJar,
);
if (onTreezorTokenExpired != null) {
if (onTokenExpired != null && onUnauthorized != null) {
dio.interceptors.add(
TreezorTokenInterceptor(onTokenExpired: onTreezorTokenExpired),
TreezorTokenInterceptor(
onTokenExpired: onTokenExpired,
onUnauthorized: onUnauthorized,
),
);
}

View File

@@ -3,19 +3,29 @@ import 'dart:convert';
import 'package:dio/dio.dart';
class TreezorTokenInterceptor extends Interceptor {
TreezorTokenInterceptor({required void Function() onTokenExpired})
: _onTokenExpired = onTokenExpired;
TreezorTokenInterceptor({
required void Function() onTokenExpired,
required void Function() onUnauthorized,
}) : _onTokenExpired = onTokenExpired,
_onUnauthorized = onUnauthorized;
final void Function() _onTokenExpired;
final void Function() _onUnauthorized;
bool _handling = false;
@override
void onError(DioException err, ErrorInterceptorHandler handler) {
final message = _extractApiMessage(err.response?.data);
if (message != null && message.contains('Treezor Token Expired') && !_handling) {
_handling = true;
_onTokenExpired();
Future.delayed(const Duration(seconds: 2), () => _handling = false);
if (!_handling) {
final message = _extractApiMessage(err.response?.data);
if (message != null && message.contains('Treezor Token Expired')) {
_handling = true;
_onTokenExpired();
Future.delayed(const Duration(seconds: 2), () => _handling = false);
} else if (err.response?.statusCode == 401) {
_handling = true;
_onUnauthorized();
Future.delayed(const Duration(seconds: 2), () => _handling = false);
}
}
handler.next(err);
}

View File

@@ -243,16 +243,15 @@ class TreezorRemoteDatasourceImpl implements TreezorRemoteDatasource {
required String scaProof,
}) async {
try {
await _repository.post<void>(
'/wallets/transfer',
body: <String, dynamic>{
'walletId': walletId,
'target': beneficiaryId,
'beneficiaryValidationId': beneficiaryValidationId,
'amount': amount,
'scaProof': scaProof,
},
);
final body = <String, dynamic>{
'walletId': walletId,
'target': beneficiaryId,
'beneficiaryValidationId': beneficiaryValidationId,
'amount': amount.toStringAsFixed(2),
'scaProof': scaProof,
};
debugPrint('[Payout] POST /wallets/transfer body: $body');
await _repository.post<void>('/wallets/transfer', body: body);
} on DioException catch (error) {
throw _mapDioError(error, defaultMessage: 'Error in /wallets/transfer');
}