diff --git a/src/store/routeAssets/actions.ts b/src/store/routeAssets/actions.ts index a4d7014c1..e621061bb 100644 --- a/src/store/routeAssets/actions.ts +++ b/src/store/routeAssets/actions.ts @@ -18,6 +18,7 @@ import { NumberLike } from '@sora-substrate/math'; import { Messages } from '@sora-substrate/util/build/logger'; import { assert } from '@polkadot/util'; import { slippageMultiplier } from '@/modules/ADAR/consts'; +import { getTokenEquivalent, getAssetUSDPrice } from './utils'; const actions = defineActions({ processingNextStage(context) { @@ -265,42 +266,18 @@ const actions = defineActions({ }, }); -function getAssetUSDPrice(asset, fiatPriceObject) { - if (!asset) return null; - return FPNumber.fromCodecValue(fiatPriceObject[asset.address], 18).toFixed(18); -} - function getTransferParams(context, inputAsset, recipient) { const { rootState } = routeAssetsActionContext(context); if (recipient.asset.address === inputAsset.address) { const priceObject = rootState.wallet.account.fiatPriceObject; - const amount = Number(recipient.usd) / Number(getAssetUSDPrice(recipient.asset, priceObject)); - const transfer = api.api.tx.assets.transfer( - inputAsset.address, - recipient.wallet, - new FPNumber(amount, inputAsset.decimals).toCodecString() - ); - const formattedToAddress = - recipient.wallet.slice(0, 2) === 'cn' ? recipient.wallet : formatAddress(recipient.wallet); - const history = { - symbol: recipient.asset.symbol, - to: formattedToAddress, - amount: `${amount}`, - assetAddress: recipient.wallet, - type: Operation.Transfer, - }; + const amount = getTokenEquivalent(priceObject, recipient.asset, recipient.usd); return { - action: async () => await api.transfer(recipient.asset, recipient.wallet, amount), + action: async () => await api.transfer(recipient.asset, recipient.wallet, amount.toString()), recipient, - transfer: { - extrinsic: transfer, - history: history, - }, swapAndSendData: { address: recipient.wallet, targetAmount: amount, asset: recipient.asset, - // dexId: bestDexId, }, }; } else { @@ -316,8 +293,8 @@ function getTransferParams(context, inputAsset, recipient) { recipient.wallet, inputAsset, recipient.asset, - amountFrom, - amountTo, + amountFrom.toString(), + amountTo.toString(), undefined, true, undefined, @@ -378,8 +355,7 @@ async function executeBatchSwapAndSend(context, data: Array): Promise const { commit, getters, rootCommit, rootState } = routeAssetsActionContext(context); const inputAsset = getters.inputToken; const newData = data.map((item) => { - const decimals = item.swapAndSendData.asset.decimals; - const targetAmount = new FPNumber(item.swapAndSendData.targetAmount, decimals).toCodecString(); + const targetAmount = item.swapAndSendData.targetAmount.toCodecString(); return { accountId: item.swapAndSendData.address, targetAmount, @@ -396,9 +372,11 @@ async function executeBatchSwapAndSend(context, data: Array): Promise let inputTokenAmount: FPNumber = FPNumber.ZERO; const swapTransferData = groupedData.map((entry) => { const [outcomeAssetId, receivers] = entry; - const approxSum = sumBy(receivers, (receiver) => receiver.usd); - const dexIdData = getAmountAndDexId(context, inputAsset, findAsset(outcomeAssetId) as Asset, approxSum); - inputTokenAmount = inputTokenAmount.add(FPNumber.fromCodecValue(dexIdData?.amountFrom as string)); + const approxSum = receivers.reduce((sum, receiver) => { + return sum.add(new FPNumber(receiver.usd)); + }, FPNumber.ZERO); + const dexIdData = getAmountAndDexId(context, inputAsset, findAsset(outcomeAssetId) as Asset, approxSum.toString()); + inputTokenAmount = inputTokenAmount.add(dexIdData?.amountFrom); const dexId = dexIdData?.bestDexId; return { outcomeAssetId, @@ -495,9 +473,7 @@ function calcTxParams( const liquiditySources = liquiditySource ? [liquiditySource] : []; return { args: [ - // dexId, asset.address, - // assetTo.address, amount, liquiditySources, liquiditySource === LiquiditySourceTypes.Default ? 'Disabled' : 'AllowSelected', @@ -505,20 +481,22 @@ function calcTxParams( }; } -function getAmountAndDexId(context: any, assetFrom: Asset, assetTo: Asset, usd: number) { +function getAmountAndDexId(context: any, assetFrom: Asset, assetTo: Asset, usd: number | string) { const { rootState, getters, rootGetters } = routeAssetsActionContext(context); + const tokenEquivalent = getTokenEquivalent(rootState.wallet.account.fiatPriceObject, assetTo, usd); + if (assetFrom.address === assetTo.address) + return { amountFrom: tokenEquivalent, amountTo: tokenEquivalent, bestDexId: 0 }; const subscription = getters.subscriptions.find((sub) => sub.assetAddress === assetTo.address); - if (!subscription) return null; + if (!subscription) { + throw new Error('Subscription did not found'); + } const { paths, payload, liquiditySources, dexQuoteData } = subscription; - const tokenEquivalent = new FPNumber(usd) - .div(FPNumber.fromCodecValue(rootState.wallet.account.fiatPriceObject[assetTo.address], assetTo.decimals)) - .toNumber(); const dexes = api.dex.dexList; const results = dexes.reduce<{ [dexId: number]: SwapResult }>((buffer, { dexId }) => { const swapResult = api.swap.getResult( assetFrom, assetTo, - `${tokenEquivalent}`, + tokenEquivalent.toString(), true, [rootGetters.swap.swapLiquiditySource].filter(Boolean) as Array, (dexQuoteData as Record)[dexId].paths, @@ -549,7 +527,7 @@ function getAmountAndDexId(context: any, assetFrom: Asset, assetTo: Asset, usd: } const { amount, amountWithoutImpact, fee, rewards } = results[bestDexId]; - return { amountFrom: amount, amountTo: tokenEquivalent, bestDexId, allDexes: results }; + return { amountFrom: FPNumber.fromCodecValue(amount), amountTo: tokenEquivalent, bestDexId, allDexes: results }; } export default actions; diff --git a/src/store/routeAssets/utils.ts b/src/store/routeAssets/utils.ts index 0d7eb9c3e..bf53f5142 100644 --- a/src/store/routeAssets/utils.ts +++ b/src/store/routeAssets/utils.ts @@ -1,6 +1,9 @@ import { api } from '@soramitsu/soraneo-wallet-web'; import { Recipient } from './types'; import { Asset, AccountAsset } from '@sora-substrate/util/build/assets/types'; +import { FPNumber, Operation } from '@sora-substrate/util/build'; +import { FiatPriceObject } from '@soramitsu/soraneo-wallet-web/lib/services/subquery/types'; +import type { WhitelistArrayItem } from '@sora-substrate/util/build/assets/types'; export default { validate(recipient: Recipient) { @@ -32,3 +35,16 @@ export default { return amount && !isNaN(amount) && Number.isFinite(amount); }, }; + +export function getTokenEquivalent( + priceObject: FiatPriceObject, + asset: Asset | AccountAsset | WhitelistArrayItem, + usd: number | string +): FPNumber { + return new FPNumber(usd).div(FPNumber.fromCodecValue(priceObject[asset.address], asset.decimals)); +} + +export function getAssetUSDPrice(asset, fiatPriceObject) { + if (!asset) return null; + return FPNumber.fromCodecValue(fiatPriceObject[asset.address], asset.decimals); +}