From cc484801b3dd3521ff58bd8e2ff5cc4851c39382 Mon Sep 17 00:00:00 2001 From: DaoDev <88341957+DaoDev44@users.noreply.github.com> Date: Mon, 4 Oct 2021 19:01:41 -0600 Subject: [PATCH] add approvalNeeded to ZrxSwapper --- packages/swapper/src/api.ts | 10 ++++++- .../swappers/thorchain/ThorchainSwapper.ts | 6 +++- .../swapper/src/swappers/zrx/ZrxSwapper.ts | 7 +++++ .../zrx/approvalNeeded/approvalNeeded.test.ts | 30 +++++++++++++++++++ .../zrx/approvalNeeded/approvalNeeded.ts | 22 ++++++++++++++ .../swappers/zrx/buildQuoteTx/buildQuoteTx.ts | 26 +--------------- packages/types/src/types.ts | 11 +++++++ 7 files changed, 85 insertions(+), 27 deletions(-) create mode 100644 packages/swapper/src/swappers/zrx/approvalNeeded/approvalNeeded.test.ts create mode 100644 packages/swapper/src/swappers/zrx/approvalNeeded/approvalNeeded.ts diff --git a/packages/swapper/src/api.ts b/packages/swapper/src/api.ts index a4f941356..48c94ce82 100644 --- a/packages/swapper/src/api.ts +++ b/packages/swapper/src/api.ts @@ -1,12 +1,14 @@ import { HDWallet } from '@shapeshiftoss/hdwallet-core' import { Asset, + ApprovalNeededInput, + ApprovalNeededOutput, BuildQuoteTxInput, GetQuoteInput, Quote, SwapperType, ExecQuoteInput, - ExecQuoteOutput + ExecQuoteOutput, } from '@shapeshiftoss/types' export class SwapError extends Error {} @@ -53,4 +55,10 @@ export interface Swapper { * @param wallet */ executeQuote(args: ExecQuoteInput): Promise + + /** + * Get a boolean if a quote needs approval + */ + + approvalNeeded(args: ApprovalNeededInput): Promise } diff --git a/packages/swapper/src/swappers/thorchain/ThorchainSwapper.ts b/packages/swapper/src/swappers/thorchain/ThorchainSwapper.ts index 9e280337e..f5022bf05 100644 --- a/packages/swapper/src/swappers/thorchain/ThorchainSwapper.ts +++ b/packages/swapper/src/swappers/thorchain/ThorchainSwapper.ts @@ -1,4 +1,4 @@ -import { Asset, SwapperType, Quote, ExecQuoteOutput } from '@shapeshiftoss/types' +import { Asset, SwapperType, Quote, ExecQuoteOutput, ApprovalNeededOutput } from '@shapeshiftoss/types' import { Swapper } from '../../api' export class ThorchainSwapper implements Swapper { @@ -31,4 +31,8 @@ export class ThorchainSwapper implements Swapper { async executeQuote(): Promise { throw new Error('ThorchainSwapper: executeQuote unimplemented') } + + async approvalNeeded(): Promise { + throw new Error('ThorchainSwapper: executeQuote unimplemented') + } } diff --git a/packages/swapper/src/swappers/zrx/ZrxSwapper.ts b/packages/swapper/src/swappers/zrx/ZrxSwapper.ts index 5d7a8bf10..285561e1b 100644 --- a/packages/swapper/src/swappers/zrx/ZrxSwapper.ts +++ b/packages/swapper/src/swappers/zrx/ZrxSwapper.ts @@ -4,6 +4,8 @@ import BigNumber from 'bignumber.js' import { zrxService } from './utils/zrxService' import { Asset, + ApprovalNeededInput, + ApprovalNeededOutput, BuildQuoteTxInput, ChainTypes, GetQuoteInput, @@ -19,6 +21,7 @@ import { Swapper } from '../../api' import { buildQuoteTx } from './buildQuoteTx/buildQuoteTx' import { getZrxQuote } from './getQuote/getQuote' import { executeQuote } from './executeQuote/executeQuote' +import { approvalNeeded } from './approvalNeeded/approvalNeeded' export type ZrxSwapperDeps = { adapterManager: ChainAdapterManager @@ -81,4 +84,8 @@ export class ZrxSwapper implements Swapper { async executeQuote(args: ExecQuoteInput): Promise { return executeQuote(this.deps, args) } + + async approvalNeeded(args: ApprovalNeededInput): Promise { + return approvalNeeded(this.deps, args) + } } diff --git a/packages/swapper/src/swappers/zrx/approvalNeeded/approvalNeeded.test.ts b/packages/swapper/src/swappers/zrx/approvalNeeded/approvalNeeded.test.ts new file mode 100644 index 000000000..7f33d99db --- /dev/null +++ b/packages/swapper/src/swappers/zrx/approvalNeeded/approvalNeeded.test.ts @@ -0,0 +1,30 @@ +import Web3 from 'web3' +import { HDWallet } from '@shapeshiftoss/hdwallet-core' +import { ChainTypes } from '@shapeshiftoss/types' +import { ChainAdapterManager } from '@shapeshiftoss/chain-adapters' +import { approvalNeeded } from './approvalNeeded' +import { setupQuote } from '../utils/test-data/setupSwapQuote' + +const setup = () => { + const unchainedUrls = { + [ChainTypes.Ethereum]: 'http://localhost:31300/api/v1' + } + const ethNodeUrl = 'http://localhost:1000' + const adapterManager = new ChainAdapterManager(unchainedUrls) + const web3Provider = new Web3.providers.HttpProvider(ethNodeUrl) + const web3 = new Web3(web3Provider) + + return { web3, adapterManager } +} + +describe('approvalNeeded', () => { + const args = setup() + const wallet = {} + const { quoteInput, sellAsset } = setupQuote() + + it('returns false if sellAsset symbol is ETH', async () => { + const input = { quote: { ...quoteInput, sellAsset: { ...sellAsset, symbol: 'ETH' } }, wallet } + + expect(await approvalNeeded(args, input)).toEqual({ approvalNeeded: false }) + }) +}) diff --git a/packages/swapper/src/swappers/zrx/approvalNeeded/approvalNeeded.ts b/packages/swapper/src/swappers/zrx/approvalNeeded/approvalNeeded.ts new file mode 100644 index 000000000..66f14bfe8 --- /dev/null +++ b/packages/swapper/src/swappers/zrx/approvalNeeded/approvalNeeded.ts @@ -0,0 +1,22 @@ +import { AxiosResponse } from 'axios' +import { ChainAdapter } from '@shapeshiftoss/chain-adapters' +import { ApprovalNeededInput, ApprovalNeededOutput, ChainTypes, QuoteResponse } from '@shapeshiftoss/types' +import { DEFAULT_SLIPPAGE, AFFILIATE_ADDRESS, DEFAULT_ETH_PATH } from '../utils/constants' + +import { ZrxSwapperDeps } from '../ZrxSwapper' +import { zrxService } from '../utils/zrxService' +const APPROVAL_BUY_AMOUNT = '100000000000000000' // A valid buy amount - 0.1 ETH + +export async function approvalNeeded( + { adapterManager }: ZrxSwapperDeps, + { quote, wallet }: ApprovalNeededInput +): Promise { + const { sellAsset } = quote + + if (sellAsset.symbol === 'ETH' || sellAsset.chain !== ChainTypes.Ethereum) { + return { approvalNeeded: false } + } + + + return { approvalNeeded: true } +} diff --git a/packages/swapper/src/swappers/zrx/buildQuoteTx/buildQuoteTx.ts b/packages/swapper/src/swappers/zrx/buildQuoteTx/buildQuoteTx.ts index 877782ab1..b94ad4b0f 100644 --- a/packages/swapper/src/swappers/zrx/buildQuoteTx/buildQuoteTx.ts +++ b/packages/swapper/src/swappers/zrx/buildQuoteTx/buildQuoteTx.ts @@ -3,7 +3,7 @@ import { AxiosResponse } from 'axios' import * as rax from 'retry-axios' import { ChainAdapter } from '@shapeshiftoss/chain-adapters' import { SwapError } from '../../..' -import { Quote, BuildQuoteTxInput } from '@shapeshiftoss/types' +import { Quote, QuoteResponse, BuildQuoteTxInput } from '@shapeshiftoss/types' import { ZrxSwapperDeps } from '../ZrxSwapper' import { applyAxiosRetry } from '../utils/applyAxiosRetry' import { erc20AllowanceAbi } from '../utils/abi/erc20-abi' @@ -18,30 +18,6 @@ import { MAX_SLIPPAGE } from '../utils/constants' -type LiquiditySource = { - name: string - proportion: string -} - -type QuoteResponse = { - price: string - guaranteedPrice: string - to: string - data?: string - value?: string - gas?: string - estimatedGas?: string - gasPrice?: string - protocolFee?: string - minimumProtocolFee?: string - buyTokenAddress?: string - sellTokenAddress?: string - buyAmount?: string - sellAmount?: string - allowanceTarget?: string - sources?: Array -} - export async function buildQuoteTx( { adapterManager, web3 }: ZrxSwapperDeps, { input, wallet }: BuildQuoteTxInput diff --git a/packages/types/src/types.ts b/packages/types/src/types.ts index c0559dfbd..22a829edb 100644 --- a/packages/types/src/types.ts +++ b/packages/types/src/types.ts @@ -184,6 +184,17 @@ export type ExecQuoteOutput = { txid: string } +export type ApprovalNeededInput = { + quote: Quote + wallet: HDWallet +} + +export type ApprovalNeededOutput = { + approvalNeeded: boolean + gas?: string + gasPrice?: string +} + // chain-adapters export type Transaction = {