Add bw plugin assets (#387)

This commit is contained in:
Kirill Fedoseev 2020-07-07 21:26:14 +07:00 committed by GitHub
parent 861c755b09
commit 2edd8f2783
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 174 additions and 48 deletions

@ -2,19 +2,37 @@ 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 { XDaiBridge } from '@burner-wallet/exchange'
import { xdai } from '@burner-wallet/assets'
import { InfuraGateway, InjectedGateway, XDaiGateway } from '@burner-wallet/core/gateways'
import Exchange from '@burner-wallet/exchange'
import ModernUI from '@burner-wallet/modern-ui'
import { Etc, Wetc, TokenBridgeGateway, WETCBridge } from '@poanet/tokenbridge-bw-exchange'
import {
Etc,
Wetc,
Dai,
qDai,
MOON,
xMOON,
TokenBridgeGateway,
WETCBridge,
QDAIBridge,
MOONBridge
} from '@poanet/tokenbridge-bw-exchange'
import MetamaskPlugin from '@burner-wallet/metamask-plugin'
const core = new BurnerCore({
signers: [new InjectedSigner(), new LocalSigner()],
gateways: [new InjectedGateway(), new InfuraGateway(process.env.REACT_APP_INFURA_KEY), new TokenBridgeGateway()],
assets: [Wetc, Etc]
gateways: [
new InjectedGateway(),
new XDaiGateway(),
new InfuraGateway(process.env.REACT_APP_INFURA_KEY),
new TokenBridgeGateway()
],
assets: [xdai, Wetc, Etc, Dai, qDai, MOON, xMOON]
})
const exchange = new Exchange([new WETCBridge()])
const exchange = new Exchange([new XDaiBridge(), new WETCBridge(), new QDAIBridge(), new MOONBridge()])
const BurnerWallet = () => <ModernUI title="Staging Wallet" core={core} plugins={[exchange, new MetamaskPlugin()]} />

@ -93,8 +93,7 @@ if (process.env.REACT_APP_MODE === 'AMB_NATIVE_TO_ERC677') {
network: process.env.REACT_APP_FOREIGN_NETWORK,
// @ts-ignore
address: process.env.REACT_APP_FOREIGN_TOKEN_ADDRESS,
// @ts-ignore
bridgeAddress: process.env.REACT_APP_FOREIGN_MEDIATOR_ADDRESS
bridgeModes: ['erc-to-native-amb']
})
testBridge = new MediatorErcToNative({

@ -0,0 +1,12 @@
import { Mediator } from '../burner-wallet'
export default class MOONBridge extends Mediator {
constructor() {
super({
assetA: 'xmoon',
assetABridge: '0x1E0507046130c31DEb20EC2f870ad070Ff266079',
assetB: 'moon',
assetBBridge: '0xFEaB457D95D9990b7eb6c943c839258245541754'
})
}
}

@ -0,0 +1,12 @@
import { MediatorErcToNative } from '../burner-wallet'
export default class QDAIBridge extends MediatorErcToNative {
constructor() {
super({
assetA: 'qdai',
assetABridge: '0xFEaB457D95D9990b7eb6c943c839258245541754',
assetB: 'dai',
assetBBridge: '0xf6edFA16926f30b0520099028A145F4E06FD54ed'
})
}
}

@ -1,6 +1,6 @@
import { Mediator } from '../burner-wallet'
import { HOME_NATIVE_TO_ERC_ABI, FOREIGN_NATIVE_TO_ERC_ABI } from '../utils'
import { waitForEvent, isBridgeContract, constants } from '../utils'
import { waitForEvent, isVanillaBridgeContract, constants } from '../utils'
import { ValueTypes } from '@burner-wallet/exchange'
import { toBN, fromWei } from 'web3-utils'
@ -19,7 +19,7 @@ export default class WETCBridge extends Mediator {
.getAsset(this.assetA)
.getWeb3()
const contract = new web3.eth.Contract(HOME_NATIVE_TO_ERC_ABI, this.assetABridge)
const listenToBridgeEvent = await isBridgeContract(contract)
const listenToBridgeEvent = await isVanillaBridgeContract(contract)
if (listenToBridgeEvent) {
await waitForEvent(web3, contract, 'AffirmationCompleted', this.processBridgeEvents(sendResult.txHash))
} else {
@ -32,7 +32,7 @@ export default class WETCBridge extends Mediator {
.getAsset(this.assetB)
.getWeb3()
const contract = new web3.eth.Contract(FOREIGN_NATIVE_TO_ERC_ABI, this.assetBBridge)
const listenToBridgeEvent = await isBridgeContract(contract)
const listenToBridgeEvent = await isVanillaBridgeContract(contract)
if (listenToBridgeEvent) {
await waitForEvent(web3, contract, 'RelayedMessage', this.processBridgeEvents(sendResult.txHash))
} else {
@ -53,7 +53,7 @@ export default class WETCBridge extends Mediator {
.getWeb3()
const contract = new web3.eth.Contract(FOREIGN_NATIVE_TO_ERC_ABI, this.assetBBridge)
const useBridgeContract = await isBridgeContract(contract)
const useBridgeContract = await isVanillaBridgeContract(contract)
if (useBridgeContract) {
const fee = toBN(await contract.methods.getHomeFee().call())
@ -79,7 +79,7 @@ export default class WETCBridge extends Mediator {
.getWeb3()
const contract = new web3.eth.Contract(HOME_NATIVE_TO_ERC_ABI, this.assetABridge)
const useBridgeContract = await isBridgeContract(contract)
const useBridgeContract = await isVanillaBridgeContract(contract)
if (useBridgeContract) {
const fee = toBN(await contract.methods.getForeignFee().call())

@ -0,0 +1,3 @@
export { default as WETCBridge } from './WETCBridge'
export { default as QDAIBridge } from './QDAIBridge'
export { default as MOONBridge } from './MOONBridge'

@ -1,42 +1,55 @@
import { ERC20Asset } from '@burner-wallet/assets'
import { MEDIATOR_ABI, constants } from '../../utils'
import { toBN } from 'web3-utils'
import { AssetConstructor } from '@burner-wallet/assets/Asset'
import { MEDIATOR_ABI, constants, isBridgeContract } from '../../utils'
import { toBN, soliditySha3 } from 'web3-utils'
interface BridgeableERC20Constructor {
interface BridgeableERC20Constructor extends AssetConstructor {
abi?: object
address: string
id: string
name: string
network: string
bridgeAddress: string
bridgeModes: string[]
}
export default class BridgeableERC20Asset extends ERC20Asset {
protected bridgeAddress: string
private _bridge
private _bridgeModes
private _bridges: { [addr: string]: object | false }
constructor({ bridgeAddress, ...params }: BridgeableERC20Constructor) {
super({ ...params })
this.bridgeAddress = bridgeAddress.toLowerCase()
public set bridgeModes(bridgeModes: string[]) {
this._bridgeModes = bridgeModes.map(s => soliditySha3(s)!.slice(0, 10))
}
getBridgeContract() {
if (!this._bridge) {
public get bridgeModes() {
return this._bridgeModes
}
constructor({
bridgeModes = ['erc-to-native-core', 'erc-to-native-amb', 'erc-to-erc-core', 'erc-to-erc-amb'],
...params
}: BridgeableERC20Constructor) {
super(params)
this._bridges = {}
this.bridgeModes = bridgeModes
}
async getBridgeContract(addr: string) {
if (typeof this._bridges[addr] === 'undefined') {
const Contract = this.getWeb3().eth.Contract
this._bridge = new Contract(MEDIATOR_ABI, this.bridgeAddress)
const bridge = new Contract(MEDIATOR_ABI, addr)
if (await isBridgeContract(bridge, this.bridgeModes)) {
return (this._bridges[addr] = bridge)
}
return (this._bridges[addr] = false)
}
return this._bridge
return this._bridges[addr]
}
async _send({ from, to, value }) {
if (to.toLowerCase() === this.bridgeAddress) {
const bridge = await this.getBridgeContract(to)
if (bridge) {
const allowance = await this.allowance(from, to)
if (toBN(allowance).lt(toBN(value))) {
await this.approve(from, to, value)
}
const receipt = await this.getBridgeContract()
.methods.relayTokens(from, value)
.send({ from })
const receipt = await bridge.methods.relayTokens(from, value).send({ from })
const transferLog = Object.values(receipt.events as object).find(
e => e.raw.topics[0] === constants.TRANSFER_TOPIC
)

@ -0,0 +1,11 @@
import BridgeableERC20Asset from './BridgeableERC20Asset'
export default new BridgeableERC20Asset({
id: 'dai',
name: 'Dai',
network: '1',
address: '0x6b175474e89094c44da98b954eedeac495271d0f',
usdPrice: 1,
icon: 'https://static.burnerfactory.com/icons/mcd.svg',
bridgeModes: ['erc-to-native-amb']
})

@ -1,14 +1,12 @@
import { ERC20Asset } from '@burner-wallet/assets'
import { AssetConstructor } from '@burner-wallet/assets/Asset'
import { ERC677_ABI, constants } from '../../utils'
const BLOCK_LOOKBACK = 250
interface ERC677Constructor {
interface ERC677Constructor extends AssetConstructor {
abi?: object
address: string
id: string
name: string
network: string
}
export default class ERC677Asset extends ERC20Asset {

@ -1,5 +1,5 @@
import NativeMediatorAsset from './NativeMediatorAsset'
import { isBridgeContract, HOME_NATIVE_TO_ERC_ABI } from '../../utils'
import { isVanillaBridgeContract, HOME_NATIVE_TO_ERC_ABI } from '../../utils'
class EtcNativeAsset extends NativeMediatorAsset {
constructor(props) {
@ -9,7 +9,7 @@ class EtcNativeAsset extends NativeMediatorAsset {
async scanMediatorEvents(address, fromBlock, toBlock) {
const web3 = this.getWeb3()
const contract = new web3.eth.Contract(HOME_NATIVE_TO_ERC_ABI, this.mediatorAddress)
const listenToBridgeEvent = await isBridgeContract(contract)
const listenToBridgeEvent = await isVanillaBridgeContract(contract)
if (listenToBridgeEvent && this.mediatorAddress != '') {
const events = await contract.getPastEvents('AffirmationCompleted', {
fromBlock,

@ -0,0 +1,10 @@
import BridgeableERC20Asset from './BridgeableERC20Asset'
export default new BridgeableERC20Asset({
id: 'moon',
name: 'MOON',
network: '4',
address: '0xDF82c9014F127243CE1305DFE54151647d74B27A',
icon: 'https://blockscout.com/poa/xdai/images/icons/moon.png',
bridgeModes: ['erc-to-erc-amb']
})

@ -1,12 +1,10 @@
import { NativeAsset } from '@burner-wallet/assets'
import { Contract, EventData } from 'web3-eth-contract'
import { MEDIATOR_ABI } from '../../utils'
import { AssetConstructor } from '@burner-wallet/assets/Asset'
interface NativeMediatorConstructor {
interface NativeMediatorConstructor extends AssetConstructor {
mediatorAddress?: string
id: string
name: string
network: string
}
export default class NativeMediatorAsset extends NativeAsset {

@ -0,0 +1,9 @@
import NativeMediatorAsset from './NativeMediatorAsset'
export default new NativeMediatorAsset({
id: 'qdai',
name: 'qDai',
network: '181',
usdPrice: 1,
mediatorAddress: '0xFEaB457D95D9990b7eb6c943c839258245541754'
})

@ -0,0 +1,9 @@
import { default as ERC677Asset } from './ERC677Asset'
export default new ERC677Asset({
id: 'xmoon',
name: 'xMOON',
network: '100',
address: '0x1e16aa4Df73d29C029d94CeDa3e3114EC191E25A',
icon: 'https://blockscout.com/poa/xdai/images/icons/moon.png'
})

@ -9,7 +9,8 @@ export default class TokenBridgeGateway extends Gateway {
this.providerStrings = {
'61': `https://www.ethercluster.com/etc`,
'77': 'https://sokol.poa.network',
'99': 'https://core.poa.network'
'99': 'https://core.poa.network',
'181': 'https://quorum-rpc.tokenbridge.net'
}
this.providers = {}
}
@ -19,7 +20,7 @@ export default class TokenBridgeGateway extends Gateway {
}
getNetworks() {
return ['61', '77', '99']
return ['61', '77', '99', '181']
}
_provider(network) {

@ -1,6 +1,10 @@
export { default as sPOA } from './assets/sPOA'
export { default as Etc } from './assets/Etc'
export { default as Wetc } from './assets/Wetc'
export { default as Dai } from './assets/Dai'
export { default as qDai } from './assets/qDai'
export { default as MOON } from './assets/MOON'
export { default as xMOON } from './assets/xMOON'
export { default as ERC677Asset } from './assets/ERC677Asset'
export { default as BridgeableERC20Asset } from './assets/BridgeableERC20Asset'
export { default as NativeMediatorAsset } from './assets/NativeMediatorAsset'

@ -5,8 +5,12 @@ export {
sPOA,
Etc,
Wetc,
qDai,
Dai,
MOON,
xMOON,
TokenBridgeGateway,
Mediator,
MediatorErcToNative
} from './burner-wallet'
export { WETCBridge } from './wetc-bridge'
export { WETCBridge, QDAIBridge, MOONBridge } from './bridges'

@ -52,5 +52,19 @@ export default [
payable: false,
stateMutability: 'nonpayable',
type: 'function'
},
{
constant: true,
inputs: [],
name: 'getBridgeMode',
outputs: [
{
name: '',
type: 'bytes4'
}
],
payable: false,
stateMutability: 'pure',
type: 'function'
}
]

@ -1,4 +1,4 @@
export { constants, wait, waitForEvent, isBridgeContract } from './utils'
export { constants, wait, waitForEvent, isVanillaBridgeContract, isBridgeContract } from './utils'
export {
ERC677_ABI,
FOREIGN_NATIVE_TO_ERC_ABI,

@ -34,7 +34,7 @@ export const waitForEvent = async (web3, contract: Contract, event: string, call
}
}
export const isBridgeContract = async (contract: Contract): Promise<boolean> => {
export const isVanillaBridgeContract = async (contract: Contract): Promise<boolean> => {
try {
await contract.methods.deployedAtBlock().call()
return true
@ -42,3 +42,15 @@ export const isBridgeContract = async (contract: Contract): Promise<boolean> =>
return false
}
}
export const isBridgeContract = async (contract: Contract, allowedModes?: string[]): Promise<boolean> => {
try {
const mode = await contract.methods.getBridgeMode().call()
if (typeof allowedModes === 'undefined') {
return true
}
return allowedModes.includes(mode)
} catch (e) {
return false
}
}

@ -1 +0,0 @@
export { default as WETCBridge } from './WETCBridge'