/ common / features / ens / sagas.ts
sagas.ts
 1  import { SagaIterator, delay, buffers } from 'redux-saga';
 2  import { call, put, select, all, actionChannel, take, fork, race } from 'redux-saga/effects';
 3  
 4  import { INode } from 'libs/nodes/INode';
 5  import { IBaseDomainRequest } from 'libs/ens';
 6  import * as configNodesSelectors from 'features/config/nodes/selectors';
 7  import { notificationsActions } from 'features/notifications';
 8  import { ensDomainSelectorSelectors } from './domainSelector';
 9  import * as types from './types';
10  import * as actions from './actions';
11  import * as selectors from './selectors';
12  import * as helpers from './helpers';
13  
14  function* shouldResolveDomain(domain: string) {
15    const currentDomainName = yield select(ensDomainSelectorSelectors.getCurrentDomainName);
16    if (currentDomainName === domain) {
17      const currentDomainData = yield select(selectors.getCurrentDomainData);
18      if (currentDomainData) {
19        return false;
20      }
21    }
22    return true;
23  }
24  
25  function* resolveDomain(): SagaIterator {
26    const requestChan = yield actionChannel(
27      types.ENSActions.RESOLVE_DOMAIN_REQUESTED,
28      buffers.sliding(1)
29    );
30  
31    while (true) {
32      const { payload }: types.ResolveDomainRequested = yield take(requestChan);
33  
34      const { domain } = payload;
35  
36      try {
37        const shouldResolve = yield call(shouldResolveDomain, domain);
38        if (!shouldResolve) {
39          yield put(actions.resolveDomainCached({ domain }));
40          continue;
41        }
42  
43        const node: INode = yield select(configNodesSelectors.getNodeLib);
44  
45        const result: { domainData: IBaseDomainRequest; error: any } = yield race({
46          domainData: call(helpers.resolveDomainRequest, domain, node),
47          err: call(delay, 10000)
48        });
49  
50        const { domainData } = result;
51  
52        if (!domainData) {
53          throw Error();
54        }
55        const domainSuccessAction = actions.resolveDomainSucceeded(domain, domainData);
56        yield put(domainSuccessAction);
57      } catch (e) {
58        const domainFailAction = actions.resolveDomainFailed(domain, e);
59        yield put(domainFailAction);
60        yield put(
61          notificationsActions.showNotification(
62            'danger',
63            e.message || 'Could not resolve ENS address',
64            5000
65          )
66        );
67      }
68    }
69  }
70  
71  export function* ensSaga(): SagaIterator {
72    yield all([fork(resolveDomain)]);
73  }