diff --git a/src/custom/hooks/useAppData.ts b/src/custom/hooks/useAppData.ts index 972755bc17..70c1790470 100644 --- a/src/custom/hooks/useAppData.ts +++ b/src/custom/hooks/useAppData.ts @@ -1,22 +1,25 @@ import { useEffect } from 'react' import { SupportedChainId } from '@cowprotocol/cow-sdk' import { useAtom } from 'jotai' +import { Percent } from '@uniswap/sdk-core' -import TradeGp from 'state/swap/TradeGp' import { APP_DATA_HASH } from 'constants/index' -import { buildAppData } from 'utils/appData' +import { buildAppData, BuildAppDataParams } from 'utils/appData' import { appDataInfoAtom } from 'state/appData/atoms' import { AppDataInfo } from 'state/appData/types' import { useReferralAddress } from 'state/affiliate/hooks' import { useAppCode } from 'hooks/useAppCode' +import { percentToBips } from 'utils/misc' + +type UseAppDataParams = { + chainId?: SupportedChainId + allowedSlippage: Percent +} /** * Fetches and updates appDataInfo whenever a dependency changes - * - * @param chainId - * @param trade */ -export function useAppData(chainId?: SupportedChainId, trade?: TradeGp): AppDataInfo | null { +export function useAppData({ chainId, allowedSlippage }: UseAppDataParams): AppDataInfo | null { // AppDataInfo, from Jotai const [appDataInfo, setAppDataInfo] = useAtom(appDataInfoAtom) // Referrer address, from Redux @@ -26,23 +29,21 @@ export function useAppData(chainId?: SupportedChainId, trade?: TradeGp): AppData // AppCode is dynamic and based on how it's loaded (if used as a Gnosis Safe app) const appCode = useAppCode() - // Sell and buy amounts, from trade param - const sellAmount = trade?.inputAmountWithFee.quotient.toString() - const buyAmount = trade?.outputAmount.quotient.toString() - const quoteId = trade?.quoteId + // Transform slippage Percent to bips + const slippageBips = percentToBips(allowedSlippage) useEffect(() => { - if (!chainId || !sellAmount || !buyAmount) { + if (!chainId) { // reset values when there is no price estimation or network changes setAppDataInfo(null) return } - const params: Parameters = [chainId, sellAmount, buyAmount, quoteId, referrerAccount, appCode] + const params: BuildAppDataParams = { chainId, slippageBips, referrerAccount, appCode } const updateAppData = async (): Promise => { try { - const { doc, calculatedAppData } = await buildAppData(...params) + const { doc, calculatedAppData } = await buildAppData(params) console.debug(`[useAppData] appDataInfo`, JSON.stringify(doc), calculatedAppData) @@ -59,7 +60,7 @@ export function useAppData(chainId?: SupportedChainId, trade?: TradeGp): AppData } updateAppData() - }, [appCode, buyAmount, chainId, quoteId, referrerAccount, sellAmount, setAppDataInfo]) + }, [appCode, chainId, referrerAccount, setAppDataInfo, slippageBips]) return appDataInfo } diff --git a/src/custom/hooks/useSwapCallback.ts b/src/custom/hooks/useSwapCallback.ts index 368838e46c..3cba305b16 100644 --- a/src/custom/hooks/useSwapCallback.ts +++ b/src/custom/hooks/useSwapCallback.ts @@ -350,7 +350,7 @@ export function useSwapCallback(params: SwapCallbackParams): { const [deadline] = useUserTransactionTTL() - const appData = useAppData(chainId, trade) + const appData = useAppData({ chainId, allowedSlippage }) const { hash: appDataHash } = appData || {} const addAppDataToUploadQueue = useAddAppDataToUploadQueue(chainId, appData) diff --git a/src/custom/utils/appData.ts b/src/custom/utils/appData.ts index 7e56b05ab7..bd07ea0b90 100644 --- a/src/custom/utils/appData.ts +++ b/src/custom/utils/appData.ts @@ -2,21 +2,33 @@ import { COW_SDK } from 'constants/index' import { MetadataDoc, QuoteMetadata, ReferralMetadata, SupportedChainId } from '@cowprotocol/cow-sdk' import { environmentName } from 'utils/environments' -const QUOTE_METADATA_VERSION = '0.1.0' +//TODO: move helper methods to SDK +const QUOTE_METADATA_VERSION = '0.2.0' const REFERRER_METADATA_VERSION = '0.1.0' -export async function buildAppData( - chainId: SupportedChainId, - sellAmount: string, - buyAmount: string, - quoteId: number | undefined, - referrerAccount: string | undefined, +export type BuildAppDataParams = { + chainId: SupportedChainId + slippageBips: string + sellAmount?: string + buyAmount?: string + quoteId?: number + referrerAccount?: string appCode: string -) { +} + +export async function buildAppData({ + chainId, + slippageBips, + sellAmount, + buyAmount, + quoteId, + referrerAccount, + appCode, +}: BuildAppDataParams) { const sdk = COW_SDK[chainId] // build quote metadata, not required in the schema but always present - const quoteMetadata = _buildQuoteMetadata(sellAmount, buyAmount, quoteId) + const quoteMetadata = _buildQuoteMetadata(slippageBips) const metadata: MetadataDoc = { quote: quoteMetadata } // build referrer metadata, optional @@ -31,13 +43,8 @@ export async function buildAppData( return { doc, calculatedAppData } } -function _buildQuoteMetadata(sellAmount: string, buyAmount: string, quoteId: number | undefined): QuoteMetadata { - return { - id: quoteId?.toString(), // Comes from the api as number|null, metadata expects a string|undefined - sellAmount, - buyAmount, - version: QUOTE_METADATA_VERSION, - } +function _buildQuoteMetadata(slippageBips: string): QuoteMetadata { + return { version: QUOTE_METADATA_VERSION, slippageBips } } function _buildReferralMetadata(address: string): ReferralMetadata { diff --git a/src/custom/utils/misc.ts b/src/custom/utils/misc.ts index eb781aad42..15f59279ef 100644 --- a/src/custom/utils/misc.ts +++ b/src/custom/utils/misc.ts @@ -1,6 +1,7 @@ import { SupportedChainId as ChainId } from 'constants/chains' import { Market } from 'types/index' import { OrderKind } from '@cowprotocol/contracts' +import { Percent } from '@uniswap/sdk-core' const PROVIDER_REJECT_REQUEST_CODE = 4001 // See https://eips.ethereum.org/EIPS/eip-1193 const PROVIDER_REJECT_REQUEST_ERROR_MESSAGES = ['User denied message signature', 'User rejected the transaction'] @@ -157,3 +158,11 @@ export function isRejectRequestProviderError(error: any) { return false } + +/** + * Helper function that transforms a Percent instance into the correspondent BIPS value as a string + * @param percent + */ +export function percentToBips(percent: Percent): string { + return percent.multiply('100').toSignificant() +}