diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index c39b04d955156b8ee0254d950cb7082148ceaa1c..cd9619425429b68dae7cb14d19a18aa4c1680e34 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -39,6 +39,12 @@
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="june" />
+            </intent-filter>
         </activity>
         <!-- Don't delete the meta-data below.
              This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
@@ -48,10 +54,10 @@
     </application>
 
     <queries>
-        <!-- If your app opens https URLs -->
         <intent>
             <action android:name="android.intent.action.VIEW" />
             <data android:scheme="https" />
         </intent>
     </queries>
+
 </manifest>
diff --git a/lib/main.dart b/lib/main.dart
index 4c4d3a4c1a40e85a060a8861fbc5b0e7e8e526f4..40026409fee7954cf875f2ecacb880a0ee8517c9 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -21,6 +21,7 @@ import 'package:responsive_framework/responsive_wrapper.dart';
 import 'package:responsive_framework/utils/scroll_behavior.dart';
 import 'package:sentry_flutter/sentry_flutter.dart';
 import 'package:sentry_logging/sentry_logging.dart';
+import 'package:uni_links/uni_links.dart';
 
 import 'app_bloc_observer.dart';
 import 'config/theme.dart';
@@ -37,6 +38,7 @@ import 'data/models/payment_cubit.dart';
 import 'data/models/theme_cubit.dart';
 import 'data/models/transaction_cubit.dart';
 import 'g1/api.dart';
+import 'g1/g1_helper.dart';
 import 'shared_prefs.dart';
 import 'ui/contacts_cache.dart';
 import 'ui/logger.dart';
@@ -44,6 +46,7 @@ import 'ui/notification_controller.dart';
 import 'ui/screens/skeleton_screen.dart';
 import 'ui/ui_helpers.dart';
 import 'ui/widgets/connectivity_widget_wrapper_wrapper.dart';
