Heat Wallet

Heat Wallet

  • User Manual
  • Developers

›Server

User manual

  • Install the app
  • Getting Started
  • Create wallet
  • Import wallet
  • Spy on address
  • Paper/digital wallet
  • Receive crypto
  • Transfer crypto
  • Add currency
  • Balance staking

Developers

  • Developer info
  • Server

    • Add your coin
    • Plugin SDK
    • Fork SDK (non standard)
    • Network status
    • Network fee
    • Token discovery
    • Balance lookup
    • Event lookup
    • Event types
    • Utxo lookup
    • Transaction status
    • Alias lookup
    • Publickey lookup
    • Broadcast transaction

    App

    • Add your coin
    • Nodejs integrations
    • Wallet core (by Trust)

Plugin SDK

Plugin sdk was created to assist developers in creating server plugins for Heat mobile wallet app server.

Quick overview

To add indexer support for (part of) a blockchain you'd best use the plugin sdk.

The steps involved in adding support for a feature are as follows.

  1. You fork the plugin sdk repo

Now for each feature.

  1. You write code that translates parameters to a url
  2. You translate the response from the server to a format understood by the indexer
  3. You write any extra tests apart from the existing basic tests available

Finally

  1. You run a build script and commit the code to github.com
  2. You tell us about your plugin by opening an issue on our issue tracker
  3. We review your plugin and integrate it when it meets our quality standards

These features are currently supported in our indexer servers.

  • network status
  • network fee
  • token discovery
  • balance lookup
  • event lookup
  • utxo lookup
  • transaction status
  • forward and reverse alias lookup
  • public key lookup
  • broadcast transaction

Server plugins can choose to support one, some or all of these features as several plugins can be combined to construct a complete working blockchain indexer.

Step by step guide

Follow the steps below to get started with writing your first plugin.

Fork the sdk

Detailed steps on how to fork a repo on github are available here.

  1. On Github, navigate to heatcrypto/heat-server-sdk
  2. In the top-right corner of the page, click Fork

Make sure the name of your fork contains the name of the blockchain and opionally your name or organization name.

In case you are creating more than one plugin you will notice that github does not allow to create multiple forks of the same repository under one single account. From the website. To get around this restriction follow these instructions.

Rename your fork

To rename your forked repository from heat-server-sdk to your desired name please follow instructions below.

  1. On GitHub, navigate to the main page of the repository.
  2. Under your repository name, click Settings.
  3. Under the Repository Name heading, type the new name of your repository.
  4. Click Rename.

Best practice is to name your repo heat-server-BLOCKCHAIN where BLOCKCHAIN is the chain you are creating the plugin for. If that name is taken or if you wish to include your name in the repo please follow this pattern heat-server-BLOCKCHAIN-YOURNAME (for example heat-server-ripple-mike).
Naming plugins this way ensures maximum reusability and discoverability.

Code your feature

Each feature is implemented in what we call a module, all modules live in the src/modules directory.

Modules all expose one function, each specific module must adhere to a specific signature which is shared between your plugin and our indexer server.

As an example lets look at what the transaction status module looks like before we have done any coding.

import { 
  TransactionStatusParam, TransactionStatusResult, 
  tryParse, CallContext, ModuleResponse } from 'heat-server-common'

export async function transactionStatus(
  context: CallContext, 
  param: TransactionStatusParam): Promise<ModuleResponse<TransactionStatusResult>> {
  try {
    const { req, protocol, host, logger } = context
    const { blockchain, assetType, addrXpub, transactionId } = param
    const url = `${protocol}://${host}/api/GET-TRANSACTION-STATUS?transactionId=${transactionId}`;
    const json = await req.get(url);
    const data = tryParse(json, logger);
    
    const confirmations: number = 0;
    const isAccepted: boolean = false;
    
    return {
      value: {
        confirmations,
        isAccepted,
      },
    };
  } catch (e) {
    return {
      error: e.message,
    };
  }
}

heat-server-common

All plugins make use of heatcrypto/heat-server-common as it allows sharing of code between all plugins and our indexing server.

CallContext

Each module receives a CallContext as its first argument. The CallContext is provided by the indexing server.

When running unit tests you have to provide the CallContext yourself. This however is very simple as all you have to do is call the createContext(label: string) function in each of your tests.

/**
 * Each module is provided with a CallContext each time it is invoked
 */
interface CallContext {

  /**
   * Network protocol (http or https)
   */
  protocol: string;

  /**
   * Host (plus optional port) of api server
   */
  host: string;

  /**
   * Main logger, created as prefixlogger with prefix that 
   * identifies the plugin
   */
  logger: LoggerService;

  /**
   * Middleware that deals with address conversions and 
   * possible other future topics
   */
  middleWare?: ExplorerMiddleware;

  /**
   * A configured instance of MonitoredRequest is provided, 
   * this does GET and POST requests
   */
  req: MonitoredRequest;
}

