MCPcopy Index your code
hub / github.com/MinBZK/nl-wallet

github.com/MinBZK/nl-wallet @v0.5.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.5.0 ↗ · + Follow
7,665 symbols 24,695 edges 884 files 492 documented · 6%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

NL Wallet

NL Wallet is a secure app on your phone that lets you keep important personal information in one place, such as your name, age, or official documents like your ID card or driving licence. With the wallet, you can easily prove who you are, or show only the information a service needs.

For example: - Showing you are over 18 without sharing your full date of birth. - Confirming your identity when dealing with the government. - Sharing a digital version of a diploma when applying for a job.

This is useful, because: - You no longer need to upload scans of your passport. - You share only what is needed, not your whole identity. - Your documents are harder to fake, because they are digitally signed. - It works across all EU countries.

You stay in control: you choose what to share, with whom, and when.

NL Wallet is intended for Dutch nationals. It offers convenience, stronger security, and protection against identity fraud — all while giving individuals greater control over their own information.

The app is being developed by Rijksoverheid (Dutch Government), in particular the Ministry of the Interior and Kingdom Relations (MinBZK) and is expected to be available to the public in 2027.

NL Wallet also makes things easier and safer for relying parties, which are organisations that need to check identity or personal information.

For these organisations, this means: - More trust – the information comes directly from trusted sources, so it is harder to fake. - Less sensitive data to store – no need to keep copies of passports or other documents. - Easier compliance with privacy rules – only the necessary information is shared. - Faster and smoother processes – users can identify themselves quickly, with fewer steps. - European coverage – the same approach can be used in all EU countries.

This helps organisations to reduce fraud, protect personal data and offer a better experience to their users.

NL Wallet is being developed in an open and transparent way. We offer the following channels to allow you to contribute:

  • The user interface of the app is available on [Figma][3].
  • The source code is published in this [GitHub repository][4].
  • More information, events and discussions can be found on [Pleio][5].
  • Project documentation is available on [GitHub pages][25].

This documentation reflects the current implementation and will be updated with every software update.

Feel free to look around and share your [feedback and ideas][6].

Current release

See the [releases page][7] for the latest release. You can follow the latest work by subscribing to the releases of this GitHub repository at the top of this page.

Documentation

We have a dedicated [documentation site][25].

If you want to learn more about the NL Wallet development, please read the background information on the [Pleio][5] hub. The development of the user flows and screens can be followed through [Figma][3].

Licensing

The source code of the NL Wallet is released under the [EUPL license][8]. The documentation is released under the CC0 license. Please see the [.reuse/dep5][9] file for more details, which follows the [Reuse specification][10].

Contributing

We’re releasing the source code with the explicit intention of allowing contributions. The coordination of the project lies with the development team of the European Digital Identity Progam, but we’re open to all contributions. You can directly create a new Pull Request via Github, or contact the community manager via [edi@minbzk.nl][11].

The development team works on the repository in a private fork (for reasons of compliance with existing processes) and shares its work as often as possible. If you watch the repository on GitHub, you will be notified of a new release. We will also send a notification through Pleio.

Although we are open to contributions, please consider the nature of this project as outlined in this Readme. At this stage the most useful way to contribute to the project is to participate on our community site [edi.pleio.nl][5], and visit our [EDI Meet-ups and/or Heartbeats][12].

