ESOP-ui is frontend application that allows you to view and manipulate Neufund ESOP smart contract.
This README is meant to provide technical information how to run and connect UI to existing smartcontract. For introduction and information what ESOP is visit https://github.com/Neufund/ESOP where you will find exhaustive information.
There are following prerequisites to compile, run and use this application:
- Neufund ESOP smart contract
- Node.js
- ver 8 is required if you want to use Ledger Nano
- As Node 8 is pretty old it is convenient to use Node Version Manager to switch to older version.
- we didn't test it on Windows
- web browser Chrome, Opera, Firefox with U2F extension
- Ethereum wallet / signer Ledger Nano S, Metamask or Parity Ethereum Integration
At this moment ESOP-ui project depends on compiled contracts that you will find in ESOP repository. We use relative path in configuration so clone both repositories into same directory so you have following project structure
.
|-- ESOP
|-- ESOP-ui
you can have different structure -> see config.js file truffleArtifacts
key
commands to clone both repos:
git clone [email protected]:Neufund/ESOP.git
git clone [email protected]:Neufund/ESOP-ui.git
Edit ./ESOP-ui/src/config.js
and set ethEndpoint
to any of public Ethereum endpoints. Our demo contracts are
deployed to Ethereum testnet, so you have to use testnet endpoint data ex. https://api.myetherapi.com/rop
.
Switch into ESOP-ui directory, download dependencies and run webpack in development mode.
cd ESOP-ui
nvm use
yarn
yarn dev
This will fire local development webserver that will compile and display DAPP connected to Neufund ESOP demo contract.
Configuration is defined through ./src/config.js
. Most important parameters are:
truffleArtifacts
key store absolute or relative path to directory where truffle artifacts are located. Those are used by truffle-contract library which is wrapper to standard web3 library. You need to provide them for every deployment of UI.ethEndpoint
url of Ethereum node. Dapps (abbr decentralized application) are not using typical backend which provides API. Instead you can connect to any (all are sharing same network) eth node that provides json RPC api. You can use existing public ones ex. Infura or you can host your own (that can be a bit tricky).pdfRenderServer
is endpoint where instance of PDF render server is deployed. It is service that will generate pdf's with employee data similar to html view in "Show agreement" popup. If you leave this option empty this functionality will stay off.- You can define your own
derivationPath
. If none (or empty string) is provided dapp will use default from ledger-wallet-provider project.
Issue yarn build
command and Webpack will compile build into ./ESOP-ui/build
directory.
Put contents of ./ESOP-ui/build
directory on any https capable webserver. Github pages etc. are also good.
Project is not very complicated. We use standard standard JS frameworks React, Redux and Material-UI and Webpack as module bundler. To communicate with Ethereum network we use truffle-contract library. Still there are few interesting points worth mentioning:
We decided to allow your users to use Ledger Nano S which is cool security device. Since its hardware it introduces some complications into usage flow and code. We managed to resolve most of problems by creating neat library which expose standard web3 object that underneath communicate with device and use it to sign transactions. After experiences we got with this project we will improve it a bit, but it's already pretty interesting - ledger-wallet-provider.
But now we ended with need to dynamically choose which web3 we gonna use: one provided by browser (Metamask / Parity) or one with Nano support. We do it in typical way proposed by web3 doc:
if (typeof window.web3 !== 'undefined') {
//"web3 already exists" it means Metamask / Parity are beeing used.
} else {
// use own web3 that can use Nano
let engine = new ProviderEngine();
let ledgerWalletSubProvider = await LedgerWalletSubproviderFactory();
engine.addProvider(ledgerWalletSubProvider);
...
window.web3 = new Web3(engine);
}
One thing that was unpleasant surprise is way that truffle-contract handles sending transactions to eth network. Returned Promise is resolved not when transaction is mined but when transaction is accepted by node. Because of that you still need to manually check when transaction is visible on network. Also it turns out some public nodes like Infura are not supporting web3 web3.eth.filter. We had to introduce where we pool network every second to check if transaction is mined.
In ESOP project we rely on truffle framework to compile and deploy smart contracts. In UI project we use truffle-contract which works really nice when you are using contracts deployed with truffle. Point of contact between those two are artifact files created during compilation and updated after deployment. Those contain abi definitions, compiled byte code and contract addresses in every network (local, test, main) you deployed contracts to. At this moment we store those files in ESOP repo. Then in UI code that uses truffle-contract looks like this:
import RoTDef from 'truffle-artifacts/RoT.json'
...
this.RoTContractAbstr = contractBuilder(RoTDef);
this.RoTContractAbstr.setProvider(web3.currentProvider);
this.RoTContract = this.RoTContractAbstr.deployed();
Basing on current provider and addresses from truffle artifact library can obtain network addresses of you deployed contracts.
When developing UI you need to deploy and use contracts locally. Here are some tips how to do it - it's not complete "how to" but it might me useful. You should start in our ESOP repo and read and understand at least development part.
- run Parity in dev mode - example command line
parity ui --chain dev --jsonrpc-cors "http://localhost:8081" --jsonrpc-hosts="all" --jsonrpc-port 8444
- migrate contracts (you need to install whole truffle framework) to local development chain
cd ESOP; truffle migrate --networks paritydev
- edit
ESOP-ui/config.js
and set keys to local values - we provided commented correct ones. We included proxy rule in webpack dev server configuration so you won't have problems with CORS, SSL. - after that compile and run app
yarn dev
- you need to restart webpack after every contract deployment - have fun
If you have any problems join our slack channel we will be happy to help you.