Developer tutorial 2: Writing your own Moracle resolver.

Jackson
Moracle Network
Published in
4 min readNov 27, 2019

This tutorial assumes you’ve followed part one:

If you haven’t, go do that. We’ll wait. :)

In this article you’ll learn how to write your own Moracle resolver, which will allow you to access external data sources in your blockchain application on the Lisk SDK!

What is a Moracle resolver?

A Moracle resolver is simply a data source that exposes a GraphQL interface.

It allows an API to be created around any data, and made highly reliable and accessible in blockchain applications.

Things that can be accessed through Moracle resolvers include:

  • Crypto price data.
  • Weather data.
  • Information from other blockchains.
  • Machine learning services.
  • Stock market data.
  • Centralized payment services
  • Any website or API!

Anatomy of a Moracle resolver

For example, our weather API from the last tutorial consisted of two parts:

  1. A schemaMappings.js file.
  2. Some JavaScript code to actually run the query.

All Moracle resolvers must contain these two things.

schemaMappings.js

This file is responsible for two things:

  • Declaring the schema which will be merged into Moracle’s global GraphQL schema.
  • Defining the files in which each query’s resolver code is located.

Here, we create a single query called getCurrentTemperature which takes in two floats parameters labeled lat and long, and returns a float value (the current temperature). In the mappings object we’re simply stating that the getCurrentTemperature query defined in our schema variable is implemented in the file getCurrentTemperatureResolver.js . Let’s take a look at that file.

getCurrentTemperatureResolver.js

If you think this looks a bit weird, you’re right. You may have noticed that:

  1. args is not defined in the scope.
  2. asyncGet is not defined in the scope.
  3. The entire thing is wrapped in an asynchronous immediately-invoked function expression (IIFE)

This is because both args and asyncGet are special variables that are passed to the resolver function sandbox which allows Moracle to execute untrusted code. args contains the arguments passed to the GraphQL query.

The resolver must be wrapped in an async IIFE to allow use of the await keyword and for the code to run properly in the sandbox.

Now that you understand the structure of a Moracle resolver, let’s write a new one!

Creating a Moracle resolver for getting the balance of a Bitcoin address through multiple APIs.

We’re going to be creating a Moracle resolver which access multiple data sources to create a reliable and fast interface for external information.

Step 1: Create a new folder for our resolver.

In the folder Moracle-Lisk/moracle/example-resolvers create a new folder called “getBitcoinAddressBalance”. You can call it whatever we want, but we’ll use this name throughout the rest of this tutorial.

This folder name will also be the name of your resolver. In the future, this resolver name will be used for namespacing.

Step 2: Create schemaMappings.js

Inside the newly-created getBitcoinAddressBalance folder, create a file called schemaMappings.js with the following contents:

Breaking this down:

  • We’ve created a new query called getBitcoinAddressBalance which takes a single required string argument called address and returns an Int representing the amount of satoshis owned by that address.
  • We’ve stated that the resolver code for the getBitcoinAddressBalance resolver lives in balanceResolver.js. Let’s write that file now.

Step 3: Create balanceResolver.js

Now, let’s create the file that will actually run the query and return the result. We will be querying multiple endpoints and making sure they match in order to deliver a more reliable result.

This demonstrates the power of a Moracle resolver. Instead of relying on a single source, we can query both blockchain.info and blockcypher.com, check if they match, and only return the result if they do.

Step 4: Add the resolver to your database.

In Moracle-Lisk/moracle/src/resolver-processing/test.ts we can define which resolvers are loaded into the database and made available.

We can add the following lines:

const bitcoinAddressResolver = processResolver('getBitcoinAddressBalance');

and then add the resolver to the variable resolvers_to_serialize

const resolvers_to_serialize = [    resolver,    exchangeResolver,    weatherResolver,    cryptoExchangeResolver,    bitcoinAddressResolver];

Now, we can run:

node built/resolver-processing/test.js

to add our new resolver to the database.

Step 5: Testing our new resolver.

First, let’s create a new transaction type and then create a file to process the transaction asynchronously:

Note that we can simply use a Moracle request to access the resolver we wrote earlier, and get a reliable result as conveniently as if we were accessing a single API.

Now, lets create a client to test our new transaction type:

And finally, let’s run it!

node client3.js | tee >(curl -X POST -H "Content-Type: application/json" -d @- localhost:4000/api/transactions)

Let’s check our Lisk API at http://localhost:4000/api/accounts?address=16313739661670634666L to see if it worked…

It worked!

We now have the correct balance of this randomly chosen address stored in the blockchain inside this account’s asset. This data was securely sourced from multiple sources, and Moracle will store the result for this transaction forever (so the transaction can be replayed).

Conclusions

Hopefully, now you feel empowered to go create your own highly-reliable dynamic data sources for your blockchain apps using Moracle! If you have any questions at all, feel free to let us know here or at contact@moracle.network. Thanks for reading!

--

--