Add STAKE token example for testing and mainnet

This commit is contained in:
Gerardo Nardelli 2020-04-28 15:10:34 -03:00
parent 262dbc52c1
commit f4d844efd2
25 changed files with 248 additions and 156 deletions

View File

@ -1,4 +1,4 @@
FROM node:12
FROM node:12 as plugin-base
WORKDIR /plugin
@ -8,10 +8,17 @@ COPY yarn.lock .
COPY tsconfig.json .
COPY my-plugin/package.json ./my-plugin/
COPY wallet/package.json ./wallet/
COPY test-wallet/package.json ./test-wallet/
RUN yarn install
COPY ./my-plugin ./my-plugin
RUN yarn build
FROM plugin-base as test-wallet
COPY ./test-wallet ./test-wallet
CMD ["yarn", "start-wallet"]
FROM plugin-base as wallet
COPY ./wallet ./wallet
CMD ["yarn", "start-wallet"]

View File

@ -8,13 +8,14 @@ Clone the sample repo to create a plugin project that uses the TokenBridge plugi
#### Project structure
There are two main folders in the project:
- `wallet` - is a burner wallet instance ready to test your plugin
- `wallet` - is a burner wallet instance ready to use your plugin
- `test-wallet` - is a burner wallet instance ready to test your plugin and resources in testnets
- `my-plugin` - is the folder where the plugin code is located. To change the name of the plugin it is necessary to update the folder name `my-plugin` and all mentions to `my-plugin` to the new name of your plugin.
Inside `my-plugin` you can find the files that defines the resources to be exposed by the plugin to be used by the burner wallet in order to interact with the Native to ERC677 bridge extension:
- `sPOA` - uses `sPOA` defined in `tokenbridge-plugin` and adds the mediator address to the correct track of the transactions.
- `ksPOA` - extends from `ERC677Asset` defined in `tokenbridge-plugin`
- `KSPOABridge` - extends from `Mediator` defined in `tokenbridge-plugin`
Inside `my-plugin` you can find the files that defines the resources to be exposed by the plugin to be used by the burner wallet in order to interact with the ERC677 to ERC677 bridge extension:
- `Stake` - extends from `ERC677Asset` defined in `tokenbridge-plugin`
- `xStake` - extends from `ERC677Asset` defined in `tokenbridge-plugin`
- `StakeBridge` - extends from `Mediator` defined in `tokenbridge-plugin`
You can extend or replace these resources based on your use case.
@ -27,8 +28,21 @@ To build the plugin package, from the root folder of project, you need to run th
yarn build
```
### Test
The project includes a burner wallet instance where you can test the implementation of the plugin. For that, you have to make sure that the build step was performed and that the plugin resources you modified are correctly imported and used in the `src/index.tsx` file of the `wallet` folder.
### Test plugin and resources in testnets
The project includes a burner wallet instance where you can test the implementation of the plugin in testnet. For that, you have to make sure that the build step was performed and that the plugin resources you modified are correctly imported and used in the `src/index.tsx` file of the `test-wallet` folder.
1. Create `.env` file in `test-wallet` folder and set:
```
REACT_APP_INFURA_KEY=<your key from infura.com>
```
2. To start the burner wallet instance run:
```
yarn start-test-wallet
```
### Run plugin in Mainnet
The project includes a burner wallet instance where you can use the implementation of the plugin. For that, you have to make sure that the build step was performed and that the plugin resources you modified are correctly imported and used in the `src/index.tsx` file of the `wallet` folder.
1. Create `.env` file in `wallet` folder and set:
```

View File

@ -5,5 +5,13 @@ services:
build:
context: .
dockerfile: Dockerfile
target: wallet
environment:
- NODE_ENV=production
test-wallet:
build:
context: .
dockerfile: Dockerfile
target: test-wallet
environment:
- NODE_ENV=production

View File

