Package: Polymath UI - PolymathNetwork/polymath-apps GitHub Wiki

Note: At the time of this writing (October 2018), this package is going under heavy refactoring and this document will soon change. The package is intended to become strictly a package that exposes generic UI components and their related code.

Package's Concerns

This package holds shared UI components, helpers, reducers and actions used by other apps in the workspace.

Architecture

It exports React components, actions, reducers, images and styles.

Components

Note: Since this package will change, only the Redux components are described in this document

EthNetworkWrapper

Component that will only render its children once the client is connected to the network. It also contains actions and reducers associated with tracking the network's state.

  • A component can be passed through the loading prop to be displayed while the network is trying to connect
  • A component can be passed through the guide prop to be displayed if the connection failed. This is currently being used to display metamask errors, like when the extension is locked

This package manages the network's connection state,

  • Exports action types related to network
  • Provides websocket urls associated to network ids
  • Manages state of connection to the network: Exposes redux store and dispatches actions
  • Provides web3 instance(s) through store

Has the following redux state by default:

{
  isConnected: false,
  isFailed: false, 
  error: null,
  id: null,
  name: null,
  account: null,
  web3: null,
  web3WS: null,
}

React Component (default)

Renders children or other components depending on network state

Props:

  • loading: Component to display while network is connecting
  • guide: Component to display when connection failed
  • networks: Array of network ids that are supported?
    • This is passed to the init action dispatcher
  • children: Array of components to render when the connection is set

Networks

Exports utility function to get websocket url and vanity name associated to a network id

File: src/networks

getNetwork (default anonymous function)

Params:

  • id: Id of the network, defaults to local

Returns:

  • Object with:
    • name: Vanity name for network
    • url: Web socket url for network

Actions

init (async action creator)

Initializes two web3 instances (HTTP and Websockets). Provides them through the redux store

Returns: an asyncronous thunk (enabled functionality by redux-thunk)

init(networks: Array<networkId:string>) => Thunk

Steps:

  • Initialize web3 (Web3 HTTP instance):
    1. If provider exists (Metamask/Mist) then set web3 provider to browser's provider window.web3.currentProvider
    2. Get network id from provider, if no id is defined or > 10000 (why?) assume localhost
    3. If network is not known (doesn't exist in [Networks module][#networks-module]) then reject with ERROR_NETWORK
  • Initialize web3WS (Web3 Websockets instance):
    1. If process.env.REACT_APP_NODE_WS is defined, use it as provider if not, use url associated to network id. This completely disregards network id set on browser
    • NOTE: Super error prone / short-sighted implementation
    1. If network id is undefined (which was previously assumed to mean localhost) then change overwrite the already-set provider for Web3(HTTP) to whatever Web3WS is set to (which means either process.env.REACT_APP_NODE_WS or url associated to the network id, since we know this is undefined here, this is localhost)
    • NOTE: It requires two because metamask doesn't support websockets yet
    • TODO: Check how these two instances are being juggled with in the apps
  • Set a 100ms interval to check if selected account or network id in Metamask extension has changed
    • If there is a change, reload page
  • If no account is set (obtained through web3.eth.getAccounts()) it means Metamast extension is locked. reject with ERROR_LOCKED
  • Do a hacky fix to avoid websocket from disconnecting to infura?
    • Subscribe to newBlockHeaders event, if it returns an error dispatch ERROR_DISCONNECTED
  • Dispatch connected action with args:
    • id: Network id
    • name: Network name, defined by [Networks module][#networks-module]
    • account: As selected in browser or given by provider used
    • web3 and web3WS: Web3 instances

connected (syncronous action creator)

  • Sets network state as connected, isConnected = true
  • Spread-assigns params to state
connected(params: object) => ({ type: CONNECTED, params })

fail (syncronous action creator)

  • Sets network state as failed isFailed = true, isConnected = false
  • Sets network error as a number
fail(error: number) => ({ type: FAIL, error })

TxModal

Component that shows a modal with information about one or many transactions. Relies heavily on its tightly-coupled state called TxModal.

NOTE: For the way the state shaped, there is no way to allow two transactions to occur at the same time through this method

Redux State

Most of these properties are sadly being spread from the actions root, so watch out for that while dealing with this state as it is super fragile. Explanatory comments have been include in the code related to this state to help work with it.

const defaultState = {
  titles: [], 
  successTitle: null,
  continueCode: null,
  continueRoute: null,
  continueLabel: null,
  isNoEmail: false,
  hashes: [],
  receipts: [],
  total: null,
  current: null,
  isFinished: null,
  error: null,
  headingOverride: null,
};

MetamaskStatus

Being used by EthNetworkWrapper to display Metamask errors. This component depends on the network state in the redux store.