MyCrypto/common/features/gas/sagas.ts

71 lines
2.2 KiB
TypeScript

import { SagaIterator } from 'redux-saga';
import { call, put, select, takeLatest } from 'redux-saga/effects';
import { gasPriceDefaults, gasEstimateCacheTime } from 'config';
import { fetchGasEstimates, GasEstimates } from 'api/gas';
import { NetworkConfig } from 'types/network';
import { AppState } from 'features/reducers';
import * as configMetaSelectors from 'features/config/meta/selectors';
import * as configSelectors from 'features/config/selectors';
import * as types from './types';
import * as actions from './actions';
import * as selectors from './selectors';
export function* setDefaultEstimates(network: NetworkConfig): SagaIterator {
// Must yield time for testability
const time = yield call(Date.now);
const gasSettings = network.isCustom ? gasPriceDefaults : network.gasPriceSettings;
yield put(
actions.setGasEstimates({
safeLow: gasSettings.min,
standard: gasSettings.initial,
fast: gasSettings.initial,
fastest: gasSettings.max,
isDefault: true,
chainId: network.chainId,
time
})
);
}
export function* fetchEstimates(): SagaIterator {
// Don't try on non-estimating network
const network: NetworkConfig = yield select(configSelectors.getNetworkConfig);
if (network.isCustom || !network.shouldEstimateGasPrice) {
yield call(setDefaultEstimates, network);
return;
}
// Don't try while offline
const isOffline: boolean = yield select(configMetaSelectors.getOffline);
if (isOffline) {
yield call(setDefaultEstimates, network);
return;
}
// Cache estimates for a bit
const oldEstimates: AppState['gas']['estimates'] = yield select(selectors.getEstimates);
if (
oldEstimates &&
oldEstimates.chainId === network.chainId &&
oldEstimates.time + gasEstimateCacheTime > Date.now()
) {
yield put(actions.setGasEstimates(oldEstimates));
return;
}
// Try to fetch new estimates
try {
const estimates: GasEstimates = yield call(fetchGasEstimates);
yield put(actions.setGasEstimates(estimates));
} catch (err) {
console.warn('Failed to fetch gas estimates:', err);
yield call(setDefaultEstimates, network);
}
}
export function* gasSaga(): SagaIterator {
yield takeLatest(types.GasActions.FETCH_ESTIMATES, fetchEstimates);
}