@ -1,5 +1,6 @@
{
"packages": [
"test-wallet",
"wallet",
"my-plugin"
],

View File

@ -0,0 +1,8 @@
import { ERC677Asset } from '@poanet/tokenbridge-bw-exchange'
export default new ERC677Asset({
id: 'stake',
name: 'STAKE',
network: '1',
address: '0x0Ae055097C6d159879521C384F1D2123D1f195e6'
})

View File

@ -1,8 +0,0 @@
import { ERC677Asset } from '@poanet/tokenbridge-bw-exchange'
export default new ERC677Asset({
id: 'xspoa',
name: 'ksPOA',
network: '42',
address: '0xff94183659f549D6273349696d73686Ee1d2AC83'
})

View File

@ -1,5 +0,0 @@
import { sPOA } from '@poanet/tokenbridge-bw-exchange'
sPOA.setMediatorAddress('0x867949C3F2f66D827Ed40847FaA7B3a369370e13')
export default sPOA

View File

@ -0,0 +1,8 @@
import { ERC677Asset } from '@poanet/tokenbridge-bw-exchange'
export default new ERC677Asset({
id: 'xstake',
name: 'xSTAKE',
network: '100',
address: '0x' // TODO set address
})

View File

@ -1,3 +1,3 @@
export { default as ksPOA } from './assets/ksPOA'
export { default as sPOA } from './assets/sPOA'
export { default as KSPOABridge } from './pairs/KSPOABridge'
export { default as Stake } from './assets/Stake'
export { default as xStake } from './assets/xStake'
export { default as StakeBridge } from './pairs/StakeBridge'

View File

@ -1,13 +0,0 @@
import { Mediator } from '@poanet/tokenbridge-bw-exchange'
import { sPOA, ksPOA } from '../index'
export default class KSPOABridge extends Mediator {
constructor() {
super({
assetA: sPOA.id,
assetABridge: '0x867949C3F2f66D827Ed40847FaA7B3a369370e13',
assetB: ksPOA.id,
assetBBridge: '0x99FB1a25caeB9c3a5Bf132686E2fe5e27BC0e2dd'
})
}
}

View File

@ -0,0 +1,13 @@
import { Mediator } from '@poanet/tokenbridge-bw-exchange'
import { Stake, xStake } from '../index'
export default class StakeBridge extends Mediator {
constructor() {
super({
assetA: xStake.id,
assetABridge: '0x', // TODO set address
assetB: Stake.id,
assetBBridge: '0x' // TODO set address
})
}
}

View File

@ -6,12 +6,14 @@
"private": true,
"scripts": {
"install": "lerna bootstrap",
"build": "lerna run --ignore wallet build",
"build": "lerna run --ignore wallet --ignore test-wallet build",
"lint": "eslint '*/**/*.{js,ts,tsx}'",
"start-wallet": "lerna run --parallel start-wallet"
"start-wallet": "lerna run --parallel start-wallet",
"start-test-wallet": "lerna run --parallel start-test-wallet"
},
"workspaces": [
"wallet",
"test-wallet",
"my-plugin"
],
"devDependencies": {

2
test-wallet/.env.example Normal file
View File

@ -0,0 +1,2 @@
REACT_APP_INFURA_KEY=
REACT_APP_PK=0x

44
test-wallet/package.json Normal file
View File

@ -0,0 +1,44 @@
{
"name": "test-wallet",
"version": "0.1.0",
"private": true,
"dependencies": {
"@burner-wallet/assets": "^1.1.10",
"@burner-wallet/core": "^1.1.9",
"@burner-wallet/exchange": "^1.1.3",
"@burner-wallet/metamask-plugin": "^1.0.1",
"@burner-wallet/modern-ui": "^1.0.7",
"@poanet/tokenbridge-bw-exchange": "^0.0.2",
"@types/node": "12.0.4",
"@types/react": "16.8.19",
"@types/react-dom": "16.8.4",
"@types/react-router-dom": "^4.3.3",
"my-plugin": "^1.0.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "^3.2.0",
"typescript": "3.5.1",
"web3": "1.0.0-beta.55"
},
"scripts": {
"start-test-wallet": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"axios": "^0.19.0"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

View File

@ -0,0 +1,15 @@
{
"short_name": "Burner Wallet",
"name": "Burner Wallet",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

44
test-wallet/src/index.tsx Normal file
View File

@ -0,0 +1,44 @@
import React from 'react'
import ReactDOM from 'react-dom'
import BurnerCore from '@burner-wallet/core'
import { InjectedSigner, LocalSigner } from '@burner-wallet/core/signers'
import { InfuraGateway, InjectedGateway } from '@burner-wallet/core/gateways'
import ModernUI from '@burner-wallet/modern-ui'
import Exchange from '@burner-wallet/exchange'
import MetamaskPlugin from '@burner-wallet/metamask-plugin'
import { ERC677Asset, Mediator, TokenBridgeGateway } from '@poanet/tokenbridge-bw-exchange'
const sStake = new ERC677Asset({
id: 'sstake',
name: 'sStake',
network: '77',
address: '0x' // TODO set address
})
const kStake = new ERC677Asset({
id: 'kstake',
name: 'kStake',
network: '42',
address: '0x' // TODO set address
})
const StakeBridgePair = new Mediator({
assetA: sStake.id,
assetABridge: '0x', // TODO set address
assetB: kStake.id,
assetBBridge: '0x' // TODO set address
})
const core = new BurnerCore({
signers: [new InjectedSigner(), new LocalSigner({ privateKey: process.env.REACT_APP_PK, saveKey: false })],
gateways: [new InjectedGateway(), new TokenBridgeGateway(), new InfuraGateway(process.env.REACT_APP_INFURA_KEY)],
assets: [sStake, kStake]
})
const exchange = new Exchange({
pairs: [StakeBridgePair]
})
const BurnerWallet = () => <ModernUI title="Burner Wallet" core={core} plugins={[exchange, new MetamaskPlugin()]} />
ReactDOM.render(<BurnerWallet />, document.getElementById('root'))

1
test-wallet/src/react-app-env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="react-scripts" />

25
test-wallet/tsconfig.json Normal file
View File

@ -0,0 +1,25 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve"
},
"include": [
"src"
]
}

View File

@ -1,7 +0,0 @@
## Scripts
`yarn start`: Run the local script, then start the wallet. The local script will transfer ETH into the wallet address if it has a balance of 0.
`yarn start-wallet`: Start the wallet without the local script.
`yarn install-all`: Runs `yarn install` in this package, and all local dependencies.

File diff suppressed because one or more lines are too long

View File

@ -1,14 +0,0 @@
const axios = require('axios')
let id = 0
const rpc = (url, method, ...params) =>
axios.post(url, { jsonrpc: '2.0', id: id++, method, params }).then(response => response.result)
module.exports.testRPC = url => async () => {
try {
const response = await rpc(url, 'eth_blockNumber')
return !!response
} catch (e) {
return false
}
}

View File

@ -1,89 +0,0 @@
const { spawn } = require('child_process')
const fs = require('fs')
const Web3 = require('web3')
const { testRPC } = require('./run-local-lib')
const utils = require('ethereumjs-util')
process.on('unhandledRejection', e => console.error(e))
const RPC = 'http://localhost:8545'
const PK_USER = '0xecb2222da7cbca080201acf6a7bbda53a3b2bcb22e3004b83ab8c69a884becb9'
const DEPLOYER_PK = '0x13179885a8731284475aa2317a35a292131772bb5aa33734a1290b8b13944409'
const DEPLOYER_ADDRESS = utils.bufferToHex(utils.privateToAddress(DEPLOYER_PK))
const ERC20_ADDRESS = utils.bufferToHex(utils.generateAddress(DEPLOYER_ADDRESS, '0'))
const getAccount = async web3 => {
const [defaultAccount] = await web3.eth.getAccounts()
if (!defaultAccount) {
throw new Error('Can not find an unlocked account')
}
return defaultAccount
}
;(async function() {
if (!(await testRPC(RPC))) {
throw new Error('Ganache not found on port 8545')
}
const web3 = new Web3(new Web3.providers.HttpProvider(RPC), null, {
transactionConfirmationBlocks: 1
})
const user = web3.eth.accounts.privateKeyToAccount(PK_USER)
const deployer = web3.eth.accounts.privateKeyToAccount(DEPLOYER_PK)
const balance = await web3.eth.getBalance(user.address)
console.log(balance, 'bal')
if (balance === '0') {
const defaultAccount = await getAccount(web3)
console.log(`Sending 1 ETH from ${defaultAccount} to ${user.address}`)
await web3.eth.sendTransaction({
from: defaultAccount,
to: user.address,
value: web3.utils.toWei('1', 'ether')
})
}
const collectableCode = await web3.eth.getCode(ERC20_ADDRESS)
if (collectableCode === '0x') {
console.log('ERC20 contract not found, deploying')
const defaultAccount = await getAccount(web3)
await web3.eth.sendTransaction({
from: defaultAccount,
to: deployer.address,
value: web3.utils.toWei('.2', 'ether')
})
// Deploy ERC20
const erc20Bytecode = fs.readFileSync(`${__dirname}/erc20bytecode.txt`, 'utf8')
const { rawTransaction: deployTx } = await deployer.signTransaction({
gas: '5000000',
data: erc20Bytecode
})
await web3.eth.sendSignedTransaction(deployTx)
// Transfer tokens to user
console.log('Transfering tokens')
const { rawTransaction: transferTx } = await deployer.signTransaction({
to: ERC20_ADDRESS,
gas: '5000000',
data: `0xa9059cbb000000000000000000000000${user.address.substr(
2
)}0000000000000000000000000000000000000000000000056bc75e2d63100000`
})
await web3.eth.sendSignedTransaction(transferTx)
}
spawn('yarn', ['start-wallet'], {
env: {
...process.env,
REACT_APP_PK: PK_USER,
REACT_APP_ERC20_ADDRESS: ERC20_ADDRESS
},
stdio: 'inherit'
})
})()

View File

@ -2,22 +2,21 @@ import React from 'react'
import ReactDOM from 'react-dom'
import BurnerCore from '@burner-wallet/core'
import { InjectedSigner, LocalSigner } from '@burner-wallet/core/signers'
import { InfuraGateway, InjectedGateway } from '@burner-wallet/core/gateways'
import { InfuraGateway, InjectedGateway, XDaiGateway } from '@burner-wallet/core/gateways'
import ModernUI from '@burner-wallet/modern-ui'
import Exchange from '@burner-wallet/exchange'
import MetamaskPlugin from '@burner-wallet/metamask-plugin'
import { TokenBridgeGateway } from '@poanet/tokenbridge-bw-exchange'
// Import resources from our plugin
import { sPOA, ksPOA, KSPOABridge } from 'my-plugin'
import { Stake, xStake, StakeBridge } from 'my-plugin'
const core = new BurnerCore({
signers: [new InjectedSigner(), new LocalSigner({ privateKey: process.env.REACT_APP_PK, saveKey: false })],
gateways: [new InjectedGateway(), new TokenBridgeGateway(), new InfuraGateway(process.env.REACT_APP_INFURA_KEY)],
assets: [sPOA, ksPOA]
gateways: [new InjectedGateway(), new XDaiGateway(), new InfuraGateway(process.env.REACT_APP_INFURA_KEY)],
assets: [Stake, xStake]
})
const exchange = new Exchange({
pairs: [new KSPOABridge()]
pairs: [new StakeBridge()]
})
const BurnerWallet = () => <ModernUI title="Burner Wallet" core={core} plugins={[exchange, new MetamaskPlugin()]} />