Cleanup, start adding helper funcs (WIP)
This commit is contained in:
parent
07c245dbbb
commit
46fb2903b7
|
@ -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",
|
||||
|
|
148
src/index.js
148
src/index.js
|
@ -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;
|
||||
}
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue