Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • dubp_rs
  • duniterV1Latest
  • hugo_RML16
  • implementLightnode
  • master
  • polkadart-stuff
  • provider-to-riverpod
  • refactorOnboardingSlideshow
  • scanNetwork
  • 0.0.0+10
  • 0.0.0+13
  • 0.0.0+3
  • 0.0.0+4
  • 0.0.0+5
  • 0.0.0+7
  • 0.0.0+8
  • 0.0.0+9
  • polkawallet-sdk-latest
  • v0.0.1+0
  • v0.0.1+22
  • v0.0.1+6
  • v0.0.10+25
  • v0.0.10+26
  • v0.0.10+27
  • v0.0.11+28
  • v0.0.11+30
  • v0.0.11+31
  • v0.0.11+32
  • v0.0.12+33
  • v0.0.12+34
  • v0.0.12+35
  • v0.0.12+36
  • v0.0.12+37
  • v0.0.12+38
  • v0.0.12+39
  • v0.0.13+40
  • v0.0.13+41
  • v0.0.13+42
  • v0.0.14+43
  • v0.0.14+44
  • v0.0.14+45
  • v0.0.14+46
  • v0.0.15+47
  • v0.0.15+48
  • v0.0.15+49
  • v0.0.15+50
  • v0.0.15+51
  • v0.0.2+5
  • v0.0.2+7
  • v0.0.6+2
  • v0.0.6+3
  • v0.0.6+5
  • v0.0.6+8
  • v0.0.7+1
  • v0.0.7+10
  • v0.0.7+4
  • v0.0.7+5
  • v0.0.7+6
  • v0.0.7+7
  • v0.0.7+8
  • v0.0.7+9
  • v0.0.8+0
  • v0.0.8+3
  • v0.0.8+6
  • v0.0.8+7
  • v0.0.8+9
  • v0.0.9+10
  • v0.0.9+11
  • v0.0.9+12
  • v0.0.9+13
  • v0.0.9+14
  • v0.0.9+15
  • v0.0.9+16
  • v0.0.9+17
  • v0.0.9+18
  • v0.0.9+19
  • v0.0.9+2
  • v0.0.9+20
  • v0.0.9+23
  • v0.0.9+24
  • v0.1.0+52
  • v0.1.0+53
  • v0.1.0+54
  • v0.1.0+56
  • v0.1.1+58
  • v0.1.10+81
  • v0.1.11+82
  • v0.1.12+83
  • v0.1.12+84
  • v0.1.13+85
  • v0.1.14+86
  • v0.1.15+87
  • v0.1.16+88
  • v0.1.17+89
  • v0.1.18+90
  • v0.1.19+91
  • v0.1.2+59
  • v0.1.20+92
  • v0.1.21+93
  • v0.1.21+94
  • v0.1.21+95
  • v0.1.21+96
  • v0.1.21+97
  • v0.1.21+98
  • v0.1.22+100
  • v0.1.22+99
  • v0.1.23+101
  • v0.1.24+102
  • v0.1.25+105
109 results

Target

Select target project
  • clients/gecko
  • Eloitor/gecko
  • scanlegentil/gecko
  • kapis/gecko
  • aya/gecko
  • BorisPAING/gecko
6 results
Select Git revision
  • dubp_rs
  • duniterV1Latest
  • hugo_RML16
  • implementLightnode
  • master
  • refactoWidgetInsteadMethods
  • refactorOnboardingSlideshow
  • scanNetwork
  • subscribesSplit
  • tmp
  • 0.0.0+10
  • 0.0.0+13
  • 0.0.0+3
  • 0.0.0+4
  • 0.0.0+5
  • 0.0.0+7
  • 0.0.0+8
  • 0.0.0+9
  • v0.0.1+0
  • v0.0.1+22
  • v0.0.1+6
  • v0.0.10+25
  • v0.0.10+26
  • v0.0.10+27
  • v0.0.11+28
  • v0.0.11+30
  • v0.0.11+31
  • v0.0.11+32
  • v0.0.12+33
  • v0.0.12+34
  • v0.0.2+5
  • v0.0.2+7
  • v0.0.6+2
  • v0.0.6+3
  • v0.0.6+5
  • v0.0.6+8
  • v0.0.7+1
  • v0.0.7+10
  • v0.0.7+4
  • v0.0.7+5
  • v0.0.7+6
  • v0.0.7+7
  • v0.0.7+8
  • v0.0.7+9
  • v0.0.8+0
  • v0.0.8+3
  • v0.0.8+6
  • v0.0.8+7
  • v0.0.8+9
  • v0.0.9+10
  • v0.0.9+11
  • v0.0.9+12
  • v0.0.9+13
  • v0.0.9+14
  • v0.0.9+15
  • v0.0.9+16
  • v0.0.9+17
  • v0.0.9+18
  • v0.0.9+19
  • v0.0.9+2
  • v0.0.9+20
  • v0.0.9+23
  • v0.0.9+24
