User App Architecture

The documentation is compatible with UserApp v1.3.9 and will be updated and added to gradually.

How to run the App

The version of Flutter used for development: 3.10.2
(Make sure that the version installed on your PC is compatible with the one specified in the document)

The version of Dart used for development: 3.0.2
(Make sure that the version installed on your PC is compatible with the one specified in the document)

The project is compatible with the Back End version 1.2.12

If changes were made to the GraphQL scheme on the Back End side, you need:

  1. Delete the scheme (lib/infrastructure/scheme.graphql).

  2. Get a new one (get-graphql-schema ENDPOINT_URL > lib/infrastructure/schema.graphql). WARNING! The link must be in full format. Example: https://${ENDPOINT_URL}/graphql

  3. Run the build_runner (flutter pub run build_runner build).

App Structure

The application is built according to the principles of DDD architecture. We have a good separation into layers which brings beautiful features ease of navigation and testing. The diagram below shows the division into layers and their purpose.

State management in the project is implemented by Riverpod + Flutter Hooks This allows us to easily access data even in such a large project, and with the help of hooks we have almost abandoned the Stateful widget.

Application

At the Application level, we store providers and actions. Since web, mobile and tablet applications are managed in one project, all events are unified and stored in the actions folder. This allows you to minimize efforts to support the project and guarantees the same execution on devices of different types and OS.

Domain

Entities, DTOs, etc. are stored at the Domain level.

Infrastructure

Infrastructure layer includes repository, GraphQL. Repository layer is responsible for implementation for repository interface (* Repository layer is added between the domain and data mapping layers to isolate domain objects from details of the database access code and to minimize scattering and duplication of query code.). The layer is divided into feature oriented services in which interfaces are implemented. GraphQL is a very important part of the project. Since the application interacts with the graphic Back End, the application uses ferry. You can learn more about this library on the official ferry page, but in short, the developer downloads the schema (schema.graphql), creates a request file (*.graphql file) and runs build_runner to generate additional files.

Presentation

This layer is all about Flutter, it contains widgets. Since the project is quite large and contains layouts for different platforms, the following scheme was chosen for convenience:

Below is an example of a widget division structure. Example for authorization: Auth

  • components (Elements common to all auth, but used only in auth, if they are used elsewhere in the project, should be moved to a higher level)

  • tablet (UI kit for Tablet layout)

  • web ((UI kit for Web layout)

  • mobile (UI kit for mobile layout)

    • components auth_button.dart element.dart another_element.dart

    • sign in

      • components sign_in.dart

    • sign up

      • components sign_up.dart

This is how the entire project is distributed. Initially, Presentation is divided into several main modules App, Auth, Exchange and Components (contains elements that are used throughout the project, that is, common to all). Auxiliary elements are also marked in Presentation: constants (contains a list of paths to assets, colors), helpers (various loaders, errors, validation forms, and other auxiliary elements are stored here). And also Controller. The task of the controller is to check whether the user must be authorized, as well as global navigation of the application.

Local Storage

The project uses Hive to store various data on the user's device. Primarily, the local database is used in the project to save critical data (see config.json) Also, the boxes store the date, which can be lost due to the loss of the state (not very pleasant features of Flutter web). The list of all boxes is indicated in the main.dart when registering hive adapters.

Assets

  • Fonts The application uses local fonts stored in assets/fonts WARNING: When changing fonts, replace/add to pubspec.yaml -> fonts

  • Icons/Images All graphic assets (*.png, *.jpg, *.svg etc.) are stored in assets/icons. The path to each asset is stored in constant variables in lib/presentation/constants/assets_path.dart WARNING: When removing/adding a new asset, add a new line to assets_path.dart, and do not write the full path to the asset in the widget.

Localization

For localization, the application uses the easy_localization library. Localization json is stored in assets/lang. To add a new locale, you need to create a new json and add the locale to the list of supported locales (lib/presentation/helpers/capitalize.dart -> List supportedLocales).

Config.json

This file is created to set project settings and activate/deactivate certain project modules. Below is a list of variables and an explanation of their use. url - link to the Back End (indicate only in an incomplete format, an incomplete link is sent to the service, because the link format is indicated there) terms_and_conditions_url - Link to Privacy Policy (must be specified in full format. http://link_to_your_policy) ramp_config - enable/disable Ramp support, ramp base config google_auth - enable/disable google authentication, base config header_config - enable/disable different app modules trading_enabled - enable/disable advanced trading module custodial_exchange_enabled - enable/disable Swap module non_custodial_exchange_enabled - enable/disable Non custodial exchange module pro_swap_enabled - enable/disable PRO Swap module non_custodial_wallet_connect - enable/disable WalletConnect in project (Only Web support)

The settings are set by default for development. When publishing to the server, DevOps must specify the value in the config file. Thanks to this solution, you can change the config without rebuilding the application.

Customisation.md

All customisations and changes that differentiate the custom version of the product from the master branch are listed here.

build.yaml

This configuration file so that build_runner knows which generators to run and where to find our GraphQL schema (watch ferry_generator).

analysis_options.yaml

Configuration file for linter. We are constantly working on the quality of the code, so we are constantly adding new rules to make the code more qualitative and productive.

.gitlab-ci.yml

Setting up CI/CD for Gitlab.

Dockerfile

Configuration file for building a docker image. IMPORTANT! If a different version of flutter will be used for development, you need to replace it here as well, so that there are no problems during deployment.

.gitignore

A list of files that should not be stored in the repository.