Call Parameters

Modules are not much good if you cant pass parameters to them. Thats where the second parameter to each module comes into play. Each module has its own interface for their parameter as well as for their result. All these interfaces can be found listed here or look in the right hand side menu on this page at each feature and look for Plugin Input.

Typically many more parameters are provided to your module than you actually need, the reason for this stems from the fact that these parameters (like which blockchain or assetType) are used much higher in the call hierarchy in the indexing servers.

API url

Its your task to construct the GET url to the blockchain api server.

const url = `${protocol}://${host}/api/GET-TRANSACTION-STATUS?transactionId=${transactionId}`;

Its very important to use the protocol and host provided by the CallContext. Otherwise your plugin cannot be used in paralel when more than one blockchain api server is available.

Download API response

Once we have the url for our request we can download this data with either GET or POST and parse the response (if its json).

The tryParse method provided by heat-server-common is the preferred and advised way to parse JSON. Using this method ensures proper error handling and logging.

The req object (MonitoredRequest) provided by CallContext should be used for all your GET and POST requests, this allows us to tune the specifics of the underlaying HTTP client.

const json = await req.get(url);
const data = tryParse(json, logger);

To do POST requests are used as follows.

const json = await req.post(url, { form: { transactionBytes: transactionHex } }, [200]);
const data = tryParse(json, logger);

Translate response

Finally you translate the response from the blockchain api server to the expected result by the indexing server. The details of this result can be found in the Result interface as can be seen in the example above.

Test your code

To test your code we use unit tests which have sensible defaults and can run be run as is.

Lets look at the unit test for the transaction status feature we just coded. Below is the code as it is provided to you by the sdk you forked in the previous steps.

import * as chai from 'chai';
const { isObject, isNumber, isBoolean } = chai.assert
import 'mocha';
import { createContext } from './test_config'
import { transactionStatus } from '../src/modules/transaction_status';
import { Blockchains, AssetTypes } from 'heat-server-common';

describe('Transaction Status', () => {
  it('should work', async () => {
    const blockchain: Blockchains = Blockchains.ETHEREUM
    const assetType: AssetTypes = AssetTypes.NATIVE
    const addrXpub: string = '0x12345'
    const transactionId: string = '0x67890'
    let resp = await transactionStatus(createContext('Transaction'), {
      blockchain, assetType, addrXpub, transactionId
    })
    isObject(resp)
    let result = resp.value
    isObject(result)
    isNumber(result.confirmations)
    isBoolean(result.isAccepted)
  });
});

As can be seen we have setup the mocha testframework and are using chai assertion library. While a basic test is provided you should really spend time and code your own.

Configure your test

Before you can run your tests you need to configure them by opening test/test_config.ts and set your protocol and host values.

export const testConfig = {
  protocol: 'http',
  host: 'localhost:3000'
}

Run your tests

To run your tests on the command line run npm run test.

Deploying your plugin

When you have completed writing your module code and unit tests its time to prepare your plugin for deployment.

To do so open src/explorer.ts and at a minimum set the ID value to a globally unique identifier which identifies your plugin.

We strongly advise to use an id that is made up of the last part of your repo name. The part after heat-server- specifically.
So if your plugin is named heat-server-bitcoin-mike please use as an ID bitcoin-mike

Optionally you can comment out or add any modules you did or not implement in the modules variable.

Its good practice to remove any module you did not implement as it helps the indexing server identify when its trying to call a feature that is not implemented in your plugin.

Building your code

Finally we build the plugin by running a script on the command line. Open a command prompt at your plugin root and run npm run prepublish, this will transpile your typescript into javascript and creates the dist folder.

Commit build to github.com

For the indexer server to directly load your plugin code from github you should add the compiled code in the dist folder to your repo and push these changes to github.

To do so open .gitignore and remove the line that says /dist.

Now on the command line add, commit and push the code in /dist.

$ git add dist
$ git commit -m "Add dist to git"
$ git push origin master

Enable your plugin in Heat Wallet

Now that you have created your plugin we will review it before making it available on our indexer platform.

Please create a new issue at https://github.com/heatcrypto/heat-server-sdk/issues and cleary state you request a review and include your plugin repo on github.

Last updated on 9/15/2020
← Add your coinFork SDK (non standard) →
  • Quick overview
  • Step by step guide
  • Fork the sdk
    • Rename your fork
  • Code your feature
    • heat-server-common
    • CallContext
    • Call Parameters
    • API url
    • Download API response
    • Translate response
  • Test your code
    • Configure your test
    • Run your tests
  • Deploying your plugin
    • Building your code
    • Commit build to github.com
  • Enable your plugin in Heat Wallet
Heat Wallet
Docs
Install the appCreate your first walletImport an existing walletDevelopers
Community
Project ChatTwitter
Available here
Copyright © 2020 Heat Ledger