mirror of
https://github.com/status-im/MyCrypto.git
synced 2025-01-10 19:16:10 +00:00
Address messages, warnings and gas limits (#930)
* Move address messages to config folder, add some other messages for common pitfalls. * Fix checksum vs lowercase issues. * Use gas limit if an address message specified one. Allow messages to have a custom severity. Add a function for getting message to reduce complexity. * Handle address message gas limit on all actions, make separate saga fn. * Apparently I used the wrong takeEvery?
This commit is contained in:
parent
d1a2c885a2
commit
9ee30b957d
103
common/components/CurrentCustomMessage.tsx
Normal file
103
common/components/CurrentCustomMessage.tsx
Normal file
@ -0,0 +1,103 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { AppState } from 'reducers';
|
||||
import { getCurrentTo, ICurrentTo } from 'selectors/transaction';
|
||||
import { getAllTokens } from 'selectors/config';
|
||||
import { getWalletInst } from 'selectors/wallet';
|
||||
import { getAddressMessage, Token } from 'config';
|
||||
|
||||
interface ReduxProps {
|
||||
currentTo: ICurrentTo;
|
||||
tokens: Token[];
|
||||
wallet: AppState['wallet']['inst'];
|
||||
}
|
||||
|
||||
interface State {
|
||||
walletAddress: string | null;
|
||||
}
|
||||
|
||||
class CurrentCustomMessageClass extends PureComponent<ReduxProps, State> {
|
||||
public state: State = {
|
||||
walletAddress: null
|
||||
};
|
||||
|
||||
public async componentDidMount() {
|
||||
if (this.props.wallet) {
|
||||
const walletAddress = await this.props.wallet.getAddressString();
|
||||
this.setState({ walletAddress });
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const message = this.getMessage();
|
||||
if (message) {
|
||||
return (
|
||||
<div className="clearfix form-group">
|
||||
<div className={`alert alert-${message.severity} col-xs-12`}>{message.message}</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private getMessage() {
|
||||
const { currentTo, tokens } = this.props;
|
||||
const { walletAddress } = this.state;
|
||||
// Make sure all comparisons are lower-cased.
|
||||
const address = currentTo.raw.toLowerCase();
|
||||
|
||||
let message;
|
||||
let severity;
|
||||
|
||||
// First check against our hard-coded messages
|
||||
const msg = getAddressMessage(address);
|
||||
if (msg) {
|
||||
message = (
|
||||
<React.Fragment>
|
||||
<p>
|
||||
<small>
|
||||
A message regarding <strong>{address}</strong>:
|
||||
</small>
|
||||
</p>
|
||||
<p>{msg.msg}</p>
|
||||
</React.Fragment>
|
||||
);
|
||||
severity = msg.severity || 'info';
|
||||
}
|
||||
|
||||
// Otherwise check if any of our tokens match the address
|
||||
if (!message) {
|
||||
const token = tokens.find(tk => tk.address.toLowerCase() === address);
|
||||
if (token) {
|
||||
message = `
|
||||
You’re currently sending to the ${token.symbol} contract. If you
|
||||
wanted to send ${token.symbol} to an address, change the To Address to
|
||||
where you want it to go, make sure you have a positive ${token.symbol}
|
||||
balance in your wallet, and select it from the dropdown next to the
|
||||
Amount field.
|
||||
`;
|
||||
severity = 'warning';
|
||||
}
|
||||
}
|
||||
|
||||
// Finally check if they're sending to themselves (lol)
|
||||
if (walletAddress === address) {
|
||||
message = 'You’re sending to yourself. Are you sure you want to do that?';
|
||||
severity = 'warning';
|
||||
}
|
||||
|
||||
if (message) {
|
||||
return {
|
||||
message,
|
||||
severity
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const CurrentCustomMessage = connect((state: AppState): ReduxProps => ({
|
||||
currentTo: getCurrentTo(state),
|
||||
tokens: getAllTokens(state),
|
||||
wallet: getWalletInst(state)
|
||||
}))(CurrentCustomMessageClass);
|
@ -1,18 +0,0 @@
|
||||
import { CustomMessage, messages } from './components';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { AppState } from 'reducers';
|
||||
import { getCurrentTo, ICurrentTo } from 'selectors/transaction';
|
||||
|
||||
interface StateProps {
|
||||
currentTo: ICurrentTo;
|
||||
}
|
||||
class CurrentCustomMessageClass extends Component<StateProps> {
|
||||
public render() {
|
||||
return <CustomMessage message={messages.find(m => m.to === this.props.currentTo.raw)} />;
|
||||
}
|
||||
}
|
||||
|
||||
export const CurrentCustomMessage = connect((state: AppState) => ({
|
||||
currentTo: getCurrentTo(state)
|
||||
}))(CurrentCustomMessageClass);
|
@ -1,25 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
interface Props {
|
||||
message?: {
|
||||
to: string;
|
||||
msg: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const CustomMessage = (props: Props) => {
|
||||
return (
|
||||
<div className="clearfix form-group">
|
||||
{!!props.message && (
|
||||
<div className="alert alert-info col-xs-12 clearfix">
|
||||
<p>
|
||||
<small>A message from {props.message.to}</small>
|
||||
</p>
|
||||
<p>
|
||||
<strong>{props.message.msg}</strong>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,2 +0,0 @@
|
||||
export * from './CustomMessage';
|
||||
export * from './messages';
|
@ -1,30 +0,0 @@
|
||||
export const messages = [
|
||||
{
|
||||
// donation address example
|
||||
to: '0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8',
|
||||
gasLimit: 21000,
|
||||
data: '',
|
||||
msg: 'Thank you for donating to MyEtherWallet. TO THE MOON!'
|
||||
},
|
||||
{
|
||||
// BAT
|
||||
to: '0x0D8775F648430679A709E98d2b0Cb6250d2887EF',
|
||||
gasLimit: 200000,
|
||||
data: '0xb4427263',
|
||||
msg: 'BAT. THE SALE IS OVER. STOP CLOGGING THE BLOCKCHAIN PLEASE'
|
||||
},
|
||||
{
|
||||
// BANCOR
|
||||
to: '0x00000',
|
||||
gasLimit: 200000,
|
||||
data: '',
|
||||
msg: 'Bancor. Starts June XX, 2017.'
|
||||
},
|
||||
{
|
||||
// Moeda
|
||||
to: '0x4870E705a3def9DDa6da7A953D1cd3CCEDD08573',
|
||||
gasLimit: 200000,
|
||||
data: '',
|
||||
msg: 'Moeda. Ends at block 4,111,557.'
|
||||
}
|
||||
];
|
@ -1 +0,0 @@
|
||||
export * from './CurrentCustomMessage';
|
189
common/config/addressMessages.ts
Normal file
189
common/config/addressMessages.ts
Normal file
@ -0,0 +1,189 @@
|
||||
import { toChecksumAddress } from 'ethereumjs-util';
|
||||
|
||||
export interface AddressMessage {
|
||||
msg: string;
|
||||
gasLimit?: number;
|
||||
data?: string;
|
||||
severity?: 'warning' | 'danger' | 'success' | 'info';
|
||||
}
|
||||
|
||||
// MAKE SURE THE ADDRESS KEY IS EITHER LOWER CASED OR CHECKSUMMED.
|
||||
export const ADDRESS_MESSAGES: { [key: string]: AddressMessage } = {
|
||||
'0x7cb57b5a97eabe94205c07890be4c1ad31e486a8': {
|
||||
msg: 'Thank you for donating to MyEtherWallet. TO THE MOON!'
|
||||
},
|
||||
'0x75aa7b0d02532f3833b66c7f0ad35376d373ddf8': {
|
||||
gasLimit: 300000,
|
||||
msg: 'Accord (ARD) ERC20 token sale - http://accordtoken.com'
|
||||
},
|
||||
'0x16b0e62ac13a2faed36d18bce2356d25ab3cfad3': {
|
||||
gasLimit: 200000,
|
||||
msg:
|
||||
"BTQ ICO ends February 1, 2018. btc btq is your exclusive bitcoin boutique and world's premier cryptocurrency lifestyle brand. https://thebtcbtq.com/btq"
|
||||
},
|
||||
'0xa9877b1e05d035899131dbd1e403825166d09f92': {
|
||||
gasLimit: 200000,
|
||||
msg: 'MNT Token Sale - http://mnt.coinjoker.com'
|
||||
},
|
||||
'0xef6b4ce8c9bc83744fbcde2657b32ec18790458a': {
|
||||
gasLimit: 930000,
|
||||
msg: 'PUC Token Sale - http://price-s.info'
|
||||
},
|
||||
'0x13f11c9905a08ca76e3e853be63d4f0944326c72': {
|
||||
gasLimit: 300000,
|
||||
data: '0xb4427263',
|
||||
msg: 'DIVX Token Sale - www.diviproject.org'
|
||||
},
|
||||
'0x4b0712de9b75bc68a566215acca876ea5e55c172': {
|
||||
gasLimit: 114293,
|
||||
msg: 'NOX Token Sale'
|
||||
},
|
||||
'0xf5dffdeaea54bb56156b47de1c7b4346c7dba69c': {
|
||||
gasLimit: 180000,
|
||||
msg: 'GEE Token Sale'
|
||||
},
|
||||
'0xc88c7e1aebd89187d13bd42e1ff814d32f492bf6': {
|
||||
gasLimit: 250000,
|
||||
msg:
|
||||
'STORM token sale: gamified micro-tasks - Earn anywhere, anytime, from any device. https://www.stormtoken.com, NOV 7, 2017'
|
||||
},
|
||||
'0xdd64ef0c8a41d8a17f09ce2279d79b3397184a10': {
|
||||
gasLimit: 200000,
|
||||
msg:
|
||||
'RVL token sale: PRE-ICO SUPER SALE, SHARING ECONOMY PIATTAFORM, https://www.R-EVOLUTIONCOIN.COM.com, DIC 15, 2017'
|
||||
},
|
||||
' 0xea0c348a297084bffbddad7f89216f24a2106e58': {
|
||||
gasLimit: 300000,
|
||||
msg:
|
||||
'Aigang token sale contract. Autonomous insurance network - fully automated insurance for IoT devices and a platform for insurance innovation built around data: https://aigang.network . Ends 12/15/2017'
|
||||
},
|
||||
'0x17681500757628c7aa56d7e6546e119f94dd9479': {
|
||||
gasLimit: 170000,
|
||||
msg:
|
||||
'Confideal token sale. Confideal is a platform for making deals. https://confideal.io, ends Jan 31, 2018'
|
||||
},
|
||||
'0x5454af9d2ba75a60fa5b0419c251810544cea21d': {
|
||||
gasLimit: 200000,
|
||||
msg: 'WeBetCrypto ICO Sale. Thank you for your support!'
|
||||
},
|
||||
'0x882448f83d90b2bf477af2ea79327fdea1335d93': {
|
||||
gasLimit: 200000,
|
||||
msg: 'Vibehub ICO Sale. Thank you for your support!'
|
||||
},
|
||||
'0xdea6d29da64bba5ab86a7424ca894756e7ae8ed3': {
|
||||
gasLimit: 200000,
|
||||
msg: 'Trade.io ICO Sale. Thank you for your support!'
|
||||
},
|
||||
'0xaf518d65f84e4695a4da0450ec02c1248f56b668': {
|
||||
gasLimit: 200000,
|
||||
msg: 'Substratum Network ICO Sale. Thank you for your support!'
|
||||
},
|
||||
'0x0f33bb20a282a7649c7b3aff644f084a9348e933': {
|
||||
gasLimit: 400000,
|
||||
msg: 'YUPIE (YUPIE) ICO'
|
||||
},
|
||||
'0xbd2ed3e85faa3433c068c7b3f9c8c7d839ce88d7': {
|
||||
gasLimit: 69153,
|
||||
msg: 'Horizon State Token Sale. Thank you for your support. '
|
||||
},
|
||||
'0x8aec8f09a840faea966f4b0e29a497d8f5b5a6b4': {
|
||||
gasLimit: 200000,
|
||||
msg: 'DataBrokerDAO. https://databrokerdao.com'
|
||||
},
|
||||
'0xeaaf270436a0ed397ed23bbf64df7b1dcaff142f': {
|
||||
gasLimit: 85000,
|
||||
msg: 'BattleDrome ICO/Crowdsale. Thanks for your support!'
|
||||
},
|
||||
'0x58b7056deb51ed292614f0da1e94e7e9c589828d': {
|
||||
gasLimit: 150000,
|
||||
msg: 'Simple Token — the cryptocurrency that powers digital communities.'
|
||||
},
|
||||
'0x5fb3d432bae33fcd418ede263d98d7440e7fa3ea': {
|
||||
gasLimit: 200000,
|
||||
msg: 'SunContract ICO address - suncontract.org'
|
||||
},
|
||||
'0xd88755197e107603c139df6e709ed09eec6b6bb3': {
|
||||
gasLimit: 200000,
|
||||
msg: 'NVC Fund'
|
||||
},
|
||||
'0x2a8a7afa955d8616e2e60e454e5a9c6b6c0a60fc': {
|
||||
gasLimit: 200000,
|
||||
msg: 'OHNI ICO. Restoration of our communities!'
|
||||
},
|
||||
'0xf9f0fc7167c311dd2f1e21e9204f87eba9012fb2': {
|
||||
gasLimit: 200000,
|
||||
msg: 'Easy Homes ICO. Thank you!'
|
||||
},
|
||||
'0x7fc408011165760ee31be2bf20daf450356692af': {
|
||||
gasLimit: 200000,
|
||||
msg: 'Mitrav ICO Sale. Thank you for your support!'
|
||||
},
|
||||
'0xa5dd8cde486436f0cfd62652952e1fcec5a61cae': {
|
||||
gasLimit: 300000,
|
||||
msg: 'WinBitcoin ICO Sale. Thank you for your support!'
|
||||
},
|
||||
'0x19d7a9ad3b49252fd2ef640d0e43dfd651168499': {
|
||||
gasLimit: 100000,
|
||||
msg: 'BMChain ICO - Platform of digital reputation - Official site https://bmchain.io'
|
||||
},
|
||||
'0xafe60511341a37488de25bef351952562e31fcc1': {
|
||||
gasLimit: 200000,
|
||||
msg: 'Tbot ICO Sale.'
|
||||
},
|
||||
'0xe386b139ed3715ca4b18fd52671bdcea1cdfe4b1': {
|
||||
gasLimit: 200000,
|
||||
msg:
|
||||
'Zeus Exchange - The First Hybrid Trading Platform for Traditional Stock Investors and Crypto Traders. Official site https://zeus.exchange'
|
||||
},
|
||||
'0xb70835d7822ebb9426b56543e391846c107bd32c': {
|
||||
gasLimit: 200000,
|
||||
msg: 'Game Token Sale'
|
||||
},
|
||||
'0x5f53f7a8075614b699baad0bc2c899f4bad8fbbf': {
|
||||
gasLimit: 200000,
|
||||
msg: 'Rebellious Token'
|
||||
},
|
||||
'0xd5e3036d5ce7ec222379d16f6ffc38c38c55bf7f': {
|
||||
gasLimit: 200000,
|
||||
msg:
|
||||
'Ethereum High HIG is a robust and feather-light cryptocurrency designed to hedge the risk of your portfolio'
|
||||
},
|
||||
'0x2a3aa9eca41e720ed46b5a70d6c37efa47f768ac': {
|
||||
gasLimit: 200000,
|
||||
msg: 'REAL CHAIN TOKEN!'
|
||||
},
|
||||
'0x7705faa34b16eb6d77dfc7812be2367ba6b0248e': {
|
||||
gasLimit: 200000,
|
||||
msg: 'Artex - Art Provenance Blockchain. Official site https://artex.global'
|
||||
},
|
||||
'0x29afa3443f752eb29d814d9042fd88a4a2dc0f1e': {
|
||||
gasLimit: 200000,
|
||||
msg: 'SIRIN LABS official crowdsale address. Official website https://sirinlabs.com'
|
||||
},
|
||||
'0xa671f2914ba0e73979ffc47cd350801d1714b18f': {
|
||||
gasLimit: 150000,
|
||||
msg: 'TRV Ongoing Sale.'
|
||||
},
|
||||
'0xdee3bfae40ac2ae9c69ebf30ecaf67a499a9dd5e': {
|
||||
gasLimit: 150000,
|
||||
msg: 'The World News Pre-ICO.'
|
||||
},
|
||||
'0x92685e93956537c25bb75d5d47fca4266dd628b8': {
|
||||
gasLimit: 200000,
|
||||
msg: 'Bitlle Token. Official website https://bitlle.com'
|
||||
},
|
||||
'0x2097175d0abb8258f2468e3487f8db776e29d076': {
|
||||
gasLimit: 200000,
|
||||
msg: 'LiveEdu EDU token sale. Official website: https://tokensale.liveedu.tv/'
|
||||
},
|
||||
'0x4f8b6ca78711207e1b281db63e8d6eaa1ce2f63e': {
|
||||
gasLimit: 230000,
|
||||
msg: 'HEdpAY (Hdp.ф) sale. Official sale website: https://ibiginvestments.com/hedpay'
|
||||
}
|
||||
};
|
||||
|
||||
export function getAddressMessage(address: string): AddressMessage | undefined {
|
||||
const lowerAddr = address.toLowerCase();
|
||||
const checksumAddr = toChecksumAddress(address);
|
||||
return ADDRESS_MESSAGES[lowerAddr] || ADDRESS_MESSAGES[checksumAddr];
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
export * from './networks';
|
||||
export * from './data';
|
||||
export * from './bity';
|
||||
export * from './addressMessages';
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { SagaIterator, buffers, delay } from 'redux-saga';
|
||||
import { apply, put, select, take, actionChannel, call, fork, race } from 'redux-saga/effects';
|
||||
import {
|
||||
apply,
|
||||
put,
|
||||
select,
|
||||
take,
|
||||
actionChannel,
|
||||
call,
|
||||
fork,
|
||||
race,
|
||||
takeEvery
|
||||
} from 'redux-saga/effects';
|
||||
import BN from 'bn.js';
|
||||
import { INode } from 'libs/nodes/INode';
|
||||
import { getNodeLib, getOffline, getAutoGasLimitEnabled } from 'selectors/config';
|
||||
import { getWalletInst } from 'selectors/wallet';
|
||||
import { getTransaction, IGetTransaction } from 'selectors/transaction';
|
||||
import { getTransaction, IGetTransaction, getCurrentToAddressMessage } from 'selectors/transaction';
|
||||
import {
|
||||
EstimateGasRequestedAction,
|
||||
setGasLimitField,
|
||||
@ -21,6 +32,7 @@ import {
|
||||
import { TypeKeys as ConfigTypeKeys, ToggleAutoGasLimitAction } from 'actions/config';
|
||||
import { IWallet } from 'libs/wallet';
|
||||
import { makeTransaction, getTransactionFields, IHexStrTransaction } from 'libs/transaction';
|
||||
import { AddressMessage } from 'config';
|
||||
|
||||
export function* shouldEstimateGas(): SagaIterator {
|
||||
while (true) {
|
||||
@ -38,16 +50,17 @@ export function* shouldEstimateGas(): SagaIterator {
|
||||
TypeKeys.TOKEN_TO_ETHER_SWAP,
|
||||
ConfigTypeKeys.CONFIG_TOGGLE_AUTO_GAS_LIMIT
|
||||
]);
|
||||
// invalid field is a field that the value is null and the input box isnt empty
|
||||
// reason being is an empty field is valid because it'll be null
|
||||
|
||||
const isOffline: boolean = yield select(getOffline);
|
||||
const autoGasLimitEnabled: boolean = yield select(getAutoGasLimitEnabled);
|
||||
const message: AddressMessage | undefined = yield select(getCurrentToAddressMessage);
|
||||
|
||||
if (isOffline || !autoGasLimitEnabled) {
|
||||
if (isOffline || !autoGasLimitEnabled || (message && message.gasLimit)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// invalid field is a field that the value is null and the input box isnt empty
|
||||
// reason being is an empty field is valid because it'll be null
|
||||
const invalidField =
|
||||
(action.type === TypeKeys.TO_FIELD_SET || action.type === TypeKeys.DATA_FIELD_SET) &&
|
||||
!action.payload.value &&
|
||||
@ -110,4 +123,21 @@ export function* localGasEstimation(payload: EstimateGasRequestedAction['payload
|
||||
yield put(setGasLimitField({ raw: gasLimit.toString(), value: gasLimit }));
|
||||
}
|
||||
|
||||
export const gas = [fork(shouldEstimateGas), fork(estimateGas)];
|
||||
export function* setAddressMessageGasLimit() {
|
||||
const autoGasLimitEnabled: boolean = yield select(getAutoGasLimitEnabled);
|
||||
const message: AddressMessage | undefined = yield select(getCurrentToAddressMessage);
|
||||
if (autoGasLimitEnabled && message && message.gasLimit) {
|
||||
yield put(
|
||||
setGasLimitField({
|
||||
raw: message.gasLimit.toString(),
|
||||
value: new BN(message.gasLimit)
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const gas = [
|
||||
fork(shouldEstimateGas),
|
||||
fork(estimateGas),
|
||||
takeEvery(TypeKeys.TO_FIELD_SET, setAddressMessageGasLimit)
|
||||
];
|
||||
|
@ -144,5 +144,5 @@ li {
|
||||
|
||||
// Blockquotes
|
||||
blockquote {
|
||||
padding: $space-sm $line-height-computed;
|
||||
padding: $space-sm #{$line-height-computed}rem;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import { AppState } from 'reducers';
|
||||
import { isEtherUnit, TokenValue, Wei, Address } from 'libs/units';
|
||||
import { gasPriceValidator, gasLimitValidator } from 'libs/validators';
|
||||
import { getDataExists, getGasPrice, getGasLimit } from 'selectors/transaction';
|
||||
import { getAddressMessage, AddressMessage } from 'config';
|
||||
|
||||
interface ICurrentValue {
|
||||
raw: string;
|
||||
@ -42,6 +43,11 @@ const isValidGasPrice = (state: AppState): boolean => gasPriceValidator(getGasPr
|
||||
|
||||
const isValidGasLimit = (state: AppState): boolean => gasLimitValidator(getGasLimit(state).raw);
|
||||
|
||||
function getCurrentToAddressMessage(state: AppState): AddressMessage | undefined {
|
||||
const to = getCurrentTo(state);
|
||||
return getAddressMessage(to.raw);
|
||||
}
|
||||
|
||||
export {
|
||||
getCurrentValue,
|
||||
getCurrentTo,
|
||||
@ -50,5 +56,6 @@ export {
|
||||
isEtherTransaction,
|
||||
isValidCurrentTo,
|
||||
isValidGasPrice,
|
||||
isValidGasLimit
|
||||
isValidGasLimit,
|
||||
getCurrentToAddressMessage
|
||||
};
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { buffers, delay } from 'redux-saga';
|
||||
import { apply, put, select, take, actionChannel, call, race } from 'redux-saga/effects';
|
||||
import BN from 'bn.js';
|
||||
import { getNodeLib, getOffline, getAutoGasLimitEnabled } from 'selectors/config';
|
||||
import { getWalletInst } from 'selectors/wallet';
|
||||
import { getTransaction } from 'selectors/transaction';
|
||||
import { getTransaction, getCurrentToAddressMessage } from 'selectors/transaction';
|
||||
import {
|
||||
setGasLimitField,
|
||||
estimateGasFailed,
|
||||
@ -12,7 +13,12 @@ import {
|
||||
estimateGasTimedout
|
||||
} from 'actions/transaction';
|
||||
import { makeTransaction, getTransactionFields } from 'libs/transaction';
|
||||
import { shouldEstimateGas, estimateGas, localGasEstimation } from 'sagas/transaction/network/gas';
|
||||
import {
|
||||
shouldEstimateGas,
|
||||
estimateGas,
|
||||
localGasEstimation,
|
||||
setAddressMessageGasLimit
|
||||
} from 'sagas/transaction/network/gas';
|
||||
import { cloneableGenerator } from 'redux-saga/utils';
|
||||
import { Wei } from 'libs/units';
|
||||
import { TypeKeys as ConfigTypeKeys } from 'actions/config';
|
||||
@ -20,6 +26,7 @@ import { TypeKeys as ConfigTypeKeys } from 'actions/config';
|
||||
describe('shouldEstimateGas*', () => {
|
||||
const offline = false;
|
||||
const autoGasLimitEnabled = true;
|
||||
const addressMessage = undefined;
|
||||
const transaction: any = 'transaction';
|
||||
const tx = { transaction };
|
||||
const rest: any = {
|
||||
@ -64,8 +71,12 @@ describe('shouldEstimateGas*', () => {
|
||||
expect(gen.next(offline).value).toEqual(select(getAutoGasLimitEnabled));
|
||||
});
|
||||
|
||||
it('should select getCurrentToAddressMessage', () => {
|
||||
expect(gen.next(autoGasLimitEnabled).value).toEqual(select(getCurrentToAddressMessage));
|
||||
});
|
||||
|
||||
it('should select getTransaction', () => {
|
||||
expect(gen.next(autoGasLimitEnabled).value).toEqual(select(getTransaction));
|
||||
expect(gen.next(addressMessage).value).toEqual(select(getTransaction));
|
||||
});
|
||||
|
||||
it('should call getTransactionFields with transaction', () => {
|
||||
@ -236,3 +247,44 @@ describe('localGasEstimation', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setAddressMessageGasLimit*', () => {
|
||||
const gens = cloneableGenerator(setAddressMessageGasLimit)();
|
||||
const gen = gens.clone();
|
||||
let noAutoGen;
|
||||
let noMessageGen;
|
||||
const addressMessage = {
|
||||
gasLimit: 123456,
|
||||
msg: 'Thanks for donating, er, investing in SCAM'
|
||||
};
|
||||
|
||||
it('should select getAutoGasLimitEnabled', () => {
|
||||
expect(gen.next().value).toEqual(select(getAutoGasLimitEnabled));
|
||||
});
|
||||
|
||||
it('should select getCurrentToAddressMessage', () => {
|
||||
noAutoGen = gen.clone();
|
||||
expect(gen.next(true).value).toEqual(select(getCurrentToAddressMessage));
|
||||
});
|
||||
|
||||
it('should put setGasLimitField', () => {
|
||||
noMessageGen = gen.clone();
|
||||
expect(gen.next(addressMessage).value).toEqual(
|
||||
put(
|
||||
setGasLimitField({
|
||||
raw: addressMessage.gasLimit.toString(),
|
||||
value: new BN(addressMessage.gasLimit)
|
||||
})
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('should do nothing if getAutoGasLimitEnabled is false', () => {
|
||||
noAutoGen.next(false);
|
||||
expect(noAutoGen.next(addressMessage).done).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should do nothing if getCurrentToAddressMessage is undefined', () => {
|
||||
expect(noMessageGen.next(undefined).done).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user