Tutorial

This tutorial will explain how to use the Vortex and Vortex Components packages in a React Dapp. The first part will speak about how to use Vortex in a React Dapp (if you want to manually instantiate it and connect your components to the store). The second part will explain how to use the Generic Vortex Components.

Installing

Both Vortex and Vortex Components are available on the public npm registry. You can simply run:

npm install --save vort_x vort_x-components

Vortex

Creating a classic Vortex instance for Truffle Users

/!\ This section is only more informations about how Vortex works. If you want to use it in React, use the VortexGate component !! /!\

Creating a Vortex instance is quite easy. Start by importing the Vortex class from the vort_x package.

// ES6 or TS
import { Vortex } from 'vort_x';
// or
const Vortex = require('vort_x').Vortex;

Then, call the factory constructor.

const SimpleStorage = require("SimpleStorage.json");
const MySmartContract = require("MySmartContract.json");

const web3_loader = new Promise((ok, ko) => {
    try {
        let web3 = // Recover your web3 instance as you want.
        ok(web3);
    } catch (e) {
        ko(e);
    }
});

const instance = Vortex.factory(
    {
        type: 'truffle',
        truffle_contracts: [SimpleStorage, MySmartContract],
        preloaded_contracts: ["SimpleStorage"],
        network_contracts: [SimpleStorage]
    },
    web3_loader,
    {
        ipfs_config: {
            host: 'url',
            port: '5001',
            options: {
                protocol: 'https'
            }
        },
        backlink_config: {
            url: {
                "mainnet": "wss://mainnet.infura.io/ws",
                "default": "ws://localhost:8545/ws"
            }
        }
    });

As a first argument, you will need to provide this object

{
   type: 'truffle',
   truffle_contracts: [SimpleStorage, MySmartContract],
   preloaded_contracts: ["SimpleStorage"]
   network_contracts: [SimpleStorage]
}

type here defines the framework being used. Here we use truffle.

truffle_contracts is an array of Truffle artifacts (generated by truffle migrate).

preloaded_contracts is an array of contract names you want to load when instantiating.

network_contracts is an arrau of Truffle artifacts, and will be used to determine network compatibility based only on the network of the given contracts.

web3_loader is a custom web3 fetcher.

And the last argument is the configuration.

Your instance is ready to be run, but you can still tweak your store before running it.