63 results
Show changes
Commits on Source (836)
Showing
with 712 additions and 134 deletions
----------------------------------------------------------------
## Objectif
Migrer les providers hérités de `package:provider` vers **Riverpod 3**.
### Étapes automatiques
1. Pour chaque `ChangeNotifier`, créer un `Notifier` équivalent :
```dart
@riverpod
class Counter extends _$Counter {
@override
int build() => 0;
void increment() => state++;
}
```
2. Remplacer `context.watch<MyModel>()` par `ref.watch(counterProvider)`.
3. Supprimer l'import `provider.dart` dès qu'il n'est plus utilisé.
4. Supprimer le fichier de l'ancien provider deprecated à la fin de la migration
### Contraintes
* Ne jamais utiliser le codegen pour riverpod. Pas de @riverpod syntax. Jamais.
* Créer un nouveau fichier du même nom, mais dans ./lib/providers au lieu de ./lib/providers_deprecated
* Préférer `AsyncNotifier` lorsque l'état dépend d'appels asynchrones.
* Éviter les `StateProvider` persistants dans la logique métier.
* Bien séparer la logique métier dans des services du dossier ./lib/services, des providers. Les providers Riverpod ne doivent avoir QUE de la logique lié au state manager pure.
* Bien faire attention à changer tous les appels de l'ancien provider vers quelque chose de plus idiomatique Riverpod, optimisé, de sorte de ne jamais changer le comportement attendu.
## Rester Idiomatique avec Riverpod
### Inspiration des Providers Existants
**TOUJOURS** s'inspirer des patterns établis dans `lib/providers/providers.dart` :
#### 1. Providers de Service (Pattern Principal)
```dart
/// Provides the [d.WalletService] for managing wallets, safes, and cryptographic keys.
final walletServiceProvider = Provider<d.WalletService>((ref) {
return ref.watch(durtProvider).wallets;
});
```
**Principes à respecter :**
- Documentation claire en anglais avec triple slash `///`
- Typage explicite `Provider<ServiceType>`
- Utilisation de `ref.watch()` pour les dépendances
- Nommage consistant avec suffixe `Provider`
#### 2. FutureProvider pour Opérations Async
```dart
/// Provides the genesis blockchain time for transaction date calculations.
final genesisTimeProvider = FutureProvider<DateTime>((ref) async {
final storageService = ref.watch(storageServiceProvider);
return await storageService.getGenesisBlockchainTime();
});
```
**Utiliser quand :**
- Opération asynchrone unique
- Données cachées automatiquement
- Pas besoin de mutation d'état
#### 3. Structure et Organisation
**Hiérarchie des dépendances :**
1. `durtProvider` (racine)
2. Providers de services dérivés
3. Providers de données/état spécifiques
### Patterns Interdits
❌ **NE PAS créer de providers redondants**
```dart
// MAUVAIS - déjà couvert par walletServiceProvider
final walletsProvider = Provider((ref) => ref.watch(durtProvider).wallets);
```
❌ **NE PAS ignorer les providers existants**
```dart
// MAUVAIS - utiliser storageServiceProvider à la place
final myStorageProvider = Provider((ref) => d.Durt.i.storage);
```
### Patterns Recommandés
✅ **Réutiliser les providers de base**
```dart
@riverpod
class WalletBalance extends _$WalletBalance {
@override
FutureOr<double> build(String walletId) async {
final storage = ref.watch(storageServiceProvider);
return await storage.getBalance(walletId);
}
}
```
✅ **Composer avec les services existants**
```dart
@riverpod
Future<bool> isIdentityValid(IsIdentityValidRef ref, String identity) async {
final squid = ref.watch(squidServiceProvider);
final utils = ref.watch(utilsProvider);
// Logic combining multiple services
return await squid.checkIdentity(identity) && utils.validateFormat(identity);
}
```
### Migration Checklist
Avant de créer un nouveau provider :
1. ✅ Vérifier si un provider existant couvre le besoin
2. ✅ S'assurer de la cohérence avec `providers.dart`
3. ✅ Utiliser `riverpod_generator` (`@riverpod`)
4. ✅ Documentation en anglais
5. ✅ Typage explicite
6. ✅ Tests des dépendances avec `ref.watch()`
### Types de Providers par Cas d'Usage
| Cas d'Usage | Provider Type | Exemple |
|-------------|---------------|---------|
| Service statique | `Provider<T>` | `walletServiceProvider` |
| Données async cachées | `FutureProvider<T>` | `genesisTimeProvider` |
| État mutable simple | `@riverpod class extends Notifier` | Compteurs, flags |
| État async mutable | `@riverpod class extends AsyncNotifier` | Listes, données API |
| Données paramétrées | `@riverpod FutureOr<T> myProvider(Ref ref, String param)` | Balance par wallet |
### Exemple Complet de Migration
**Avant (Provider legacy) :**
```dart
class WalletNotifier extends ChangeNotifier {
List<Wallet> _wallets = [];
List<Wallet> get wallets => _wallets;
Future<void> loadWallets() async {
_wallets = await WalletService.getAll();
notifyListeners();
}
}
```
**Après (Riverpod idiomatique) :**
```dart
@riverpod
class WalletList extends _$WalletList {
@override
FutureOr<List<Wallet>> build() async {
final walletService = ref.watch(walletServiceProvider);
return await walletService.getAll();
}
Future<void> refresh() async {
state = const AsyncLoading();
state = await AsyncValue.guard(() async {
final walletService = ref.read(walletServiceProvider);
return await walletService.getAll();
});
}
}
```
!.env.example
# iOS Build Configuration
## Deprecated
APPLE_ID=your.email@example.com
APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx
BUNDLE_ID=com.example.gecko
TEAM_ID=XXXXXXXXXX
## iOS New way
APP_STORE_CONNECT_API_KEY_PATH=/path/to/your/key.p8
APP_STORE_CONNECT_API_KEY_ID=YOUR_KEY_ID
APP_STORE_CONNECT_API_ISSUER_ID=YOUR_ISSUER_ID
IOS_APP_IDENTIFIER=fr.axiom-team.gecko
APP_STORE_RELEASE_STATUS=auto # auto, manual, or hold
# Android Google Play Store Configuration
GOOGLE_PLAY_JSON_KEY_PATH=path/to/your/google-play-service-account.json
ANDROID_PACKAGE_NAME=fr.axiomteam.gecko
GOOGLE_PLAY_TRACK=production
GOOGLE_PLAY_RELEASE_STATUS=completed
# Optional: You can also pass changelog as command argument:
# ./scripts/deploy-android.sh --changelog "Bug fixes and improvements"
{
"flutterSdkVersion": "3.32.7"
}
\ No newline at end of file
3.32.7
\ No newline at end of file
3.32.7
\ No newline at end of file
{
"flutter": "3.32.7"
}
\ No newline at end of file
......@@ -15,9 +15,6 @@
*.iws
.idea/
# VS Code related
.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
......@@ -40,6 +37,7 @@ app.*.map.json
# Android related
android/key.properties
android/gecko-*.json
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
......@@ -47,11 +45,164 @@ android/key.properties
# Rust things
/target
# Linux builds
linux/
# Custom
scripts/private/
AppDir/
appimage-builder-cache/
AppImageBuilder.yml
integration_test/duniter/data/chains/
# Ignore PC deps
scripts/pushGecko
android-old
# Environment variables
.env
# Helios related
/ios/Flutter/Helios.xcconfig
/ios/Helios.xcconfig
/ios/Runner/GoogleService-Info.plist
goldensExports
/test/**/failures
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# Visual Studio Code related
.classpath
.project
.settings/
.ccls-cache
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
**/generated_plugin_registrant.dart
.packages
.packages.generated
.pub-preload-cache/
.pub-cache/
.pub/
/build/
flutter_*.png
linked_*.ds
unlinked.ds
unlinked_spec.ds
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android related
**/android/**/gradle-wrapper.jar
.gradle/
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/**/GeneratedPluginRegistrant.java
**/android/key.properties
*.jks
local.properties
**/.cxx/
/android/app/debug
/android/app/profile
/android/app/release
# android build folder
android/app/build/*
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/.last_build_id
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Flutter.podspec
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/ephemeral
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
/ios/build
/ios/Podfile.lock
# macOS
**/Flutter/ephemeral/
**/Pods/
**/macos/Flutter/GeneratedPluginRegistrant.swift
**/macos/Flutter/ephemeral
**/xcuserdata/
# Windows
**/windows/flutter/ephemeral/
**/windows/flutter/generated_plugin_registrant.cc
**/windows/flutter/generated_plugin_registrant.h
**/windows/flutter/generated_plugins.cmake
# Linux
**/linux/flutter/ephemeral/
**/linux/flutter/generated_plugin_registrant.cc
**/linux/flutter/generated_plugin_registrant.h
**/linux/flutter/generated_plugins.cmake
# Coverage
coverage/
# zsh
.autoenv*
# FVM Version Cache
.fvm/flutter_sdk/
.fvm/versions/
# Exceptions to above rules
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
!/dev/ci/**/Gemfile.lock
# Tests related
integration_test/screenshots/
.fvm/flutter_sdk
......@@ -5,9 +5,9 @@ stages:
- package
.env:
image: axiomteam/gecko-ci:v0.0.8
image: ghcr.io/cirruslabs/flutter:3.24.3
tags:
- redshift
- docker
format:
extends: .env
......@@ -17,6 +17,8 @@ format:
- if: $CI_COMMIT_TAG || $CI_MERGE_REQUEST_ID
- when: manual
stage: format
script:
- dart format --set-exit-if-changed lib
build_and_test:
extends: .env
......@@ -26,29 +28,11 @@ build_and_test:
- if: $CI_COMMIT_TAG || $CI_MERGE_REQUEST_ID
- when: manual
stage: build_and_test
tags:
- redshift
script:
- flutter clean
- rm -rf /root/.pub-cache
- flutter pub get
- flutter analyze
# - flutter test
lint:
extends: .env
rules:
- if: $CI_COMMIT_REF_NAME =~ /^wip*$/
when: manual
- if: $CI_COMMIT_TAG || $CI_MERGE_REQUEST_ID
- when: manual
stage: quality
audit_dependencies:
extends: .env
rules:
- if: $CI_COMMIT_REF_NAME =~ /^wip*$/
when: manual
- if: $CI_COMMIT_TAG || $CI_MERGE_REQUEST_ID
- when: manual
stage: quality
releases:test:
extends: .env
......
......@@ -4,7 +4,27 @@
# This file should be version controlled and should not be manually edited.
version:
revision: 1aafb3a8b9b0c36241c5f5b34ee914770f015818
channel: stable
revision: "6fba2447e95c451518584c35e25f5433f14d888c"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 6fba2447e95c451518584c35e25f5433f14d888c
base_revision: 6fba2447e95c451518584c35e25f5433f14d888c
- platform: ios
create_revision: 6fba2447e95c451518584c35e25f5433f14d888c
base_revision: 6fba2447e95c451518584c35e25f5433f14d888c
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
{
"version": "0.2.0",
"configurations": [
{
"name": "Flutter (Debug)",
"type": "dart",
"request": "launch",
"program": "lib/main.dart",
"args": ["--no-enable-impeller"],
"flutterMode": "debug"
},
{
"name": "Flutter (Profile)",
"type": "dart",
"request": "launch",
"program": "lib/main.dart",
"args": ["--no-enable-impeller"],
"flutterMode": "profile"
},
{
"name": "Flutter (Release)",
"type": "dart",
"request": "launch",
"program": "lib/main.dart",
"flutterMode": "release"
}
],
"compounds": []
}
\ No newline at end of file
{
"dart.flutterSdkPath": ".fvm/versions/3.32.7"
}
\ No newline at end of file
# Ğecko
Ğecko is a transaction client owned by [Axiom-Team association] and written in Dart. It is fast and secure thanks to native code compilation. It is not intended to manage member accounts, but rather simple wallets.
Ğecko is mobile client for Duniter v2s blockchain (Ḡ1v2): https://duniter.org/blog/duniter-substrate<br>
It use polkawallet_sdk package to interact with Duniter: https://github.com/polkawallet-io/sdk
The development is quite early, you can participate in the discussion [on the Duniter forum](https://forum.duniter.org/t/gecko-nouveau-client-de-paiements-1-sur-mobile-en-cours-de-developpement-dart-flutter/7857) (mostly FR)
This application is maintained by [Axiom-Team association](https://axiom-team.fr/).
[Axiom-Team association]: https://axiom-team.fr/
You can download the last version of the app [here](https://forum.duniter.org/t/gecko-gdev-last-build/9367/last).<br>
You can ask questions about Ḡecko developpement in our [Duniter forum](https://forum.duniter.org/t/gecko-talks-user-support/9372/last).
## Getting Started
<div align="center">
![Demo Gif](https://git.p2p.legal/axiom-team/gecko/raw/branch/master/assets/Demo-0.0.1+0.gif)
![Demo Gif](https://git.duniter.org/clients/gecko/-/raw/master/images/demo-0.0.9+2.gif)
<br><br>
![Foo](https://git.p2p.legal/axiom-team/gecko/raw/commit/1cd2d63fe02949edabb69aa5fc498512c01db416/images/art/bb_gecko.png)
</div>
## Develop
To contribute to the code, we advise you to install the following development environment.
To contribute to the code, we advise you to install the following development environment:
1. [Android Studio](https://developer.android.com/studio/install)
2. [Flutter](https://docs.flutter.dev/get-started/install)
3. [VSCode](https://code.visualstudio.com/docs/setup/linux) or [VSCodium](https://vscodium.com/)
1. Android Studio
- Android VM
- Android NDK
1. Flutter SDK
1. VSCode/Codium Flutter extension
This will take about 12GB on your drive and 20 min of your time (with a good connection). Don't
hesitate to ask on the forum for a peer-coding session if you are stuck.
This will take about 12GB on your drive and 30 min of your time (with a good connection). Don't hesitate to ask on the forum for a peer-coding session if you are stuck.
At the end, `flutter doctor` command should be OK for what you need.
### Android Studio
Android Studio will let you set up an Android VM and install tools you need.
- Install [Android Studio](https://developer.android.com/studio/) using your favorite installation method.
- Install [Android Studio](https://developer.android.com/studio/) using your favorite installation
method.
- At startup, do not open a project but click "configure" at the bottom of the "Welcome" menu
- In "SDK Manager"
- SDK Platforms Ttab
- note your SDK folder location (later used for Rust environment variables)
- select Android 11 (R) API level 30 (default)
- SDK Tools
- select NDK (native development kit used to compile Rust to native target)
- SDK Platforms tab
- select Android 11 (R) API level 30 (default) or higher
- In "AVD Manager"
- create a virtual machine (ours is Pixel 4 32bits machine)
- launch it in the emulator
- create a virtual machine
If you reach this point without trouble, you're good to go for the next step.
### iOS (Xcode on Mac)
TODO: documentation
### Flutter SDK
Flutter is a powerfull SDK to develop Android apps. [Install it](https://flutter.dev/docs/get-started/install/linux) with your favorite installation method.
Flutter is a powerfull SDK to develop Android
apps. [Install it](https://flutter.dev/docs/get-started/install/linux) with your favorite
installation method.
### VSCode
We are using VSCode and therefore document the process for this IDE. Of course you're free to use whatever you want.
Clone the ğecko repo and open a dart file (e.g. `lib/main.dart`). VSCode will suggest you to insall relevant extensions.
We are using VSCode and therefore document the process for this IDE. Of course you're free to use
whatever you want.
Clone the ğecko repo and open a dart file (e.g. `lib/main.dart`). VSCode will suggest you to insall
relevant extensions.
### Build the app
### Launch the app in debug mode
In a dart file (e.g. `lib/main.dart`), type the `F5` key to build the code. The app should open automatically in your VM which is running.
Start a VM, then open a dart file (e.g. `lib/main.dart`), type the `F5` key to build the code. The app should open
automatically in your VM which is running.
### Build your app for Desktop
### Build APK
#### Linux
You will need to generate PlayStore key or disable signing APK before continue.
Then, check this script and launch it:
Install dependancies:
```
./scripts/build-apk.sh
```
### Integration tests
`sudo apt-get install clang cmake ninja-build pkg-config libgtk-3-dev`
Open an android or iOS emulator, then launch this script:
Then build debug for linux:
```
./integration_test/launch_test.sh
```
`flutter run -d linux`
It will start the [default test scenario](https://git.duniter.org/clients/gecko/-/blob/master/integration_test/scenarios/gecko_complete.dart).
If you get this error:
You can start another scenario defined [here](https://git.duniter.org/clients/gecko/-/tree/master/integration_test/scenarios) specifying the name of the file without its extension, for example to run migrate_cesium_identity.dart test:
```
flutter /usr/share/cmake-3.16/Modules/FindPkgConfig.cmake:643 (_pkg_check_modules_internal)
./integration_test/launch_test.sh migrate_cesium_identity
```
Please try:
`sudo apt install liblzma-dev`
then
`flutter clean && flutter run -d linux`
## Roadmap
- v0.1.0 (expected date: 21-08-16)
- Reorganization of persistent data
- Complete implementation of Figma model (made by Boris)
- Account management (creation, security)
- Payment (QR-code generation / reading, form)
- Viewing transaction history
- Finalization of integration tests and unit tests
- Completing the network scan when starting the application
- F-Droid publication
- v1.0
- Multi-vault management
- Cesium import
- Advanced search
- Item basket management
- Transaction monitoring
- Contacts / Messaging
- IOS compatibility
- Sharding (sharing of key fragments)
- Apple AppStore and Google PlayStore publication
- Mock-up and UX design of future functionalities
- v2.0
- Opaque bypass
- NFC payment
- Desktop compatibility
- Web of trust management (certifications, promises of certifications)
- Calendar / community
### A problem ?
Please open an issue here: https://git.duniter.org/clients/gecko/-/boards
# Wallet Interaction Migration Guide
This guide explains how to migrate from the old `WalletsProfilesProvider` to the new Riverpod-based providers and services.
## Overview
The old `WalletsProfilesProvider` has been split into multiple specialized services and providers following Riverpod best practices:
### New Services (in `lib/services/`)
- **`QrScannerService`** - Handles QR code scanning with permissions and validation
- **`ContactService`** - Manages contact operations (add/remove/check)
- **`IdenticonService`** - Generates SVG identicons for avatars
- **`SnackbarService`** - Provides consistent snackbar styling and behavior
### New Providers (in `lib/providers/wallet_interaction_providers.dart`)
- **`walletInteractionProvider`** - State management for payment forms and comments
- **`payAmountControllerProvider`** - TextEditingController for payment amounts
- **`payCommentControllerProvider`** - TextEditingController for payment comments
- **`qrScanProvider`** - QR scanning functionality
- **`identiconProvider`** - Identicon generation
- **`isContactProvider`** - Check if address is a contact
- **`toggleContactProvider`** - Add/remove contacts
- **`copyAddressProvider`** - Copy address with snackbar
- **`copyMnemonicProvider`** - Copy mnemonic with snackbar
- **`showSnackbarProvider`** - General snackbar messages
## Migration Examples
### 1. State Management
**Before:**
```dart
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
late WalletsProfilesProvider walletsProvider;
@override
void initState() {
super.initState();
walletsProvider = WalletsProfilesProvider('someAddress');
}
@override
Widget build(BuildContext context) {
return TextField(
controller: walletsProvider.payAmount,
onChanged: (value) => walletsProvider.notifyListeners(),
);
}
}
```
**After:**
```dart
class MyWidget extends ConsumerWidget {
final String? address;
const MyWidget({this.address});
@override
Widget build(BuildContext context, WidgetRef ref) {
final payAmountController = ref.watch(payAmountControllerProvider(address));
final interaction = ref.watch(walletInteractionProvider(address));
return TextField(
controller: payAmountController,
// State automatically syncs - no manual notifyListeners needed
);
}
}
```
### 2. QR Code Scanning
**Before:**
```dart
walletsProvider.scan(context);
```
**After:**
```dart
final scanQr = ref.read(qrScanProvider);
await scanQr(context);
```
### 3. Contact Management
**Before:**
```dart
await walletsProvider.addContact(profile);
```
**After:**
```dart
final toggleContact = ref.read(toggleContactProvider);
await toggleContact(profile, context);
```
### 4. Identicon Generation
**Before:**
```dart
final svg = walletsProvider.generateIdenticon(pubkey);
```
**After:**
```dart
final svg = ref.watch(identiconProvider(pubkey));
```
### 5. Contact Check
**Before:**
```dart
final isContact = walletsProvider.isContact(address);
```
**After:**
```dart
final isContact = ref.watch(isContactProvider(address));
```
### 6. Snackbar Messages
**Before:**
```dart
snackMessage(context, message: 'Hello World');
snackCopyKey(context);
snackCopySeed(context);
```
**After:**
```dart
final showSnackbar = ref.read(showSnackbarProvider);
showSnackbar(context, 'Hello World');
final copyAddress = ref.read(copyAddressProvider);
copyAddress(context);
final copyMnemonic = ref.read(copyMnemonicProvider);
copyMnemonic(context);
```
### 7. Comment Visibility Toggle
**Before:**
```dart
walletsProvider.toggleCommentVisibility();
```
**After:**
```dart
ref.read(walletInteractionProvider(address).notifier).toggleCommentVisibility();
```
## Key Benefits
1. **Separation of Concerns**: Business logic separated into services
2. **Better Testability**: Services can be tested independently
3. **Reactive State**: Automatic UI updates when state changes
4. **Type Safety**: Better type safety with Riverpod
5. **Performance**: Automatic optimization and caching
6. **Family Providers**: Support for multiple wallet addresses simultaneously
## Utility Functions
The utility functions are now deprecated. Use the utils service directly:
**Before:**
```dart
bool valid = isAddress(address);
String ss58 = isAddressValidToSs58(address);
bool isPubkey = isPubkey(input);
```
**After:**
```dart
final utils = ref.read(utilsProvider);
bool valid = utils.isAddressValid(address);
String ss58 = utils.isAddressValidToSs58(address);
// Use the pubkey validation from QrScannerService if needed
```
## Notes
- The old `WalletsProfilesProvider` file is kept for backward compatibility but marked as deprecated
- All new code should use the new providers and services
- The migration maintains the same functionality while improving architecture
- State is automatically managed and persisted across widget rebuilds
\ No newline at end of file
......@@ -27,3 +27,6 @@ linter:
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
formatter:
page_width: 120
plugins {
id 'com.android.application'
id 'kotlin-android'
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
......@@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
......@@ -21,10 +22,6 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
......@@ -32,21 +29,30 @@ if (keystorePropertiesFile.exists()) {
}
android {
compileSdkVersion 31
namespace "fr.axiomteam.gecko"
compileSdk flutter.compileSdkVersion
ndkVersion "27.2.12479018" //flutter.ndkVersion
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '17'
}
lintOptions {
disable 'InvalidPackage'
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "gecko.axiomteam.fr"
minSdkVersion 19
targetSdkVersion 31
applicationId "fr.axiomteam.gecko"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
......@@ -65,18 +71,20 @@ android {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
useProguard true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
signingConfig signingConfigs.debug
debuggable true
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
dependencies {}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="gecko.axiomteam.fr">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="gecko.axiomteam.fr">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
......@@ -9,17 +8,21 @@
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- Biometric authentication permissions -->
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<application
android:enableOnBackInvokedCallback="true"
android:requestLegacyExternalStorage="true"
android:name="${applicationName}"
android:label="Ğecko"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true">
<!-- TODO: Remove usesCleartextTraffic for production mode ! kopa -->
<!-- android:icon="@mipmap/ic_launcher"> -->
<activity
android:requestLegacyExternalStorage="true"
android:name=".MainActivity"
android:resource="@style/NormalTheme"
android:icon="@mipmap/ic_launcher"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
......@@ -42,6 +45,10 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Ucrop.CropTheme"/>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
......
android/app/src/main/ic_launcher-playstore.png

50 KiB | W: 0px | H: 0px

android/app/src/main/ic_launcher-playstore.png

49.4 KiB | W: 0px | H: 0px

android/app/src/main/ic_launcher-playstore.png
android/app/src/main/ic_launcher-playstore.png
android/app/src/main/ic_launcher-playstore.png
android/app/src/main/ic_launcher-playstore.png
  • 2-up
  • Swipe
  • Onion skin
package gecko.axiomteam.fr
package fr.axiomteam.gecko
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity: FlutterActivity() {
class MainActivity: FlutterFragmentActivity() {
}