Git Product home page Git Product logo

hubii-core's Introduction

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 [email protected], 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.

hubii-core's People

Contributors

al-babar avatar benedictong42 avatar ghulamhussaink avatar jijordre avatar katat avatar liamaharon avatar mghazanfar89 avatar umairfarooq44 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hubii-core's Issues

Adding Ledger Nano S Support

  • Keep device status up to date in Redux (connected/disconnected/not in correct app/in wrong mode/etc)
  • Support fetching of a device address based on a mnemonic
  • Support saving a device address to local storage

Improve wallet shape

In ImportWalletForm and some other components, a wallet's name is stored under wallet.value. Please change it to be stored under wallet.name

refactor wallet data structure in store

The current wallet structure is:

software: {wallet1: {}},
hardware: {}

It would be easier to be used as an array:

[{name: 'wallet1', type: 'software', address: 'abcd'...}]

Software wallet creation/restore by ether.js

  • create software wallets
    - [ ] create hardware wallets
  • load wallet's main balance(eth)
  • load token balances under wallet
  • restore wallets

For token balances, it will need to predefine a token list with ERC20 contract addresses
Used Wallet API instead for wallet balances.

Setup CI

On push to all branches should run lint check and tests
On push to develop and master should build a Windows, MacOS and Linux binary

Adjustments for swap currencies component

I realized the amount (450) on the left should be an input instead of a fixed value.

The amount should have a maximum value based on the balance. So take this for example, the max value should be 1599.54.

The coin icon on the right should be a drop down to choose which coin to convert to, and the values in the amount on the right should be changed dynamically based on the amount value one the left.

update `Send To`

screen shot 2018-07-09 at 7 30 50 am

The Send To in the right panel should be updated according to the contact dropdown selection.

Switch from px to rem

As suggested by @benedictong42, px are inconsistent between displays eg on a 4k monitor everything will be tiny compared to a 1080p monitor. To make our UI more consistent between displays with different pixel densities, we should use rems as the unit of measurement instead.

FormSteps component

There are some improvements needed for the current AddRestoreWalletModal. This component basically is a parent modal of 3 sub modal forms. All of the 3 sub modal forms have the following common functions:

  1. Navigate back the previous form inside the sub modal, or navigate to the parent modal.
  2. A callback to be called when the form is submitted.
  3. There could be multiple forms that need to be filled in multiple steps.

Considering these common functions, we can create a reusable component for forms. Let's call it FormSteps for now. I think we can abstract the ImportWalletSteps component into a format that can be reusable for all the 3 sub modal forms. The component would accept the following props:

  1. steps array - similar to the steps array in ImportWalletSteps component
  2. prev callback - triggered when "back" arrow is clicked.
  3. next callback - triggered when next button is clicked.
  4. finish callback - triggered when the "next" button of the last step is clicked.
  5. return callback - triggered when the "prev callback" is called at the first step.

Then ImportWalletsSteps wrap FormSteps with its customized forms in the steps array, and intercept with the callbacks. This also applies to the AddWallet component.

The FormSteps component abstracts navigate back arrow and next/finish button in the forms, so that the containers/components using FormSteps doesn't need to rework the UI parts, such as the navigate back arrow, in all the sub modals.

Assuming AddWalletStepsForm and ImportWalletStepsForm are based on the StepsForm component, the codes in AddRestoreWalletModal for loading sub modals can be simplified as:

{type === 'add' && (
    <AddWalletStepsForm handleFinish={} handleReturn={} />
)}
{type === 'import' && (
    <ImportWalletStepsForm handleFinish={} handleReturn={} />
)}

Candlestick chart component

Candlestick chart in the design: https://projects.invisionapp.com/d/main#/console/13058924/277619972/preview

For the mock data, please refer to https://jsfiddle.net/mushigh/wmp65u1w/
For testing with real time data, please use setInterval to mock realtime socket pushes.

Please see the Highcharts documentation: https://www.highcharts.com/docs
and official React components: https://github.com/kirjs/react-highcharts

We should be able to use the chart design and style API detailed in the documentation to style the components to match the mockup

Here is an example of two candidate components, unstyled: https://jsfiddle.net/mushigh/wmp65u1w/

Choose a react-router implementation

Currently two implementations react-router-redux and react-router-dom are configured in the application. We are currently only using the react-router-dom implementation, and need to decide if we should

a) remove react-router-redux
b) refactor to use react-router-redux, and remove react-router-dom

Improve notification Redux logic

Liam [3:58 PM]
@kata what are your thoughts on instead of a saga for every possible notification that could be sent in the app, instead we have two generic sagas 'notifySuccess' and 'notifyError', that take a message as input?

kata [4:05 PM]
Good idea to have two generic sagas for the UI notifications. At the moment, the reason to create every possible notifications are to customize the message in the saga, because the actions can be dispatched from anywhere, so I thought we handle them all in the saga. Actually we already have a generic NOTIFY saga to call the pop the notification.

Liam [4:06 PM]
Maybe if defining the messages in multiple places could get messy, we could store/generate them in a 'strings' file or similar?
(doesn't need to be done now, just want to discuss and create an issue ๐Ÿ™‚ )

kata [4:07 PM]
now the messages are handled only in the sage, what message to show depends on the action type it received. (edited)
agree to create an issue as a backlog

Liam [4:08 PM]
Ah yeah, I see what you mean
Maybe instead of something like this
yield takeEvery(TRANSFER_ERROR, notifyTransferErrorUI);
we could do something like this
yield takeEvery(TRANSFER_ERROR, notifyUI(<params specific to transfer_error>));?
we'll probably also want to move the notifyUI Redux to the 'App' container, since it is a prime example global logic (edited)

kata [4:12 PM]
Yes, that makes sense.

Summary:

  • Use only a single notification saga
  • Move notification Redux logic to App container

DEV API environment for internal electron app release

We will need the electron build to support calling DEV Wallet API for the internal versions.

At the moment, the build calls the productio API as it defaults to the PROD environment when building the electron app.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.