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 }