If you plan to make non-trivial changes, we recommend that you open an issue beforehand where we can discuss your planned changes. This increases the chance that we might be able to use your contribution (or it avoids doing work if there are reasons why we wouldn't be able to use it).

Note that all commits should be signed using a GPG key.

Getting started

This section contains the general setup requirements of the project. For more information on how to configure specific components like [wallet app][13], [wallet core][14], [wallet_web][15], and [wallet_provider][16], please see the corresponding README files.

The app's UI is built using Flutter, but to avoid tying the app to Flutter & Dart, all core business logic is built using Rust. This gives us the more flexibility to migrate to completely native iOS/Android apps if the need arises. This does mean building the app is slightly more complex than a simple flutter run. This section describes how to set up your environment.

System requirements

The various components of NL Wallet have different requirements. To make sure things run correctly, you need to take the following system requirements into account.

Mobile apps

Our mobile apps require at least the following operating system versions:

  • Android 10.0 (API-level 29)
  • iOS 15.0

The app does not put a particularly heavy load on the device, so CPU and memory requirements are low to average. Note that this is subject to change.

Wallet web

The wallet_web frontend helper library effectively runs in the browser of a person that wants to interact with a relying party that integrates with the NL Wallet platform. As such, wallet_web has requirements on the minimum browser version supported:

  • Firefox 60.9+
  • Chrome 109+
  • Edge 109+
  • Safari 13+

Note that the above are not recommendations, but simply a statement about the minimum version we have some confidence in running correctly. We always recommend that you run the latest stable browser your platform offers. Also note that the above is subject to change.

Backend services

We have various backend services, mostly built in Rust that make up the wallet platform. In general, we build binaries for glibc and musl Linux-based distributions. We've found that usually the musl binary will work on almost anything, but the glibc binary really requires a glibc-based distribution.

Operating systems we use and test our builds on
  • Alpine 3.x
  • Arch Linux (any current)
  • Debian 12+
  • RHEL 8+ (and derivatives)
Services we depend on
  • PostgreSQL 10+ (first version with jsonb support)
  • RDO-MAX v2.13.x+ (see [their repository][26] for details)
  • BrpProxy v2.1.x (see [their repository][27] for details)

Specifically for PostgreSQL you need to consider storage requirements. Our database-backed services are wallet_provider, verification_server, issuance_server, demo_issuer (usually not built for production environments) and pid_issuer. They have a very simple database layout. A good ballpark figure is to allocate 100GiB for a wallet_provider instance and 10GiB for instances of the verification_server, issuance_server or pid_issuer. Of course, these requirements will change with time and duration of usage, and are subject to change. Also note that these size requirements assume somewhat serious usage; for development purposes you can make do with a lot less.

Rust-based backend services
  • wallet_provider
  • verification_server
  • issuance_server
  • pid_issuer
  • demo_relying_party
  • demo_issuer
  • gba_hc_converter

The above Rust-based services require a regular Linux machine or container based on one of the aforementioned operating systems. Memory requirements of these services are very low (we're seeing 20 to 50 megabytes of usage on our Kubernetes clusters, but of course it depends on usage too). The storage requirements are effectively non-existent due to usage of PostgreSQL for state.

Additional supporting services (in addition to rust-based backend services)

The Wallet app needs several supporting services to run, and also requires the user to log in using DigiD in order to create the Wallet. The services are the following:

  • digid-connector (rdo-max)
  • static_server
  • gba_hc_converter
  • brpproxy
  • postgresql

All these applications will need to be configured correctly. A local development environment with automatic configuration of all the above services can be set up using the scripts/setup-devenv.sh and scripts/start-devenv.sh scripts, which we'll document later in this Readme.

Network connectivity

For end-users, an internet connection is required to use the disclosure and issuance features of the wallet app. For relying parties and issuers, who want to obtain disclosed attributes and issue attributes respectively, the same requirement holds.

Development requirements

To do development work on the NL reference wallet, you need to following tools:

  • Rust (including additional targets and utilities)
  • Android SDK + NDK (for Android builds)
  • Xcode (for iOS builds)
  • Flutter
  • Docker (to run supporting services)
  • PKCS #11 library

In the following sub-sections we will document how to install and configure these.

Rust

To install Rust and Cargo using rustup, follow the [installation guide][20]. After installation, make sure to add the following targets:

  • For iOS: rustup target add aarch64-apple-ios x86_64-apple-ios
  • For iOS simulator: rustup target add aarch64-apple-ios-sim
  • For Android: rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android

Make sure rustc, and cargo are on your path and run the following commands to install a few additional utilities we use:

cargo install --locked cargo-edit cargo-expand 'cargo-ndk@^4' cargo-nextest
cargo install --locked --version 2.11.1 flutter_rust_bridge_codegen
cargo install --locked --version 1.1.19 sea-orm-cli
cargo install --list

Android

To build for Android you need to have the Android SDK and NDK installed on your system. You can [download Android Studio here][21]. Note the install location and set the ANDROID_HOME environment variable to point to that installation location. The following is an example that assumes you installed Android Studio in /opt/android, sets the necessary variables, and adds certain Android-specific tools and utilities to your path:

export ANDROID_HOME="/opt/android"
export ANDROID_NDK_HOME="$(find "$ANDROID_HOME/ndk" -maxdepth 1 -type d | sort -V | tail -n1)"
export PATH="$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_NDK_HOME"

After having done the above, you will have tools like adb, sdkmanager, and ndk-build on your path.

With sdkmanager --list_installed you can list the installed Android SDK components. Now let's install some extra components we'll need:

# Install all needed packages. On intel/amd, x86_64 is
# fine, on arm64, use arm64-v8a for the system-image.
sdkmanager --install \
'build-tools;36.0.0' \
'cmdline-tools;latest' \
'emulator' \
'ndk;28.2.13676358' \
'platform-tools' \
'platforms;android-36' \
'sources;android-36' \
"system-images;android-36;google_apis_playstore;$(uname -m|sed s/arm64/arm64-v8a/)"

Note: The ndk version was the latest non-release-candidate version as of this writing (2025-08-28); If there is a newer stable version, feel free to use that. Same for the android version - it's 36 as of this writing, but newer might be available when you read this - feel free to use that too.

You will need to create an Android virtual device (AVD) so you can run the emulator. To do that, do the following:

  1. Start Android Studio, open or create any project;
  2. Click "File" pulldown menu, then "Tool Windows" -> "Device Manager";
  3. Click on "+", then "Create Virtual Device", select "Pixel 3"
  4. For "Name", choose something descriptive like "pixel3-x86_64-android16-api36"
  5. For "API", select latest available, like "API 36.0"
  6. For "Services", select "Google Play Store"
  7. For "System Image", choose whichever latest Google Play enabled image is available. For example: "Google Play System Image", "API 36.0"
  8. Click on the "Additional Settings" tab
  9. Set "Expanded Storage" to "Custom", "12", "GB"
  10. Set "RAM" to "4", "GB"
  11. Set "VM heap size" to "512", "MB"
  12. Click on the blue "Finish" button

When you run $ANDROID_HOME/emulator/emulator -list-avds on the command-line, you should see your just-created virtual device show up.

Xcode

  1. Install [Xcode][23]
  2. Follow the steps to install iOS simulators
  3. Start the simulator using open -a Simulator

Flutter

To install Flutter follow this [installation guide][17]. You can validate your initial setup by making sure flutter is on your path, and then running flutter doctor which will tell you if all is well with its dependencies. Make sure flutter doctor has no complaints or warnings; specifically, it needs to find the Android and/or Xcode related components (in the case of Android, it needs to find the SDK toolchain and Android Studio itself).

Manage your local Flutter version using FVM (optional)

FVM is a simple CLI to manage Flutter SDK versions per project. It enables fast switching between Flutter versions and pin them to your Flutter project. When using FVM; all Flutter related commands need to be prefixed with fvm, e.g. fvm flutter run.

To install FVM follow this [installation guide][18]. You can validate your initial setup by running fvm flutter doctor after installation. Select [Y]es when asked to install the pinned Flutter version defined in [fvm_config.json][19].

Note that FVM only pins the Flutter version for local development, not for the CI pipelines.

Docker

Make sure

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Method 3,043
Function 2,516
Class 1,446
Enum 520
Interface 140

Languages

Rust84%
Kotlin11%
C++2%
TypeScript2%
Python1%
Ruby1%

Modules by API surface

wallet_core/flutter_api/src/frb_generated.rs265 symbols
wallet_app/ios/Runner/frb_generated.h174 symbols
wallet_core/lib/openid4vc/src/openid4vp.rs95 symbols
wallet_core/wallet_provider/service/src/account_server.rs93 symbols
wallet_core/lib/openid4vc/src/verifier.rs93 symbols
wallet_core/wallet_provider/service/src/instructions.rs91 symbols
archive/mdoc-disclosure/mdoc/verifier.rs85 symbols
wallet_core/wallet/src/wallet/disclosure.rs73 symbols
wallet_core/lib/sd_jwt_vc_metadata/src/metadata.rs72 symbols
wallet_core/lib/openid4vc/src/issuance_session.rs70 symbols
wallet_core/wallet/src/storage/database_storage.rs67 symbols
wallet_core/flutter_api/src/api/full.rs66 symbols

Datastores touched

issuance_serverDatabase · 1 repos
verification_serverDatabase · 1 repos
wallet_providerDatabase · 1 repos
wallet_provider_audit_logDatabase · 1 repos
pid_issuerDatabase · 1 repos

For agents

$ claude mcp add nl-wallet \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page