import {
resolveDomainFailed,
resolveDomainSucceeded,
ResolveDomainRequested,
resolveDomainCached
} from 'actions/ens';
import { TypeKeys } from 'actions/ens/constants';
import { SagaIterator, delay, buffers } from 'redux-saga';
import { INode } from 'libs/nodes/INode';
import { getNodeLib } from 'selectors/config';
import { call, put, select, all, actionChannel, take, fork, race } from 'redux-saga/effects';
import { showNotification } from 'actions/notifications';
import { resolveDomainRequest } from './modeMap';
import { getCurrentDomainName, getCurrentDomainData } from 'selectors/ens';
import { IBaseDomainRequest } from 'libs/ens';
function* shouldResolveDomain(domain: string) {
const currentDomainName = yield select(getCurrentDomainName);
if (currentDomainName === domain) {
const currentDomainData = yield select(getCurrentDomainData);
if (currentDomainData) {
return false;
}
return true;
function* resolveDomain(): SagaIterator {
const requestChan = yield actionChannel(
TypeKeys.ENS_RESOLVE_DOMAIN_REQUESTED,
buffers.sliding(1)
);
while (true) {
const { payload }: ResolveDomainRequested = yield take(requestChan);
const { domain } = payload;
try {
const shouldResolve = yield call(shouldResolveDomain, domain);
if (!shouldResolve) {
yield put(resolveDomainCached({ domain }));
continue;
const node: INode = yield select(getNodeLib);
const result: { domainData: IBaseDomainRequest; error: any } = yield race({
domainData: call(resolveDomainRequest, domain, node),
err: call(delay, 10000)
});
const { domainData } = result;
if (!domainData) {
throw Error();
const domainSuccessAction = resolveDomainSucceeded(domain, domainData);
yield put(domainSuccessAction);
} catch (e) {
const domainFailAction = resolveDomainFailed(domain, e);
yield put(domainFailAction);
yield put(showNotification('danger', e.message || 'Could not resolve ENS address', 5000));
export function* ens(): SagaIterator {
yield all([fork(resolveDomain)]);