109 lines
3.8 KiB
TypeScript
109 lines
3.8 KiB
TypeScript
import { select, call, put, takeEvery } from 'redux-saga/effects';
|
|
import { SagaIterator } from 'redux-saga';
|
|
import { SetUnitMetaAction, TypeKeys } from 'actions/transaction';
|
|
import {
|
|
getTokenTo,
|
|
getTokenValue,
|
|
getTo,
|
|
getPreviousUnit,
|
|
getValue,
|
|
getDecimalFromUnit
|
|
} from 'selectors/transaction';
|
|
import { isNetworkUnit } from 'selectors/config';
|
|
import { getToken, MergedToken } from 'selectors/wallet';
|
|
import { TokenValue, Address } from 'libs/units';
|
|
import {
|
|
swapTokenToEther,
|
|
swapEtherToToken,
|
|
swapTokenToToken
|
|
} from 'actions/transaction/actionCreators/swap';
|
|
import { encodeTransfer } from 'libs/transaction';
|
|
import { AppState } from 'reducers';
|
|
import { bufferToHex } from 'ethereumjs-util';
|
|
import { validateInput, rebaseUserInput, IInput } from 'sagas/transaction/validationHelpers';
|
|
import { setSchedulingToggle } from 'actions/schedule';
|
|
|
|
export function* handleSetUnitMeta({ payload: currentUnit }: SetUnitMetaAction): SagaIterator {
|
|
const previousUnit: string = yield select(getPreviousUnit);
|
|
const prevUnit = yield select(isNetworkUnit, previousUnit);
|
|
const currUnit = yield select(isNetworkUnit, currentUnit);
|
|
const etherToEther = currUnit && prevUnit;
|
|
const etherToToken = !currUnit && prevUnit;
|
|
const tokenToEther = currUnit && !prevUnit;
|
|
const tokenToToken = !currUnit && !prevUnit;
|
|
const decimal: number = yield select(getDecimalFromUnit, currentUnit);
|
|
|
|
if (etherToEther || previousUnit === '') {
|
|
return;
|
|
}
|
|
|
|
if (tokenToEther) {
|
|
const tokenTo: AppState['transaction']['meta']['tokenTo'] = yield select(getTokenTo);
|
|
const tokenValue: AppState['transaction']['meta']['tokenValue'] = yield select(getTokenValue);
|
|
|
|
//set the 'to' field from what the token 'to' field was
|
|
// if switching to ether, clear token data and value
|
|
const { value, raw }: IInput = yield call(rebaseUserInput, tokenValue);
|
|
|
|
const isValid = yield call(validateInput, value, currentUnit);
|
|
return yield put(
|
|
swapTokenToEther({ to: tokenTo, value: { raw, value: isValid ? value : null }, decimal })
|
|
);
|
|
}
|
|
|
|
if (etherToToken || tokenToToken) {
|
|
const currentToken: MergedToken | undefined = yield select(getToken, currentUnit);
|
|
if (!currentToken) {
|
|
throw Error('Could not find token during unit swap');
|
|
}
|
|
const input:
|
|
| AppState['transaction']['fields']['value']
|
|
| AppState['transaction']['meta']['tokenValue'] = etherToToken
|
|
? yield select(getValue)
|
|
: yield select(getTokenValue);
|
|
const { raw, value }: IInput = yield call(rebaseUserInput, input);
|
|
|
|
const isValid = yield call(validateInput, value, currentUnit);
|
|
const to: AppState['transaction']['fields']['to'] = yield select(getTo);
|
|
|
|
const valueToEncode = isValid && value ? value : TokenValue('0');
|
|
let addressToEncode;
|
|
if (etherToToken) {
|
|
addressToEncode = to.value || Address('0x0');
|
|
} else {
|
|
const tokenTo: AppState['transaction']['meta']['tokenTo'] = yield select(getTokenTo);
|
|
addressToEncode = tokenTo.value || Address('0x0');
|
|
}
|
|
|
|
const data = encodeTransfer(addressToEncode, valueToEncode);
|
|
|
|
const basePayload = {
|
|
data: { raw: bufferToHex(data), value: data },
|
|
to: { raw: '', value: Address(currentToken.address) },
|
|
tokenValue: { raw, value: isValid ? value : null },
|
|
decimal
|
|
};
|
|
// need to set meta fields for tokenTo and tokenValue
|
|
if (etherToToken) {
|
|
yield put(
|
|
setSchedulingToggle({
|
|
value: false
|
|
})
|
|
);
|
|
|
|
return yield put(
|
|
swapEtherToToken({
|
|
...basePayload,
|
|
tokenTo: to
|
|
})
|
|
);
|
|
}
|
|
// need to rebase the token if the decimal has changed and re-validate
|
|
if (tokenToToken) {
|
|
return yield put(swapTokenToToken(basePayload));
|
|
}
|
|
}
|
|
}
|
|
|
|
export const handleSetUnit = [takeEvery(TypeKeys.UNIT_META_SET, handleSetUnitMeta)];
|