+import 'ui/widgets/first_screen/pay_contact_search_page.dart';
 
 void main() async {
   await NotificationController.initializeLocalNotifications();
@@ -79,7 +82,7 @@ void main() async {
     final Box<dynamic> box = await Hive.openBox('hydrated_box',
         path: HydratedStorage.webStorageDirectory.path);
     final List<dynamic> keysToDelete =
-        box.keys.where((dynamic key) => '$key'.startsWith('minified')).toList();
+    box.keys.where((dynamic key) => '$key'.startsWith('minified')).toList();
     box.deleteAll(keysToDelete);
     // This should we done after init
     // await HydratedBloc.storage.clear();
@@ -93,7 +96,7 @@ void main() async {
     final Directory tmpDir = await getTemporaryDirectory();
     Hive.init(tmpDir.toString());
     HydratedBloc.storage =
-        await HydratedStorage.build(storageDirectory: tmpDir);
+    await HydratedStorage.build(storageDirectory: tmpDir);
   }
 
   PWAInstall().setup(installCallback: () {
@@ -102,7 +105,8 @@ void main() async {
 
   Bloc.observer = AppBlocObserver();
 
-  void appRunner() => runApp(
+  void appRunner() =>
+      runApp(
         EasyLocalization(
           path: 'assets/translations',
           supportedLocales: const <Locale>[
@@ -146,9 +150,7 @@ void main() async {
 
   if (kReleaseMode) {
     // Only use sentry in production
-    await SentryFlutter.init((
-      SentryFlutterOptions options,
-    ) {
+    await SentryFlutter.init((SentryFlutterOptions options,) {
       options.tracesSampleRate = 1.0;
       options.reportPackages = false;
       // options.addInAppInclude('sentry_flutter_example');
@@ -195,7 +197,7 @@ class AppIntro extends StatefulWidget {
 
 class _AppIntro extends State<AppIntro> {
   final GlobalKey<IntroductionScreenState> introKey =
-      GlobalKey<IntroductionScreenState>();
+  GlobalKey<IntroductionScreenState>();
 
   void _onIntroEnd(BuildContext context, AppCubit cubit) {
     cubit.introViewed();
@@ -209,40 +211,43 @@ class _AppIntro extends State<AppIntro> {
   Widget build(BuildContext context) {
     return BlocBuilder<AppCubit, AppState>(
         builder: (BuildContext buildContext, AppState state) {
-      final AppCubit cubit = context.read<AppCubit>();
-      return IntroductionScreen(
-        key: introKey,
-        pages: <PageViewModel>[
-          for (int i = 1; i <= 5; i++)
-            createPageViewModel('intro_${i}_title', 'intro_${i}_description',
-                'assets/img/undraw_intro_$i.png', context),
-        ],
-        onDone: () => _onIntroEnd(buildContext, cubit),
-        showSkipButton: true,
-        skipOrBackFlex: 0,
-        onSkip: () => _onIntroEnd(buildContext, cubit),
-        nextFlex: 0,
-        skip: Text(tr('skip')),
-        next: const Icon(Icons.arrow_forward),
-        done: Text(tr('start'),
-            style: const TextStyle(fontWeight: FontWeight.w600)),
-        dotsDecorator: const DotsDecorator(
-          size: Size(10.0, 10.0),
-          color: Color(0xFFBDBDBD),
-          activeColor: Colors.blueAccent,
-          activeSize: Size(22.0, 10.0),
-          activeShape: RoundedRectangleBorder(
-            borderRadius: BorderRadius.all(Radius.circular(25.0)),
-          ),
-        ),
-      );
-    });
+          final AppCubit cubit = context.read<AppCubit>();
+          return IntroductionScreen(
+            key: introKey,
+            pages: <PageViewModel>[
+              for (int i = 1; i <= 5; i++)
+                createPageViewModel(
+                    'intro_${i}_title', 'intro_${i}_description',
+                    'assets/img/undraw_intro_$i.png', context),
+            ],
+            onDone: () => _onIntroEnd(buildContext, cubit),
+            showSkipButton: true,
+            skipOrBackFlex: 0,
+            onSkip: () => _onIntroEnd(buildContext, cubit),
+            nextFlex: 0,
+            skip: Text(tr('skip')),
+            next: const Icon(Icons.arrow_forward),
+            done: Text(tr('start'),
+                style: const TextStyle(fontWeight: FontWeight.w600)),
+            dotsDecorator: const DotsDecorator(
+              size: Size(10.0, 10.0),
+              color: Color(0xFFBDBDBD),
+              activeColor: Colors.blueAccent,
+              activeSize: Size(22.0, 10.0),
+              activeShape: RoundedRectangleBorder(
+                borderRadius: BorderRadius.all(Radius.circular(25.0)),
+              ),
+            ),
+          );
+        });
   }
 }
 
-PageViewModel createPageViewModel(
-    String title, String body, String imageAsset, BuildContext context) {
-  final ColorScheme colorScheme = Theme.of(context).colorScheme;
+PageViewModel createPageViewModel(String title, String body, String imageAsset,
+    BuildContext context) {
+  final ColorScheme colorScheme = Theme
+      .of(context)
+      .colorScheme;
   final TextStyle titleStyle = TextStyle(
     color: colorScheme.primary,
     fontWeight: FontWeight.bold,
@@ -270,7 +275,7 @@ class GinkgoApp extends StatefulWidget {
 
   // The navigator key is necessary to navigate using static methods
   static final GlobalKey<NavigatorState> navigatorKey =
-      GlobalKey<NavigatorState>();
+  GlobalKey<NavigatorState>();
 
   @override
   State<GinkgoApp> createState() => _GinkgoAppState();
@@ -286,10 +291,16 @@ class _GinkgoAppState extends State<GinkgoApp> {
   }
 
   void _printNodeStatus({String prefix = 'Starting'}) {
-    final int nDuniterNodes = NodeManager().nodeList(NodeType.duniter).length;
+    final int nDuniterNodes = NodeManager()
+        .nodeList(NodeType.duniter)
+        .length;
     final int nCesiumPlusNodes =
-        NodeManager().nodeList(NodeType.cesiumPlus).length;
-    final int nGvaNodes = NodeManager().nodeList(NodeType.gva).length;
+        NodeManager()
+            .nodeList(NodeType.cesiumPlus)
+            .length;
+    final int nGvaNodes = NodeManager()
+        .nodeList(NodeType.gva)
+        .length;
     logger(
         '$prefix with $nDuniterNodes duniter nodes, $nCesiumPlusNodes c+ nodes, and $nGvaNodes gva nodes');
     if (!kReleaseMode) {
@@ -303,12 +314,13 @@ class _GinkgoAppState extends State<GinkgoApp> {
   @override
   void initState() {
     super.initState();
+    _initDeepLinkListener();
     NodeManager().loadFromCubit(context.read<NodeListCubit>());
     // Only after at least the action method is set, the notification events are delivered
     NotificationController.startListeningNotificationEvents();
     Once.runHourly('load_nodes', callback: () async {
       final bool isConnected =
-          await ConnectivityWidgetWrapperWrapper.isConnected;
+      await ConnectivityWidgetWrapperWrapper.isConnected;
       if (isConnected) {
         logger('Load nodes via once');
         _loadNodes();
@@ -323,7 +335,10 @@ class _GinkgoAppState extends State<GinkgoApp> {
     Once.runDaily('clear_cache', callback: () {
       logger('clear cache via once');
       ContactsCache().clear();
-      ContactsCache().addContacts(context.read<ContactsCubit>().state.contacts);
+      ContactsCache().addContacts(context
+          .read<ContactsCubit>()
+          .state
+          .contacts);
     });
     Once.runOnce('resize_avatars', callback: () {
       logger('resize avatar via once');
@@ -334,101 +349,146 @@ class _GinkgoAppState extends State<GinkgoApp> {
   @override
   void dispose() {
     ContactsCache().dispose();
+    _disposeDeepLinkListener();
     super.dispose();
   }
 
+  late StreamSubscription<dynamic>? _sub;
+
+  Future<void> _initDeepLinkListener() async {
+    _sub = linkStream.listen((String? link) async {
+      if (!mounted) {
+        return;
+      }
+      if (link != null) {
+        logger('got link: $link');
+        if (parseScannedUri(link) != null) {
+          showDialog(
+            context: context,
+            builder: (BuildContext context) {
+              return
+                PayContactSearchPage(uri: link);
+            },
+          );
+        }
+      }
+    }, onError: (Object err) {
+      if (!mounted) {
+        return;
+      }
+      logger('got err: $err');
+    });
+  }
+
+  void _disposeDeepLinkListener() {
+    if (_sub != null) {
+      _sub!.cancel();
+      _sub = null;
+    }
+  }
+
   @override
   Widget build(BuildContext context) {
     return BlocBuilder<NodeListCubit, NodeListState>(
         builder: (BuildContext nodeContext, NodeListState state) {
-      return ConnectivityAppWrapper(
-          app: FilesystemPickerDefaultOptions(
-              fileTileSelectMode: FileTileSelectMode.wholeTile,
-              theme: FilesystemPickerTheme(
-                topBar: FilesystemPickerTopBarThemeData(
-                  backgroundColor: Theme.of(context).colorScheme.primary,
-                ),
-              ),
-              child: MaterialApp(
-                /// Localization is not available for the title.
-                title: 'Äž1nkgo',
-                theme: ThemeData(
-                    useMaterial3: true, colorScheme: lightColorScheme),
-                darkTheme:
+          return ConnectivityAppWrapper(
+              app: FilesystemPickerDefaultOptions(
+                  fileTileSelectMode: FileTileSelectMode.wholeTile,
+                  theme: FilesystemPickerTheme(
+                    topBar: FilesystemPickerTopBarThemeData(
+                      backgroundColor: Theme
+                          .of(context)
+                          .colorScheme
+                          .primary,
+                    ),
+                  ),
+                  child: MaterialApp(
+
+                    /// Localization is not available for the title.
+                    title: 'Äž1nkgo',
+                    theme: ThemeData(
+                        useMaterial3: true, colorScheme: lightColorScheme),
+                    darkTheme:
                     ThemeData(useMaterial3: true, colorScheme: darkColorScheme),
 
-                navigatorKey: GinkgoApp.navigatorKey,
-                scaffoldMessengerKey: globalMessengerKey,
-
-                /// Theme stuff
-                themeMode: context.watch<ThemeCubit>().state.themeMode,
-
-                /// Localization stuff
-                localizationsDelegates: context.localizationDelegates,
-                supportedLocales: context.supportedLocales,
-                locale: context.locale,
-                debugShowCheckedModeBanner: false,
-                home: context.read<AppCubit>().isIntroViewed
-                    ? BetterFeedback(
+                    navigatorKey: GinkgoApp.navigatorKey,
+                    scaffoldMessengerKey: globalMessengerKey,
+
+                    /// Theme stuff
+                    themeMode: context
+                        .watch<ThemeCubit>()
+                        .state
+                        .themeMode,
+
+                    /// Localization stuff
+                    localizationsDelegates: context.localizationDelegates,
+                    supportedLocales: context.supportedLocales,
+                    locale: context.locale,
+                    debugShowCheckedModeBanner: false,
+                    home: context
+                        .read<AppCubit>()
+                        .isIntroViewed
+                        ? BetterFeedback(
                         localizationsDelegates: context.localizationDelegates
                           ..add(CustomFeedbackLocalizationsDelegate()),
                         child: const SkeletonScreen())
-                    : const AppIntro(),
-                builder: (BuildContext buildContext, Widget? widget) {
-                  NotificationController.locale = context.locale;
-                  return ResponsiveWrapper.builder(
-                    BouncingScrollWrapper.builder(
-                        context,
-                        ConnectivityWidgetWrapperWrapper(
-                          //message: tr('offline'),
-                          //height: 18,
-
-                          offlineWidget: /* Container(
+                        : const AppIntro(),
+                    builder: (BuildContext buildContext, Widget? widget) {
+                      NotificationController.locale = context.locale;
+                      return ResponsiveWrapper.builder(
+                        BouncingScrollWrapper.builder(
+                            context,
+                            ConnectivityWidgetWrapperWrapper(
+                              //message: tr('offline'),
+                              //height: 18,
+
+                              offlineWidget: /* Container(
                                 color: Colors.transparent,
                                 child: Center(
                                   child: */
                               Column(
-                            mainAxisSize: MainAxisSize.min,
-                            children: <Widget>[
-                              const Icon(
-                                Icons.cloud_off,
-                                size: 48,
-                                color: Colors.grey,
-                              ),
-                              const SizedBox(height: 6),
-                              Container(
-                                  padding: const EdgeInsets.all(5.0),
-                                  decoration: const BoxDecoration(
+                                mainAxisSize: MainAxisSize.min,
+                                children: <Widget>[
+                                  const Icon(
+                                    Icons.cloud_off,
+                                    size: 48,
                                     color: Colors.grey,
-                                    borderRadius:
-                                        BorderRadius.all(Radius.circular(10.0)),
                                   ),
-                                  child: Text(
-                                    tr('offline'),
-                                    style: const TextStyle(
-                                      color: Colors.white,
-                                      decoration: TextDecoration.none,
-                                      fontSize: 14,
-                                    ),
-                                  )),
-                              const SizedBox(height: 110),
-                            ],
-                          ),
-
-                          child: widget!,
-                        )),
-                    maxWidth: 480,
-                    minWidth: 480,
-                    // defaultScale: true,
-                    breakpoints: <ResponsiveBreakpoint>[
-                      const ResponsiveBreakpoint.resize(200, name: MOBILE),
-                      const ResponsiveBreakpoint.resize(480, name: TABLET),
-                      const ResponsiveBreakpoint.resize(1000, name: DESKTOP),
-                    ],
-                    background: Container(color: const Color(0xFFF5F5F5)),
-                  );
-                },
-              )));
-    });
+                                  const SizedBox(height: 6),
+                                  Container(
+                                      padding: const EdgeInsets.all(5.0),
+                                      decoration: const BoxDecoration(
+                                        color: Colors.grey,
+                                        borderRadius:
+                                        BorderRadius.all(Radius.circular(10.0)),
+                                      ),
+                                      child: Text(
+                                        tr('offline'),
+                                        style: const TextStyle(
+                                          color: Colors.white,
+                                          decoration: TextDecoration.none,
+                                          fontSize: 14,
+                                        ),
+                                      )),
+                                  const SizedBox(height: 110),
+                                ],
+                              ),
+
+                              child: widget!,
+                            )),
+                        maxWidth: 480,
+                        minWidth: 480,
+                        // defaultScale: true,
+                        breakpoints: <ResponsiveBreakpoint>[
+                          const ResponsiveBreakpoint.resize(200, name: MOBILE),
+                          const ResponsiveBreakpoint.resize(480, name: TABLET),
+                          const ResponsiveBreakpoint.resize(
+                              1000, name: DESKTOP),
+                        ],
+                        background: Container(color: const Color(0xFFF5F5F5)),
+                      );
+                    },
+                  )));
+        });
   }
 }
diff --git a/pubspec.lock b/pubspec.lock
index 941c148acaef3a95c2ee6dbb334d73f1fa75b582..3669e3a1734f08d954e0a2f7ea523e044a0d457c 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1459,6 +1459,30 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.3.1"
+  uni_links:
+    dependency: "direct main"
+    description:
+      name: uni_links
+      sha256: "051098acfc9e26a9fde03b487bef5d3d228ca8f67693480c6f33fd4fbb8e2b6e"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.5.1"
+  uni_links_platform_interface:
+    dependency: transitive
+    description:
+      name: uni_links_platform_interface
+      sha256: "929cf1a71b59e3b7c2d8a2605a9cf7e0b125b13bc858e55083d88c62722d4507"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.0"
+  uni_links_web:
+    dependency: transitive
+    description:
+      name: uni_links_web
+      sha256: "7539db908e25f67de2438e33cc1020b30ab94e66720b5677ba6763b25f6394df"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.1.0"
   universal_html:
     dependency: "direct main"
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 5630d3ef211309b65c059c7ae7d5e4a818628a71..9e25e455e2ceac0c14f9e92c1e446336030c827f 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -92,6 +92,7 @@ dependencies:
   crypto: ^3.0.3
   flutter_nfc_kit: ^3.3.1
   ndef: ^0.3.1
+  uni_links: ^0.5.1
 
 dev_dependencies:
   flutter_test: