This guide will walk you through setting up Veramo on React Native (using expo). You should have a good understanding of React Native and have your environment set up correctly to build iOS and Android apps. Check out the React Native docs to learn more. NodeJS v14 or later is required to run Veramo.
You'll be creating a React Native application that is able to create and remember Decentralized Identifiers (DIDs) along with some keys associated with them and display them in a list.
Let's set up Veramo to run locally on the device and use
expo-sqlite to store data, identities, and keys. Our
identifier provider will be
did:ethr. Initially, we will set up the agent in the
most basic config and add more plugins for additional functionality as we go.
Right now we just want to create an identifier.
Bootstrap React Native
Use the Expo CLI bootstrap a new typescript project.
Then, we initialize a new project like so:
Ensure your project is building and running ok before continuing to next steps (
npm run android or
npm run ios).
In an ideal world we would install some dependencies, paste some sample code and start our app, but anyone who has
worked with a non-trivial react-native app probably already knows that we don't currently live in this ideal world.
Some libraries that we will be depending on make use of the node
crypto package, or the
crypto.subtle API of
browsers. These are not yet available to react-native/expo environments out of the box, so there is a bit of ceremony to
bundle everything properly.
Also, the metro bundler that react-native uses doesn't yet support the
cjs file extension (
see facebook/metro#535) which is used by some libraries in the stack, so
we have to configure these too.
metro.config.js file and make sure it looks like this:
Next, we start setting up the shims that will be required by our libraries.
Now edit your
babel.config.js file at your project root and add the
babel-plugin-rewrite-require to it, like so:
Next, we can start adding the shims to the top of our
App.tsx file. Read
about strong random values here.
Prerequisites are ready. We can now go on to create a Veramo agent.
Let's install Veramo Core and some plugins. As you may already have read, Veramo is a framework where almost all the functionality is provided by plugins. Depending on the constellation of plugins that you are using, your Veramo agent will be able to perform some functions or others.
In this case, we are creating a Veramo agent that can create a specific type of DID.
Veramo can work with many DID methods, and since it is modular and extensible you can also add support for other methods
that are not provided out of the box. But first let's work with a single type of DID,
Don't worry; we will walk through what each of these plugins does in the next section.
Create a setup file in
setup.ts and import the following dependencies:
Create an Infura project ID and a database encryption key:
Since we're in an expo app, we'll use
expo-sqlite as a database driver.
Next initialize our sqlite database using TypeORM:
Finally, create the agent and add plugins for Key, Identifiers, Resolution, Credentials and Storage.
What we have so far.
Let's take a moment to understand what's going on here.
We created an
agent object using the
createAgent method and an array of
These plugins provide some methods, which are then made available from the
For example, the
DIDManager plugin has a
While this plugin is in use, this function is available on the
agent object as
DIDManager needs to work with keys when creating DIDs, or when executing operations that update a DID
document. To do this, it calls
agent and asks for a
IKeyManager implementation. In our case, this is provided by
KeyManager plugin. This kind of pattern makes the framework very modular, allowing you to replace plugin
implementations to suit your needs, or to add other plugins that may not be available out of the box.
This is made for Typescript
createAgent method allows you to specify the plugin interfaces that you are using, by
the Intersection type between the
This is entirely optional, but it allows you to develop more easily by letting your IDE give you hints about the available method names and their parameters and return types.
We haven't found a good way of automatically
Basic User Interface
Awesome! That's a basic agent configured and ready to use. Let's try it out 🚀 Now that the agent has been created and configured with plugins, we can create some identifiers. For this, we will need some basic UI.
Veramo does not impose decisions on how you manage state in your app and will work alongside any existing
architecture like Redux or Mobx etc. For brevity, we use
useState in this example, but you can treat Veramo like you
would any async data source.
App.tsx, delete all the contents after the shims you setup earlier and then replace it with the following code:
Now, we can finally run the app to see some identifiers being created!
Once loaded hit the Create identifier button a few times, and you should see your identifiers being created!
Building for production
When you use
@veramo/data-store you will need to ensure that class names are not mangled during the minification step
of a release build. This is because it uses
typeorm which relies on class names to make decisions about database
To get around this issue, you can use one of the solutions from this thread:
When working with expo/react-native it is easy to get your working directory into a broken state. We found that the easiest way out is to clear all caches and start from scratch (keeping your source code, of course).
To do this we usually:
- stop the
- then clear some directories,
- restart the bundler without cache
- rebundle the app
your Veramo related code
Normally you will use a lot of
@veramo/* packages when working with Veramo. It is very common for these packages to
depend on each other, and/or on other common libraries.
For this reason, it is very important to keep these packages in sync in terms of versions.
Having different versions of these libraries running at the same time in your app will very easily lead to
non-deterministic behavior. The only compatibility matrix you can count on is all
@veramo/* packages at the same
In this guide we:
- set up a react-native application using
- did all the ceremony to make sure
cryptoworks for all the dependencies,
- created a very basic Veramo agent,
- used that agent to create some DIDs and show them in a basic UI.
did:ethr:goerli identifiers we created
are Decentralized Identifiers(DIDs) that use the
ethr DID method
and are anchored on the
goerli network. This means that when someone wants to resolve these DIDs, the resolver uses
that network to construct the corresponding DID documents. You may also have noticed that there was no transaction
involved in creating these DIDs. You can read more about how this works by going through
Check out the next section to see how to set up your Veramo agent to resolve these DIDs and others and obtain their DID Documents.