import { PayloadAction } from '@reduxjs/toolkit' import { call, put, takeLatest } from 'redux-saga/effects' import { stakingPoolActions } from '.' import { GOOGLE_TRACKING_ACTIONS, GOOGLE_TRACKING_CATEGORIES } from '../../constants/googleTracking' import { CustomError, showToastError } from '../../utils/errorHelper' import { trackEventWithGA } from '../../utils/googleTracking' import { hiddenGlobalLoading, showGlobalLoading, toastSuccess } from '../../utils/uiHelper' import { userActions } from '../user' import { ClaimStakingProps, GetPoolConfigListProps, GetStakingListProps, PoolConfigProps, StakeProps } from './types' export function* getPoolConfigList(action: PayloadAction) { try { const { payload } = action const { stakingPoolContract } = payload const data = yield call(stakingPoolContract.getPoolConfigs) const minStakeValue = yield call(stakingPoolContract.getMinStaking) const poolConfigList: PoolConfigProps[] = data.map( ({ id, aprDecimal, apr, isActive, limit, staking, startTime, totalDay, endTime }) => ({ id, aprDecimal, apr, apy: apr * Math.floor(365 / totalDay), isActive, limit: parseFloat(limit.toString()), staking: parseFloat(staking.toString()), startTime: parseFloat(startTime.toString()), totalDay, endTime: parseFloat(endTime.toString()), minStakeValue: parseFloat(minStakeValue.toString()), }), ) yield put( stakingPoolActions.getPoolConfigListSuccess( [...poolConfigList].sort((a: PoolConfigProps, b: PoolConfigProps) => a.totalDay - b.totalDay), ), ) } catch (error) { yield put(stakingPoolActions.getStakingListFailed()) showToastError(error) } } export function* getStakingList(action: PayloadAction) { try { const { payload } = action const { poolConfigId, stakingPoolContract } = payload const data = yield call(stakingPoolContract.getStakingInfos, poolConfigId) const stakingList = data.map(({ id, isReceived, poolConfig, sender, staked, createdAt }) => ({ id, isReceived, poolConfig, sender, staked: parseFloat(staked.toString()), createdAt: parseFloat(createdAt.toString()), })) yield put(stakingPoolActions.getStakingListSuccess(stakingList)) } catch (error) { yield put(stakingPoolActions.getStakingListFailed()) showToastError(error) } } export function* claimStaking(action: PayloadAction) { let isActionSuccess = true try { const { payload } = action const { stakingId, stakingPoolContract, poolConfigId } = payload const data = yield call(stakingPoolContract.claim, stakingId) showGlobalLoading() const receipt = yield call(data.wait) const { status } = receipt if (status) { yield put(userActions.getAdjustedBalances()) yield put(stakingPoolActions.getStakingList({ stakingPoolContract, poolConfigId })) yield put(stakingPoolActions.claimStakingSuccess()) } } catch (error) { isActionSuccess = false yield put(stakingPoolActions.claimStakingFailed()) showToastError(error) } finally { hiddenGlobalLoading() trackEventWithGA( GOOGLE_TRACKING_CATEGORIES.CLAIM_STAKING, GOOGLE_TRACKING_ACTIONS.STAKING_POOL_ACTION, isActionSuccess, ) } } export function* stake(action: PayloadAction) { let isActionSuccess = true try { const { payload } = action const { stakingValue, poolId, stakingPoolContract } = payload const data = yield call(stakingPoolContract.stake, stakingValue, poolId) showGlobalLoading() const receipt = yield call(data.wait) const { status } = receipt if (status) { toastSuccess({ title: 'Success', message: `Staking ${stakingValue} DAPP successfully` }) yield put(stakingPoolActions.stakeSuccess()) yield put(userActions.getAdjustedBalances()) yield put( stakingPoolActions.getPoolConfigList({ stakingPoolContract, }), ) } else { throw new CustomError('Failed staking.') } } catch (error) { isActionSuccess = false yield put(stakingPoolActions.stakeFailed()) showToastError(error) } finally { hiddenGlobalLoading() trackEventWithGA(GOOGLE_TRACKING_CATEGORIES.STAKING, GOOGLE_TRACKING_ACTIONS.STAKING_POOL_ACTION, isActionSuccess) } } export default function* boxInventorySaga() { yield takeLatest(stakingPoolActions.getPoolConfigList.type, getPoolConfigList) yield takeLatest(stakingPoolActions.getStakingList.type, getStakingList) yield takeLatest(stakingPoolActions.claimStaking.type, claimStaking) yield takeLatest(stakingPoolActions.stake.type, stake) }