on master help sign in
lib: implement and use safe fromWei and toWei functions
c53aba4Fang
src/components/NeedFundsNotice.js+3−3
@@ -1,5 +1,5 @@
1import React from 'react';
1import React from 'react';
2−import { fromWei, toBN } from 'web3-utils';
2+import { safeFromWei } from '../lib/lib';
3
3
4import Highlighted from './Highlighted';
4import Highlighted from './Highlighted';
5import CopiableAddress from './CopiableAddress';
5import CopiableAddress from './CopiableAddress';
@@ -16,8 +16,8 @@ export default function NeedFundsNotice({
16 <WarningBox {...rest}>
16 <WarningBox {...rest}>
17 <Highlighted warning>
17 <Highlighted warning>
18 Your ownership address <CopiableAddress>{address}</CopiableAddress>{' '}
18 Your ownership address <CopiableAddress>{address}</CopiableAddress>{' '}
19− needs at least {fromWei(toBN(minBalance))} ETH and currently has{' '}
19+ needs at least {safeFromWei(minBalance)} ETH and currently has{' '}
20− {fromWei(toBN(balance))} ETH. The transaction will automatically resume
20+ {safeFromWei(balance)} ETH. The transaction will automatically resume
21 once enough ETH is available. Waiting... <Blinky />
21 once enough ETH is available. Waiting... <Blinky />
22 </Highlighted>
22 </Highlighted>
23 </WarningBox>
23 </WarningBox>
src/lib/error.js+3−3
@@ -1,4 +1,4 @@
1−import { fromWei, toBN } from 'web3-utils';
1+import { safeFromWei } from './lib';
2
2
3const BRIDGE_ERROR = {
3const BRIDGE_ERROR = {
4 MISSING_WEB3: 'no web3 object found',
4 MISSING_WEB3: 'no web3 object found',
@@ -18,13 +18,13 @@ const BRIDGE_ERROR = {
18const renderTxnError = (web3, msg) => {
18const renderTxnError = (web3, msg) => {
19 const txnCost = (web3, msg) => {
19 const txnCost = (web3, msg) => {
20 const costWei = msg.match(/upfront cost is: ([0-9]+)/);
20 const costWei = msg.match(/upfront cost is: ([0-9]+)/);
21− const costEth = fromWei(toBN(costWei[1]), 'ether');
21+ const costEth = safeFromWei(costWei[1], 'ether');
22 return parseFloat(costEth).toFixed(4);
22 return parseFloat(costEth).toFixed(4);
23 };
23 };
24
24
25 const acctBalance = (web3, msg) => {
25 const acctBalance = (web3, msg) => {
26 const balWei = msg.match(/sender's account only has: ([0-9]+)/);
26 const balWei = msg.match(/sender's account only has: ([0-9]+)/);
27− const balEth = fromWei(toBN(balWei[1]), 'ether');
27+ const balEth = safeFromWei(balWei[1], 'ether');
28 return parseFloat(balEth).toFixed(4);
28 return parseFloat(balEth).toFixed(4);
29 };
29 };
30
30
src/lib/lib.js+27
@@ -1,5 +1,30 @@
1import ob from 'urbit-ob';
1import ob from 'urbit-ob';
2import patp2dec from './patp2dec';
2import patp2dec from './patp2dec';
3+import { fromWei, toWei, toBN } from 'web3-utils';
4+
5+const safeFromWei = (num, target) => {
6+ try {
7+ return fromWei(toBN(num), target);
8+ } catch (e) {
9+ e.message =
10+ `(safeFromWei got ${typeof num} (${num}), made ${typeof toBN(
11+ num
12+ )}. Please report this issue!) ` + e.message;
13+ throw e;
14+ }
15+};
16+
17+const safeToWei = (num, source) => {
18+ try {
19+ return toWei(toBN(num), source);
20+ } catch (e) {
21+ e.message =
22+ `(safeToWei got ${typeof num} (${num}), made ${typeof toBN(
23+ num
24+ )}. Please report this issue!) ` + e.message;
25+ throw e;
26+ }
27+};
3
28
4const compose = (...fs) =>
29const compose = (...fs) =>
5 fs.reduceRight((pF, nF) => (...args) => nF(pF(...args)), v => v);
30 fs.reduceRight((pF, nF) => (...args) => nF(pF(...args)), v => v);
@@ -43,6 +68,8 @@ const patpStringLength = byteLength =>
43 byteLength * 3 + Math.ceil(byteLength / 2);
68 byteLength * 3 + Math.ceil(byteLength / 2);
44
69
45export {
70export {
71+ safeFromWei,
72+ safeToWei,
46 compose,
73 compose,
47 allFalse,
74 allFalse,
48 isLast,
75 isLast,
src/lib/reticket.js+3−2
@@ -12,7 +12,8 @@ import { addHexPrefix } from './wallet';
12import { sendAndAwaitAll } from './txn';
12import { sendAndAwaitAll } from './txn';
13import getSuggestedGasPrice from './getSuggestedGasPrice';
13import getSuggestedGasPrice from './getSuggestedGasPrice';
14import { GAS_LIMITS } from './constants';
14import { GAS_LIMITS } from './constants';
15−import { toWei, toBN } from 'web3-utils';
15+import { toBN } from 'web3-utils';
16+import { safeToWei } from './lib';
16
17
17// the initial network key revision is always 1
18// the initial network key revision is always 1
18const INITIAL_NETWORK_KEY_REVISION = 1;
19const INITIAL_NETWORK_KEY_REVISION = 1;
@@ -143,7 +144,7 @@ export async function reticketPointBetweenWallets({
143 progress(TRANSACTION_PROGRESS.SIGNING);
144 progress(TRANSACTION_PROGRESS.SIGNING);
144
145
145 const suggestedGasPrice = await getSuggestedGasPrice(networkType);
146 const suggestedGasPrice = await getSuggestedGasPrice(networkType);
146− const gasPrice = toWei(suggestedGasPrice.toFixed(), 'gwei');
147+ const gasPrice = safeToWei(suggestedGasPrice.toFixed(), 'gwei');
147 const gasPriceBN = toBN(gasPrice);
148 const gasPriceBN = toBN(gasPrice);
148 let totalCost = toBN(0);
149 let totalCost = toBN(0);
149 let inviteNonce = await web3.eth.getTransactionCount(fromWallet.address);
150 let inviteNonce = await web3.eth.getTransactionCount(fromWallet.address);
src/lib/txn.js+4−3
@@ -1,5 +1,6 @@
1import Tx from 'ethereumjs-tx';
1import Tx from 'ethereumjs-tx';
2−import { toWei, fromWei, toHex, toBN } from 'web3-utils';
2+import { toHex } from 'web3-utils';
3+import { safeFromWei, safeToWei } from './lib';
3import retry from 'async-retry';
4import retry from 'async-retry';
4
5
5import { NETWORK_TYPES } from './network';
6import { NETWORK_TYPES } from './network';
@@ -31,7 +32,7 @@ const signTransaction = async ({
31 // TODO: require these in txn object
32 // TODO: require these in txn object
32 nonce = toHex(nonce);
33 nonce = toHex(nonce);
33 chainId = toHex(chainId);
34 chainId = toHex(chainId);
34− gasPrice = toHex(toWei(gasPrice, 'gwei'));
35+ gasPrice = toHex(safeToWei(gasPrice, 'gwei'));
35 gasLimit = toHex(gasLimit);
36 gasLimit = toHex(gasLimit);
36
37
37 const txParams = { nonce, chainId, gasPrice, gasLimit };
38 const txParams = { nonce, chainId, gasPrice, gasLimit };
@@ -193,7 +194,7 @@ const getTxnInfo = async (web3, addr) => {
193 return {
194 return {
194 nonce: nonce,
195 nonce: nonce,
195 chainId: chainId,
196 chainId: chainId,
196− gasPrice: fromWei(toBN(gasPrice), 'gwei'),
197+ gasPrice: safeFromWei(gasPrice, 'gwei'),
197 };
198 };
198};
199};
199
200
src/lib/useEthereumTransaction.js+3−2
@@ -1,6 +1,6 @@
1import { useCallback, useEffect, useState } from 'react';
1import { useCallback, useEffect, useState } from 'react';
2import { Just } from 'folktale/maybe';
2import { Just } from 'folktale/maybe';
3−import { toWei, toBN } from 'web3-utils';
3+import { toBN } from 'web3-utils';
4
4
5import { useNetwork } from 'store/network';
5import { useNetwork } from 'store/network';
6import { useWallet } from 'store/wallet';
6import { useWallet } from 'store/wallet';
@@ -22,6 +22,7 @@ import { ensureFundsFor } from 'lib/tank';
22import useDeepEqualReference from 'lib/useDeepEqualReference';
22import useDeepEqualReference from 'lib/useDeepEqualReference';
23import useGasPrice from 'lib/useGasPrice';
23import useGasPrice from 'lib/useGasPrice';
24import timeout from 'lib/timeout';
24import timeout from 'lib/timeout';
25+import { safeToWei } from 'lib/lib';
25
26
26const STATE = {
27const STATE = {
27 NONE: 'NONE',
28 NONE: 'NONE',
@@ -148,7 +149,7 @@ export default function useEthereumTransaction(
148 const costGwei = toBN(gasLimit)
149 const costGwei = toBN(gasLimit)
149 .mul(toBN(gasPrice))
150 .mul(toBN(gasPrice))
150 .mul(toBN(rawTxs.length));
151 .mul(toBN(rawTxs.length));
151− const cost = toWei(costGwei.toString(), 'gwei');
152+ const cost = safeToWei(costGwei, 'gwei');
152 let usedTank = false;
153 let usedTank = false;
153 // if this ethereum transaction is being executed by a specific point
154 // if this ethereum transaction is being executed by a specific point
154 // see if we can use the tank
155 // see if we can use the tank
src/lib/useInviter.js+3−2
@@ -1,5 +1,5 @@
1import { useState, useCallback, useEffect } from 'react';
1import { useState, useCallback, useEffect } from 'react';
2−import { toWei, toBN } from 'web3-utils';
2+import { toBN } from 'web3-utils';
3import * as azimuth from 'azimuth-js';
3import * as azimuth from 'azimuth-js';
4import { FORM_ERROR } from 'final-form';
4import { FORM_ERROR } from 'final-form';
5
5
@@ -16,6 +16,7 @@ import {
16} from 'lib/txn';
16} from 'lib/txn';
17import useGasPrice from 'lib/useGasPrice';
17import useGasPrice from 'lib/useGasPrice';
18import { MIN_PLANET } from 'lib/constants';
18import { MIN_PLANET } from 'lib/constants';
19+import { safeToWei } from 'lib/lib';
19
20
20import { useNetwork } from 'store/network';
21import { useNetwork } from 'store/network';
21import { useWallet } from 'store/wallet';
22import { useWallet } from 'store/wallet';
@@ -148,7 +149,7 @@ const useInviter = () => {
148 _web3,
149 _web3,
149 point,
150 point,
150 _wallet.address,
151 _wallet.address,
151− toWei(totalCost.toString(), 'gwei'),
152+ safeToWei(totalCost, 'gwei'),
152 Object.keys(invites).map(name => invites[name].rawTx),
153 Object.keys(invites).map(name => invites[name].rawTx),
153 (address, minBalance, balance) =>
154 (address, minBalance, balance) =>
154 setNeedFunds({ address, minBalance, balance }),
155 setNeedFunds({ address, minBalance, balance }),