Original Photo by Abigail Lynn on Unsplash

Onboard your ÐApp Users Using an Autonomous Agent

Chuck Bergeron
MedX Protocol
Published in
4 min readAug 1, 2018

--

(TLDR: We wrote an autonomous agent to sign and call Ethereum smart contract functions on our behalf when our beta testers make AJAX requests to Lambda endpoints. The Solidity code and Lambda function framework is publicly available on GitHub here: https://github.com/MedCredits/dapp-beta-faucet)

What is this for?
Recently our team launched a public beta test of our first MedCredits ÐApp, Hippocrates. The goal, like most betas, is to collect useful data with actual testers and their devices to improve the experience prior to the full release.

However, launching a beta for a ÐApp comes with its own set of caveats. First and foremost, your testers will need Ether to pay gas fees for transactions (and possibly pay for ERC721 tokens, etc.). Odds are they won’t be able to use their Mainnet Ether balance either, as you will likely be running your beta on the Rinkeby or Ropsten test networks. This can be a big point of friction in getting testers set up.

For MedCredits ÐApps we also had the barrier of testers requiring test MEDX (MEDT) to use ÐApps in the health system.

Our solution? A faucet that automatically drips Ether & MEDT to each tester following signup:

A simple example of our Hippocrates ĐApp’s frontend showing what this can look like to your beta testers.

Architecture

The idea is simple enough: when a new user signs up to your ÐApp, you’d like to greet them with the resources necessary for them to completely try it out.

  1. The user makes a request to our server (i.e. “Send me test Ether!)
  2. The server (Lambda endpoint) then signs a new transaction (on behalf of the contract owner)
  3. The new transaction calls the function on the deployed smart contract

After a few various attempts at creating infrastructure around this, we ended up with this solution:

The Smart Contract
A smart contract was written which allows only the Owner of it to call its functions. This contract holds a balance of both Ether and our MEDT Test Token. When a tester asks for Ether, it sends them 1 Ether (Ropsten test Ether), and when he or she asks for MEDT, it sends them 500 MEDT. This contract could also provide other functionality (more on that below) in order to bootstrap your users for their test run.

The Lambda Endpoint(s)
For the server, we decided to use Amazon’s Lambda (or more accurately, Netlify’s implementation of Amazon Lambda) endpoints - although you could configure any kind of server you like (Rails, Node, etc.). We felt this didn’t detract from our goals for decentralization since it’s only for the beta, and we will remove the Lambda functionality prior to our mainnet launch.

Caveat #1
We wrote the Lambda code using Web3's 1.0 beta34, and proceeded to spend much too much time attempting to get it’s PromiEvent datatype working with Lambda. It worked locally, however when we would deploy the functions to AWS Lambda or Netlify’s Lambda, it would hang until the timeout expired. Eventually we decided to re-write the self-signing portion using ethjs. Web3 0.2 would likely have worked as well, as it doesn’t use PromiEvents.

Caveat #2
Since we’re using Infura for our Ethereum node it’s difficult to get the contract owner’s current nonce using:

getTransactionCount("<Contract Owner's Eth Address>", "latest");

Infura uses node balancers to handle the large scale of requests they receive, so their servers may be out of date when you ask for the nonce. To combat this we implemented a loop that tries the latest known nonce, and if that doesn’t work (due to a “known transaction” error or a “transaction underpriced” error) we increment the nonce by 1 and try again until we receive the transaction hash. This is less than ideal but does the trick!

The Frontend
Once the smart contracts & Lambda functions have been deployed, and the contract has been filled up with Ether (and possibly your ERC20 token) then all that’s left is to call the Lambda endpoints. Grab your favourite XHR library (We’re using Axios) and make a GET request to one of the endpoints with the current user’s Ethereum address as the ?ethAddress=0x… URL parameter.

The response from the Lambda endpoint should include the Transaction Hash, which is the ID for the new transaction. If it’s on Ropsten or Rinkeby the tester will have to wait for the transaction to be confirmed. We then subscribe our block tracker to listen for the transaction hash, and provide feedback to the tester as the transaction moves from pending to confirmed.

Any Contract Methods
Another awesome facet to this is that it doesn’t have to be only for sending Ether or your ERC20 token. You can also have it call any public smart contract function. For example, the next phase of the Hippocrates open beta will allow our testers to optionally act as doctors if they’d like to try out the physician side of the ÐApp.
(Back to ‘The Smart Contract’ paragraph)

In Short

We hope this has given you some insight into how you can reduce the on-boarding barriers for your users and optimize for early feedback and testing of your ÐApp. Our goal is to make ÐApps as user friendly as possible and this is one way to get around an otherwise bewildering user on-boarding process.

If you end up using this tool in your project let us know as we would love to test it out!

To find out more about the MedCredits Health System, please join the discussion on our Telegram or join our mailing list!

--

--