Skip to content

The home of hubii core (aka Omphalos UI), the reference desktop app for nahmii

License

Notifications You must be signed in to change notification settings

hubiinetwork/hubii-core

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hubii core (aka Omphalos UI) GitHub release GitHub


hubii core is an Ethereum wallet manager and friendly user interface to the Ethereum scaling solution nahmii, by hubii. Send and recieve crypto assets and trustlessly make instant, cheap payments and trades, all within a secure desktop environment

Table of Contents

Highlights

  • Open source
  • Send, receive crypto assets on the Ethereum blockchain
  • Manage all wallets & addresses in one application
  • Retain full custody and control of private keys
  • First class Ledger Nano S support
  • First class Trezor support
  • Instant payments and trades without compromising on security with nahmii (WIP)

Install

macOS 10.9+, Linux, and Windows 7+ are supported (64bit only)

Download the latest version of hubii core for your system on the official releases page

Architecture

hubii core is a multiplatform desktop application built with Electron, React, Redux and styled-components. The architecture is heavily influenced by the react-boilerplate project. To understand our design decisions in greater detail, we recommend you checkout the documentaion and reasoning outlined in that repository.

Develop

Requirements

  • NodeJS LTS
  • Yarn LTS
  • Python
  • A C++ compiler

Setup API credentials

  1. Send an email with the subject line "API access" to info@hubii.com, we'll get back to you within 24 hours

  2. Add the credentials we provide to your PATH

Install dependencies

yarn

Run

yarn electron-dev

Lint

yarn lint

Test everything

yarn test

Test only what's changed since the last commit

yarn test:dev

Get Ropsten ETH

There are various faucents providing free Ropsten ETH:

  • faucet.ropsten.be
    • wget https://faucet.ropsten.be/donate/<your ethereum address>
  • faucent.metamask.io
    • Follow instructions on the website

Get Ropsten ERC20 tokens

We recommend the ERC20 BOKKY token on Ropsten. To receive BOKKY, send Ropsten ETH to the BOKKY smart contract for BOKKY tokens in return, 1 for 1.

Build from source

# compiles and builds the app for your system architecture
# the binary will be created inside the dist folder
yarn && yarn electron-build

Development guidelines

Boy scout rule

During the early development of hubii core, different people with different opinions on testing and best practices touched the code base. As a result, you will notice some of the best practices below are not implemented everywhere you look. The majority of critical code has been refactored and we are confident in the foundations of the application, but we have a long way to go cleaning up less critical components and logic.

Instead of tackling this technical debt all at once, we ask that developers follow the "boy scout rule": leave the code you're working on in a better state than you found it. Over time, we will chip away at these smaller issues.

Ensuring stability when using complex selectors

The architecture of hubii core relies on the library reselect to sit inbetween the Redux store and React components. Reselect allows us to abstract a lot of the complex data processing away from the components, keeping them as simple as possible.

One thing to be careful about when composing a complex selector is that you considered all possible structures input selectors can take, for example a selector could either be 'loaded', 'loading', or 'errored'. Forgetting to check for an uncommmon state like 'errored' can be easy, and cause catastrophic failure for the user.

The best way to lower chances of this kind of failure occuring is to test your selector/component with every variation of its possible inputs. To make this as frictionless as possible, please maintain a mocks/selectors.js file in a container's tests folder, that contains samples of every variation of structure a selector could return (see containers/WalletHoc/tests/mocks/selectors.js for an example).

Then when you or another developer wants to reach for a selector, when they're writing their tests they can be confident that they know exactly which inputs they need to test, and have the ability to effortlessly import the required mocked state.

Gitflow

Please obey by established Gitflow principles. Details can be obtained in post by Vincent Driessen or in Atlassian's Gitflow Workflow tutorial. Driessen's git-flow git extension is indispensable.

Working with numbers

During blockchain development, you'll often find yourself working with very small and very large numbers. When dealing with these types of numbers (notably Ether or token amounts), use the BigNumber library to ensure precision isn't lost. If you're interested to read more see this article for a concise explination.

Test Driven Development

Here is a video about TDD, introducing the motivations behind writing good unit tests.

index.test.js: Test the logics at the container level. component tests can be constructed similarly to this.

actions.test.js: Test any actions

reducer.test.js: Test the container reducer

saga.test.js: Test any saga logic. We recommend and are currently migrating all our saga tests to use redux-saga-test-plan

Containers as sub pages

Some containers contain up to 3 levels of complex components. Combining all the logic of each component into a single container could make the code difficult to maintain and difficult to schedule development.

To isolate the complexities between the sub components, the parent container can use sub routes to wire up the sub components. This enable isolating the logics in the parent page container from their sub pages, as well as isolating the logics between the sub pages.

For example

<Tabs defaultActiveKey={history.location.pathname}>
    <TabPane tab="Accounts" key={`${match.url}/accounts`}>
        <Route path={`${match.url}/accounts`} component={AccountsContainer} />
    </TabPane>
    <TabPane tab="Contacts" key={`${match.url}/contacts`}>
        Content of Tab Pane 2
    </TabPane>
</Tabs>

The containers/Accounts container is the parent page of a number of sub pages such as payment, savings, swap currencies etc. Although it has quite a number of sub pages, it handles its own container logics and have the sub pages to handle by them own.

In order to let the sub pages know which account and currency is currently chosen, it dispatch the actions CHANGE_CURRENT_CURRENCY or CHANGE_CURRENT_ACCOUNT, so the sub pages can react respectively.

Take Swap Currency sub page for example, it connects the currentCurrency with the state in the store using reselect. Whenever there is an update to this currentCurrency state, the swap currency container re-render the view to reflect the newly chosen currency from its parent container containers/Accounts.

Sample codes from containers/SwapCurrencies on connecting the props to the defined states from the store.

import { makeSelectCurrentCurrency } from 'containers/Accounts/selectors';
const mapStateToProps = createStructuredSelector({
  currentCurrency: makeSelectCurrentCurrency(),
});

Debugging a production build

The dev tools can be opened with Cmd+Alt+I on macOS, or Ctrl+Shift+I on Linux and Windows.