React Native Setup & Identifiers

This guide will walk you through setting up Veramo on React Native. 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. Node v12 or later is required to run Veramo.

Introduction

Let's setup Veramo to run locally on the device and use sqlite to store data, identities, and keys. Our identity provider will be ethr-did. 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 identifer.

Bootstrap React Native

Use the React Native CLI bootstrap a new typescript react project:

npx react-native init VeramoMobile --template react-native-template-typescript

Ensure your project is building and running ok before continuing to next step.

Install Dependencies

Native

We need to set up some native dependencies and shims that Veramo plugins will use for database and key management.

yarn add react-native-sodium react-native-sqlite-storage

To access node methods we need to install rn-nodeify to our dev dependencies.

yarn add rn-nodeify --dev

Add the following snippets to your package.json file

{
"scripts": {
...
"postinstall": "rn-nodeify --install assert,buffer,process,crypto,stream,vm --hack"
}
}

Import shim.js (created by rn-nodify) into the top of index.js.

import './shim'
...

Open shim.js and uncomment require('crypto)

// If using the crypto shim, uncomment the following line to ensure
// crypto is loaded first, so it can populate global.crypto
require('crypto')

Install all of the pods in your project that came with the new dependencies.

npx pod-install

Veramo

Now let's install Veramo Core and some plugins. Don't worry; we will walk through what each of these plugins does in the next section.

yarn add @veramo/core @veramo/did-manager @veramo/kms-local-react-native @veramo/did-provider-ethr @veramo/key-manager @veramo/did-resolver @veramo/data-store @veramo/credential-w3c ethr-did-resolver web-did-resolver

Close the react native packager, clean the project, and rerun your app. If everything is okay, you should see the default React Native screen as before.

Bootstrap Veramo

We bootstrap Veramo by creating a setup file and initializing the agent. Create a setup file in src/veramo/setup.ts and import the following dependencies:

// Core interfaces
import { createAgent, IDIDManager, IResolver, IDataStore, IKeyManager } from '@veramo/core'
// Core identity manager plugin
import { DIDManager } from '@veramo/did-manager'
// Ethr did identity provider
import { EthrDIDProvider } from '@veramo/did-provider-ethr'
// Core key manager plugin
import { KeyManager } from '@veramo/key-manager'
// Custom key management system for RN
import { KeyManagementSystem } from '@veramo/kms-local-react-native'
// Custom resolver
// Custom resolvers
import { DIDResolverPlugin } from '@veramo/did-resolver'
import { Resolver } from 'did-resolver'
import { getResolver as ethrDidResolver } from 'ethr-did-resolver'
import { getResolver as webDidResolver } from 'web-did-resolver'
// Storage plugin using TypeOrm
import { Entities, KeyStore, DIDStore, IDataStoreORM } from '@veramo/data-store'
// TypeORM is installed with '@veramo/data-store'
import { createConnection } from 'typeorm'

Create an infura variable:

// You will need to get a project ID from infura https://www.infura.io
const INFURA_PROJECT_ID = '<your PROJECT_ID here>'

Next initilize our sqlite database using TypeORM:

// Create react native db connection
const dbConnection = createConnection({
type: 'react-native',
database: 'veramo.sqlite',
location: 'default',
synchronize: true,
logging: ['error', 'info', 'warn'],
entities: Entities,
})

Finally, create the agent and add plugins for Key, Identity, Storage, and Resolver.

export const agent = createAgent<IDIDManager & IKeyManager & IDataStore & IDataStoreORM & IResolver>({
plugins: [
new KeyManager({
store: new KeyStore(dbConnection),
kms: {
local: new KeyManagementSystem(),
},
}),
new DIDManager({
store: new DIDStore(dbConnection),
defaultProvider: 'did:ethr:rinkeby',
providers: {
'did:ethr:rinkeby': new EthrDIDProvider({
defaultKms: 'local',
network: 'rinkeby',
rpcUrl: 'https://rinkeby.infura.io/v3/' + INFURA_PROJECT_ID,
gas: 1000001,
ttl: 60 * 60 * 24 * 30 * 12 + 1,
}),
},
}),
new DIDResolverPlugin({
resolver: new Resolver({
...ethrDidResolver({ infuraProjectId: INFURA_PROJECT_ID }),
...webDidResolver(),
}),
}),
],
})

Awesome! That's the basic agent configured and ready to use. Let's try it out ๐Ÿš€

Basic User Interface

Now that the agent has been created and configured with plugins, we can create some identifiers. For this, we will need some basic UI.

note

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.

Open App.tsx and delete all the contents and add the following code:

import React, { useEffect, useState } from 'react'
import { SafeAreaView, ScrollView, View, Text, Button } from 'react-native'
// Import agent from setup
import { agent } from './src/veramo/setup'
interface Identifier {
did: string
}
const App = () => {
const [identifiers, setIdentifiers] = useState<Identifier[]>([])
// Add the new identifier to state
const createIdentifier = async () => {
const _id = await agent.didManagerCreate()
setIdentifiers((s) => s.concat([_id]))
}
// Check for existing identifers on load and set them to state
useEffect(() => {
const getIdentifiers = async () => {
const _ids = await agent.didManagerFind()
setIdentifiers(_ids)
// Inspect the id object in your debug tool
console.log('_ids:', _ids)
}
getIdentifiers()
}, [])
return (
<SafeAreaView>
<ScrollView>
<View style={{ padding: 20 }}>
<Text style={{ fontSize: 30, fontWeight: 'bold' }}>Identifiers</Text>
<View style={{ marginBottom: 50, marginTop: 20 }}>
{identifiers && identifiers.length > 0 ? (
identifiers.map((id: Identifier) => (
<View key={id.did}>
<Text>{id.did}</Text>
</View>
))
) : (
<Text>No identifiers created yet</Text>
)}
</View>
<Button onPress={() => createIdentifier()} title={'Create Identifier'} />
</View>
</ScrollView>
</SafeAreaView>
)
}
export default App

Close the packager and rebuild the app. Once loaded hit the Create identifier button a few times and you should see your identifiers being created!