Cleanup, start adding helper funcs (WIP)

This commit is contained in:
emizzle 2019-06-13 18:28:44 +10:00
parent 07c245dbbb
commit 46fb2903b7
No known key found for this signature in database
GPG Key ID: 1FD4BAB3C37EE9BA
3 changed files with 71 additions and 85 deletions

View File

@ -53,7 +53,8 @@
"@omisego/omg-js": "2.0.0-v0.2",
"@omisego/omg-js-childchain": "2.0.0-v0.2",
"@omisego/omg-js-rootchain": "2.0.0-v0.2",
"@omisego/omg-js-util": "2.0.0-v0.2"
"@omisego/omg-js-util": "2.0.0-v0.2",
"human-standard-token-abi": "2.0.0"
},
"devDependencies": {
"@babel/cli": "7.2.3",

View File

@ -1,4 +1,3 @@
/* global web3, ethereum */
import {
confirmTransaction,
normalizeUrl,
@ -9,6 +8,7 @@ import BigNumber from "bn.js";
import ChildChain from "@omisego/omg-js-childchain";
import RootChain from "@omisego/omg-js-rootchain";
import { transaction } from "@omisego/omg-js-util";
const erc20abi = require("human-standard-token-abi");
const web3Options = { transactionConfirmationBlocks: 1 };
@ -17,70 +17,43 @@ export default class BaseEmbarkOmg {
this.logger = logger;
this.initing = false;
this.inited = false;
this.address = "";
this.addressPrivateKey = "";
this.account = {
address: "",
rootBalance: 0,
childBalance: 0
};
this.account.addressPrivateKey = "";
this.maxDeposit = 0;
// plugin opts
this.plasmaContractAddress =
pluginConfig.PLASMA_CONTRACT_ADDRESS ||
"0x740ecec4c0ee99c285945de8b44e9f5bfb71eea7";
this.watcherUrl = normalizeUrl(
pluginConfig.WATCHER_URL || "https://watchersamrong.omg.network/"
);
this.childChainUrl = normalizeUrl(
pluginConfig.CHILDCHAIN_URL || "https://samrong.omg.network/"
);
this.childChainExplorerUrl = normalizeUrl(
pluginConfig.CHILDCHAIN_EXPLORER_URL ||
"https://quest.samrong.omg.network"
);
}
async initWeb3() {
if (window.ethereum) {
this.web3 = new Web3(window.ethereum, null, web3Options);
try {
// Request account access
await ethereum.enable();
return true;
} catch (err) {
// User denied account access :(
console.error(err);
}
} else if (window.web3) {
this.web3 = new Web3(window.web3.currentProvider, null, web3Options);
return true;
}
// No web3...
return false;
this.plasmaContractAddress = pluginConfig.PLASMA_CONTRACT_ADDRESS || "0x740ecec4c0ee99c285945de8b44e9f5bfb71eea7";
this.watcherUrl = normalizeUrl(pluginConfig.WATCHER_URL || "https://watcher.samrong.omg.network/");
this.childChainUrl = normalizeUrl(pluginConfig.CHILDCHAIN_URL || "https://samrong.omg.network/");
this.childChainExplorerUrl = normalizeUrl(pluginConfig.CHILDCHAIN_EXPLORER_URL || "https://quest.samrong.omg.network");
}
async init(web3) {
//}, web3Path) {
try {
if (this.initing) {
const message = "Already intializing the Plasma chain, please wait...";
throw new Error(message);
}
this.initing = true;
this.web3 = web3;
// if (!(await this.initWeb3())) {
this.web3 = web3;
// }
let accounts = await this.web3.eth.getAccounts();
this.address = accounts.length > 1 ? accounts[1] : accounts[0]; // ignore the first account because it is our deployer account, we want the manually added account
const address = accounts.length > 1 ? accounts[1] : accounts[0]; // ignore the first account because it is our deployer account, we want the manually added account
this.account.address = address;
// check account balance on the main chain
// try {
// this.maxDeposit = await this.web3.eth.getBalance(this.address);
// this.maxDeposit = await this.web3.eth.getBalance(this.account.address);
// if (!this.maxDeposit || new BigNumber(this.maxDeposit).lte(0)) {
// throw new Error("The configured account does not have enough funds. Please make sure this account has Rinkeby ETH.");
// }
// this.maxDeposit = new BigNumber(this.maxDeposit);
// }
// catch (e) {
// this.logger.warn(`Error getting balance for account ${this.address}: ${e}`);
// this.logger.warn(`Error getting balance for account ${this.account.address}: ${e}`);
// }
// set up the Plasma chain
@ -113,26 +86,24 @@ export default class BaseEmbarkOmg {
}
// if (amount.gt(this.maxDeposit) && this.maxDeposit.gt(0)) {
// // recheck balance in case it was updated in a recent tx
// this.maxDeposit = await this.web3.eth.getBalance(this.address);
// this.maxDeposit = await this.web3.eth.getBalance(this.account.address);
// if (amount.gt(this.maxDeposit)) {
// const message = `You do not have enough funds for this deposit. Please deposit more funds in to ${this.address} and then try again.`;
// const message = `You do not have enough funds for this deposit. Please deposit more funds in to ${this.account.address} and then try again.`;
// throw new Error(message);
// }
// }
// Create the deposit transaction
const depositTx = transaction.encodeDeposit(this.address, amount, currency);
const depositTx = transaction.encodeDeposit(this.account.address, amount, currency);
if (currency === transaction.ETH_CURRENCY) {
this.logger.info(`Depositing ${amount} wei...`);
// ETH deposit
try {
const receipt = await this.rootChain.depositEth(depositTx, amount, {
from: this.address
});
const receipt = await this.rootChain.depositEth(depositTx, amount, { from: this.account.address });
this.logger.trace(receipt);
const message = `Successfully deposited ${amount} wei in to the Plasma chain.\nView the transaction: https://rinkeby.etherscan.io/tx/${
receipt.transactionHash
}`;
}`;
return message;
} catch (e) {
const message = `Error depositing ${amount} wei: ${e}`;
@ -150,18 +121,14 @@ export default class BaseEmbarkOmg {
const gasPrice = 1000000;
const receipt = await erc20.methods
.approve(this.rootChain.plasmaContractAddress, amount)
.send({ from: this.address, gasPrice, gas: 2000000 });
.send({ from: this.account.address, gasPrice, gas: 2000000 });
// Wait for the approve tx to be mined
this.logger.info(
`${amount} erc20 approved: ${
receipt.transactionHash
}. Waiting for confirmation...`
);
this.logger.info(`${amount} erc20 approved: ${receipt.transactionHash}. Waiting for confirmation...`);
await confirmTransaction(this.web3, receipt.transactionHash);
this.logger.info(`... ${receipt.transactionHash} confirmed.`);
}
return this.rootChain.depositToken(depositTx, { from: this.address });
return this.rootChain.depositToken(depositTx, { from: this.account.address });
}
async transfer(toAddress, amount) {
@ -169,9 +136,7 @@ export default class BaseEmbarkOmg {
const currency = transaction.ETH_CURRENCY;
const verifyingContract = this.plasmaContractAddress;
const transferZeroFee = currency !== transaction.ETH_CURRENCY;
const utxos = await this.childChain.getUtxos(this.address);
const utxosToSpend = selectUtxos(utxos, amount, currency, transferZeroFee);
const utxosToSpend = await selectUtxos(amount, currency);
if (!utxosToSpend) {
throw new Error(`No utxo big enough to cover the amount ${amount}`);
}
@ -192,16 +157,16 @@ export default class BaseEmbarkOmg {
// Need to add a 'change' output
const CHANGE_AMOUNT = bnAmount.sub(new BigNumber(amount));
txBody.outputs.push({
owner: this.address,
owner: this.account.address,
currency,
amount: CHANGE_AMOUNT
});
}
if (transferZeroFee && utxosToSpend.length > 1) {
if (currency !== transaction.ETH_CURRENCY && utxosToSpend.length > 1) {
// The fee input can be returned
txBody.outputs.push({
owner: this.address,
owner: this.account.address,
currency: utxosToSpend[utxosToSpend.length - 1].currency,
amount: utxosToSpend[utxosToSpend.length - 1].amount
});
@ -217,15 +182,10 @@ export default class BaseEmbarkOmg {
//
const signature = await signTypedData(
this.web3,
this.web3.utils.toChecksumAddress(this.address),
this.web3.utils.toChecksumAddress(this.account.address),
JSON.stringify(typedData)
);
// const signer = this.web3.utils.toChecksumAddress(this.address);
// const data = JSON.stringify(typedData);
// const signature = this.web3.currentProvider.send("eth_signTypedData_v3", [
// signer,
// data
// ]);
const sigs = new Array(utxosToSpend.length).fill(signature);
// Build the signed transaction
@ -237,7 +197,7 @@ export default class BaseEmbarkOmg {
result
)}\nView the transaction: ${this.childChainExplorerUrl}transaction/${
result.txhash
}`;
}`;
return message;
}
@ -248,8 +208,6 @@ export default class BaseEmbarkOmg {
const message = `No UTXOs found on the Plasma chain for ${fromAddress}.`;
throw new Error(message);
}
// NB This only exits the first UTXO.
// Selecting _which_ UTXO to exit is left as an exercise for the reader...
const errors = [];
utxos.forEach(async utxo => {
const exitData = await this.childChain.getExitData(utxo);
@ -265,9 +223,9 @@ export default class BaseEmbarkOmg {
);
return `Exited UTXO from address ${fromAddress} with value ${
utxo.amount
}. View the transaction: https://rinkeby.etherscan.io/tx/${
}. View the transaction: https://rinkeby.etherscan.io/tx/${
receipt.transactionHash
}`;
}`;
} catch (e) {
const message = `Error exiting the Plasma chain for UTXO ${JSON.stringify(
utxo
@ -280,14 +238,36 @@ export default class BaseEmbarkOmg {
}
}
selectUtxos(utxos, amount, currency) {
const correctCurrency = utxos.filter(utxo => utxo.currency === currency);
// Just find the first utxo that can fulfill the amount
const selected = correctCurrency.find(utxo =>
new BigNumber(utxo.amount).gte(new BigNumber(amount))
);
if (selected) {
return [selected];
}
async selectUtxos(amount, currency) {
const transferZeroFee = currency !== transaction.ETH_CURRENCY;
const utxos = await this.childChain.getUtxos(this.account.address);
return selectUtxos(utxos, amount, currency, transferZeroFee);
}
async getTransactions() {
return this.childChain.getTransactions({
address: this.account.address
});
}
async getBalances() {
this.account.rootBalance = await this.web3.eth.getBalance(this.account.address);
const childchainBalance = await this.childChain.getBalance(this.account.address);
this.account.childBalance = await Promise.all(childchainBalance.map(
async (balance) => {
if (balance.currency === transaction.ETH_CURRENCY) {
balance.symbol = 'wei';
} else {
const tokenContract = new this.web3.eth.Contract(erc20abi, balance.currency);
try {
balance.symbol = await tokenContract.methods.symbol().call();
} catch (err) {
balance.symbol = 'Unknown ERC20';
}
}
return balance;
}
))
}
}

View File

@ -1926,6 +1926,11 @@ hosted-git-info@^2.1.4:
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047"
integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==
human-standard-token-abi@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/human-standard-token-abi/-/human-standard-token-abi-2.0.0.tgz#e0c2057596d0a1d4a110f91f974a37f4b904f008"
integrity sha512-m1f5DiIvqaNmpgphNqx2OziyTCj4Lvmmk28uMSxGWrOc9/lMpAKH8UcMPhvb13DMNZPzxn07WYFhxOGKuPLryg==
iconv-lite@^0.4.17, iconv-lite@^0.4.4:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"