You can recover this instance at any time by calling the static get method on Vortex (will only store the last instance, but you'll never need two instances of Vortex).

Creating a classic Vortex instance for Embark Users

// ES6 or TS
import { Vortex } from 'vort_x';
// or
const Vortex = require('vort_x').Vortex;

Then, call the factory constructor.

import simple_storage from 'Embark/contracts/SimpleStorage';
import my_smart_contract from 'Embark/contracts/SimpleStorage';
import * as Chains from 'path/to/embark/dir/chains.json'

const web3_loader = new Promise((ok, ko) => {
    try {
        let web3 = // Recover your web3 instance as you want.
        ok(web3);
    } catch (e) {
        ko(e);
    }
});

const instance = Vortex.factory({
        type: 'embark',
        embark_contracts: {
            SimpleStorage: simple_storage,
            MySmartContract: my_smart_contract
        },
        chains: Chains,
        preloaded_contracts: ["SimpleStorage"]
    },
    web3_loader,
    {
        ipfs_config: {
            host: 'url',
            port: '5001',
            options: {
                protocol: 'https'
            }
        },
        backlink_config: {
             url: {
                 "mainnet": "wss://mainnet.infura.io/ws",
                 "default": "ws://localhost:8545/ws"
             }
        }
    });

As a first argument, you will need to provide this object

{
   type: 'embark',
   embark_contracts: {
       SimpleStorage: simple_storage,
       MySmartContract: my_smart_contract
   },
   chains: Chains,
   preloaded_contracts: ["SimpleStorage"]
}

type here defines the framework being used. Here we use embark.

embark_contracts is an object filled with contracts instance from Embark.

preloaded_contracts is an array of contract names you want to load when instantiating.

web3_loader is a custom web3 fetcher.

And the last argument is the configuration (which is optional).

Your instance is ready to be run, but you can still tweak your store before running it.

You can recover this instance at any time by calling the static get method on Vortex (will only store the last instance, but you'll never need two instances of Vortex).

Creating a classic Vortex instance without framework

// ES6 or TS
import { Vortex } from 'vort_x';
// or
const Vortex = require('vort_x').Vortex;

Then, call the factory constructor.

import * as ABI from 'SimpleStorage.abi';
import * as Address from 'SimpleStorage.address';
import * as DeployedBytecode from 'SimpleStorage.bytecode';

const web3_loader = new Promise((ok, ko) => {
    try {
        let web3 = // Recover your web3 instance as you want.
        ok(web3);
    } catch (e) {
        ko(e);
    }
});

const instance = Vortex.factory({
        type: 'manual',
        manual_contracts: {
            SimpleStorage: {
                abi: ABI,
                at: Address,
                deployed_bytecode: DeployedBytecode
            }
        }
    },
    web3_loader,
    {
        ipfs_config: {
            host: 'url',
            port: '5001',
            options: {
                protocol: 'https'
            }
        },
        backlink_config: {
             url: {
                 "mainnet": "wss://mainnet.infura.io/ws",
                 "default": "ws://localhost:8545/ws"
             }
        }
    });

As a first argument, you will need to provide this object

{
   type: 'manual',
   manual_contracts: {
       SimpleStorage: {
           abi: ABI,
           at: Address,
           deployed_bytecode: DeployedBytecode
       }
   }
}

type here defines the framework being used. Here we use no framework, so manual.

manual_contracts is an object filled with the minimum data needed to load contracts. abi is mandatory, at is optional but is required if you want your contract to get preloaded, deployed_bytecode is optional but required if you want network checks.

Your instance is ready to be run, but you can still tweak your store before running it.

You can recover this instance at any time by calling the static get method on Vortex (will only store the last instance, but you'll never need two instances of Vortex).

Creating an extended Vortex instance

The Vortex store is quite modular and allows you to plug your own reducers, sagas and set your starting state. Let's assume that you want to add a new entry profile in the store, and that you have created your actions and reducer. And you also want to have a redux saga that prints "LOADED" when Web3 gets loaded.

import simple_storage from 'Embark/contracts/SimpleStorage';
import my_smart_contract from 'Embark/contracts/SimpleStorage';
import * as Chains from 'path/to/embark/dir/chains.json'

// SAGAS
function* onLoaded(action: any): SagaIterator {
    console.log("LOADED");
}

function* testSaga(): any {
    yield takeEvery('LOAD_WEB3', onLoaded);
}

const loaded_sagas = [
            testSaga
        ]

// REDUCERS
const profile_reducer = require("./profile_reducer");

// INITIAL_STATE
const initial_state = {
    profile: {
        username: 'John Doe'
    }
}

const web3_loader = new Promise((ok, ko) => {
    try {
        let web3 = // Recover your web3 instance as you want.
        ok(web3);
    } catch (e) {
        ko(e);
    }
});

const instance = Vortex.factory({
        type: 'embark',
        embark_contracts: {
            SimpleStorage: simple_storage,
            MySmartContract: my_smart_contract
        },
        chains: Chains,
        preloaded_contracts: ["SimpleStorage"]
    }, web3_loader, {
        reducer: {profile: profile_reducer},
        custom_state: initial_state,
        custom_sagas: loaded_sagas,
        ipfs_config: {
            host: 'ipfs.infura.io',
            port: '5001',
            options: {
                protocol: 'https'
            }
        },
        backlink_config: {
             url: {
                 "mainnet": "wss://mainnet.infura.io/ws",
                 "default": "ws://localhost:8545/ws"
             }
        }
    });

Now your store will behave exactly like before, but it will also support your profile actions.

Configuration options are:

  • reducer: An object containing the reducers you want to merge with the Vortex Store. Default: undefined
  • custom_state: An object defining your initial state, that will be merged with the Vortex initial state. Default: undefined
  • account_refresh_rate: A refresh rate (in ms) for account balance refresh. Default: 5000
  • custom_sagas: Custom sagas you want to add to the already existing redux-saga middleware.
  • ipfs_config: Configuration for the ipfs endpoint.
  • backlink_config: Configuration for the backlink endpoint.

Preparing before running

Before really running the Vortex Store, you can still tweak your settings with the following methods from the Vortex class.

This will add a new contract (just like if you gave it at instantiation).

This will add a network id to the whitelist. If the whitelist remains empty, no network checks will be done by Vortex.

This method takes a Truffle artifact and adds all the networks where it has been deployed to the whitelist. Can be called on multiple artifacts.

You can find all of the tweakers on the Vortex class documentation.

Running Vortex

Now that you have configured your Vortex, it is time for you to run it.

instance.run()

Will start the store.

instance.loadWeb3()

Will give the order to load the web3 instance from the loader you have provided during creation.