UNPKG

raiden-ts

Version:

Raiden Light Client Typescript/Javascript SDK

82 lines 4.2 kB
import { EMPTY, timer } from 'rxjs'; import { filter, mergeMap, mergeWith, withLatestFrom } from 'rxjs/operators'; import { intervalFromConfig } from '../../config'; import { messageSend } from '../../messages/actions'; import { isActionOf } from '../../utils/actions'; import { pluckDistinct } from '../../utils/rx'; import { transferExpire, transferSecretRequest, transferSecretReveal, transferSigned, transferUnlock, } from '../actions'; import { Direction } from '../state'; import { transferKey } from '../utils'; import { retrySendUntil$ } from './utils'; /** * Retry sending protocol messages until stop conditions are met. * * @param action$ - Observable of transferExpire.success actions * @param state$ - Observable of RaidenStates * @param deps - Epics dependencies * @param deps.config$ - Config observable * @returns Observable of messageSend.request actions */ export function transferRetryMessageEpic(action$, state$, { config$ }) { return action$.pipe(filter(isActionOf([ transferSigned, transferUnlock.success, transferExpire.success, transferSecretRequest, transferSecretReveal, ])), withLatestFrom(state$, config$), mergeMap(([action, state, { revealTimeout }]) => { const transfer = state.transfers[transferKey(action.meta)]; const transfer$ = state$.pipe(pluckDistinct('transfers', transferKey(action.meta))); let to; let viaUserId; let stop$; switch (action.type) { case transferSigned.type: if (action.meta.direction === Direction.SENT) { to = action.payload.partner; viaUserId = action.payload.userId; stop$ = transfer$.pipe(filter((transfer) => !!(transfer.transferProcessed || transfer.unlockProcessed || // unlock|expired shouldn't happen before transferProcessed transfer.expiredProcessed || transfer.channelClosed))); } break; case transferUnlock.success.type: if (action.meta.direction === Direction.SENT) { to = action.payload.partner; viaUserId = action.payload.userId; stop$ = transfer$.pipe(filter((transfer) => !!(transfer.unlockProcessed || transfer.channelClosed))); } break; case transferExpire.success.type: if (action.meta.direction === Direction.SENT) { to = action.payload.partner; stop$ = transfer$.pipe(filter((transfer) => !!(transfer.expiredProcessed || transfer.channelClosed))); } break; case transferSecretRequest.type: if (action.meta.direction === Direction.RECEIVED && transfer) { to = transfer.transfer.initiator; viaUserId = action.payload.userId; stop$ = transfer$.pipe(filter((transfer) => /* transfer.secret would be enough, but let's test secretReveal to possibly retry * failed RevealSecret sign prompts */ !!(transfer.secretReveal || transfer.channelClosed)), // or when we get inside the danger zone mergeWith(timer(new Date((transfer.expiration - revealTimeout) * 1e3)))); } break; case transferSecretReveal.type: if (action.meta.direction === Direction.RECEIVED && transfer) { to = transfer.partner; viaUserId = action.payload.userId; stop$ = transfer$.pipe(filter((transfer) => !!(transfer.unlock || transfer.channelClosed))); } break; } if (!to || !stop$) return EMPTY; return retrySendUntil$(messageSend.request({ message: action.payload.message, userId: viaUserId }, { address: to, msgId: action.payload.message.message_identifier.toString() }), action$, stop$, intervalFromConfig(config$)); })); } //# sourceMappingURL=retry.js.map