Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions packages/public-api/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ ACROSS_INTEGRATOR_ID=
BEBOP_API_KEY=
CHAINFLIP_API_KEY=
NEAR_INTENTS_API_KEY=
TENDERLY_API_KEY=
TENDERLY_ACCOUNT_SLUG=
TENDERLY_PROJECT_SLUG=

# Affiliate
DEFAULT_AFFILIATE_BPS=60
Expand Down
3 changes: 0 additions & 3 deletions packages/public-api/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ export const getServerConfig = (): SwapperConfig => ({
VITE_RELAY_API_URL: env.RELAY_API_URL,
VITE_BEBOP_API_KEY: env.BEBOP_API_KEY,
VITE_NEAR_INTENTS_API_KEY: env.NEAR_INTENTS_API_KEY,
VITE_TENDERLY_API_KEY: env.TENDERLY_API_KEY,
VITE_TENDERLY_ACCOUNT_SLUG: env.TENDERLY_ACCOUNT_SLUG,
VITE_TENDERLY_PROJECT_SLUG: env.TENDERLY_PROJECT_SLUG,
VITE_TRON_GRID_API_KEY: env.TRON_GRID_API_KEY,
VITE_SUI_NODE_URL: env.SUI_NODE_URL,
VITE_ACROSS_API_URL: env.ACROSS_API_URL,
Expand Down
3 changes: 0 additions & 3 deletions packages/public-api/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ const envSchema = z.object({
BOB_GATEWAY_API_KEY: z.string().default(''),
CHAINFLIP_API_KEY: z.string().min(1),
NEAR_INTENTS_API_KEY: z.string().min(1),
TENDERLY_API_KEY: z.string().min(1),
TENDERLY_ACCOUNT_SLUG: z.string().min(1),
TENDERLY_PROJECT_SLUG: z.string().min(1),
TRON_GRID_API_KEY: z.string().default(''),

// Feature flags
Expand Down
2 changes: 2 additions & 0 deletions packages/public-api/src/routes/rates/getRates.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isEvmChainId } from '@shapeshiftoss/chain-adapters'
import type { GetTradeRateInput } from '@shapeshiftoss/swapper'
import { getTradeRates, swappers, TradeQuoteError } from '@shapeshiftoss/swapper'
import type { Request, Response } from 'express'
Expand Down Expand Up @@ -84,6 +85,7 @@ export const getRates = async (req: Request, res: Response): Promise<void> => {
accountNumber: undefined,
quoteOrRate: 'rate' as const,
chainId: sellAsset.chainId,
...(isEvmChainId(sellAsset.chainId) && { supportsEIP1559: false as const }),
}

const ratePromises = ENABLED_SWAPPER_NAMES.map(async (swapperName): Promise<ApiRate | null> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type { AcrossSwapTx } from './types'

type BaseArgs = {
swapTx: AcrossSwapTx
spenderAddress: string
fallbackNetworkFeeCryptoBaseUnit: string
}

Expand All @@ -39,7 +40,16 @@ export function getAcrossStepData(
export async function getAcrossStepData(
args: GetAcrossStepDataArgs,
): Promise<Result<AcrossRateStepData | AcrossQuoteStepData, SwapErrorRight>> {
const { swapTx, sellAsset, from, type, input, fallbackNetworkFeeCryptoBaseUnit, deps } = args
const {
swapTx,
sellAsset,
spenderAddress,
from,
type,
input,
fallbackNetworkFeeCryptoBaseUnit,
deps,
} = args

const supportsEIP1559 = 'supportsEIP1559' in input ? input.supportsEIP1559 : false

Expand All @@ -56,6 +66,12 @@ export async function getAcrossStepData(
gasLimit: swapTx.gas,
}

const stateOverride = {
sellAsset,
sellAmountCryptoBaseUnit: input.sellAmountIncludingProtocolFeesCryptoBaseUnit,
spenderAddress,
}

if (type === 'rate') {
const networkFeeCryptoBaseUnit = await (async () => {
try {
Expand All @@ -64,6 +80,7 @@ export async function getAcrossStepData(
transactionData,
from,
supportsEIP1559,
stateOverride,
})
} catch {
return fallbackNetworkFeeCryptoBaseUnit
Expand All @@ -81,6 +98,7 @@ export async function getAcrossStepData(
transactionData,
from,
supportsEIP1559,
stateOverride,
})

const stepData: AcrossQuoteStepData = { transactionData, networkFeeCryptoBaseUnit }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ export const getAcrossTradeContext = async ({
return `${bridgeFeeAssetCaipChainId}/${tokenStandard}:${bridgeFeeAsset.address}`
})()

const allowanceContract = isEvmChainId(sellAsset.chainId) ? quote.checks.allowance.spender : ''

const protocolFees: QuoteFeeData['protocolFees'] = bridgeFeeAssetId
? {
[bridgeFeeAssetId]: {
Expand All @@ -214,7 +216,7 @@ export const getAcrossTradeContext = async ({
slippageTolerancePercentageDecimal: input.slippageTolerancePercentageDecimal,
},
stepCommon: {
allowanceContract: isEvmChainId(sellAsset.chainId) ? quote.checks.allowance.spender : '',
allowanceContract,
rate,
buyAmountBeforeFeesCryptoBaseUnit,
buyAmountAfterFeesCryptoBaseUnit,
Expand All @@ -240,6 +242,7 @@ export const getAcrossTradeContext = async ({
swapTx: quote.swapTx,
sellAsset,
from: depositor,
spenderAddress: allowanceContract,
fallbackNetworkFeeCryptoBaseUnit: quote.fees.originGas.amount,
deps,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type BaseArgs = {
bridgeType: BRIDGE_TYPE
sellAmountCryptoBaseUnit: string
buyAsset: Asset
spenderAddress: string
}

export type GetArbitrumBridgeStepDataArgs = StepDataArgs<
Expand All @@ -40,7 +41,8 @@ export function getArbitrumBridgeStepData(
export async function getArbitrumBridgeStepData(
args: GetArbitrumBridgeStepDataArgs,
): Promise<Result<ArbitrumBridgeRateStepData | ArbitrumBridgeQuoteStepData, SwapErrorRight>> {
const { input, deps, bridgeType, sellAmountCryptoBaseUnit, sellAsset, buyAsset } = args
const { input, deps, bridgeType, sellAmountCryptoBaseUnit, sellAsset, buyAsset, spenderAddress } =
args

const adapter = deps.assertGetEvmChainAdapter(sellAsset.chainId)
const supportsEIP1559 = 'supportsEIP1559' in input ? input.supportsEIP1559 : false
Expand All @@ -58,11 +60,13 @@ export async function getArbitrumBridgeStepData(
return Ok(stepData)
}

const { from, receiveAddress } = args

const request = await buildArbitrumBridgeRequest({
bridgeType,
sellAmountCryptoBaseUnit,
from: args.from,
receiveAddress: args.receiveAddress,
from,
receiveAddress,
sellAsset,
buyAsset,
})
Expand All @@ -83,8 +87,13 @@ export async function getArbitrumBridgeStepData(
const networkFeeCryptoBaseUnit = await getEvmNetworkFeeCryptoBaseUnit({
adapter,
transactionData,
from: args.from,
from,
supportsEIP1559,
stateOverride: {
sellAsset,
sellAmountCryptoBaseUnit,
spenderAddress,
},
})

const stepData: ArbitrumBridgeQuoteStepData = { transactionData, networkFeeCryptoBaseUnit }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export const getArbitrumBridgeTradeContext = async ({
sellAmountCryptoBaseUnit: sellAmountIncludingProtocolFeesCryptoBaseUnit,
buyAsset,
sellAsset,
spenderAddress: allowanceContract,
deps,
},
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { BebopQuoteResponse } from '../types'

type BaseArgs = {
tx: BebopQuoteResponse['tx']
spenderAddress: string
}

export type GetBebopStepDataArgs = StepDataArgs<BaseArgs, { from: string }>
Expand All @@ -27,7 +28,7 @@ export function getBebopStepData(
export async function getBebopStepData(
args: GetBebopStepDataArgs,
): Promise<Result<BebopRateStepData | BebopQuoteStepData, SwapErrorRight>> {
const { tx, sellAsset, type, input, from, deps } = args
const { tx, spenderAddress, sellAsset, type, input, from, deps } = args

const adapter = deps.assertGetEvmChainAdapter(sellAsset.chainId)
const supportsEIP1559 = 'supportsEIP1559' in input ? input.supportsEIP1559 : false
Expand Down Expand Up @@ -65,6 +66,11 @@ export async function getBebopStepData(
transactionData,
from,
supportsEIP1559,
stateOverride: {
sellAsset,
sellAmountCryptoBaseUnit: input.sellAmountIncludingProtocolFeesCryptoBaseUnit,
spenderAddress,
},
})

const stepData: BebopQuoteStepData = { transactionData, networkFeeCryptoBaseUnit }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ export const getBebopTradeContext = async ({
const buyAmountBeforeFeesCryptoBaseUnit = buyTokenData.amountBeforeFee || buyAmount
const buyAmountAfterFeesCryptoBaseUnit = buyAmount

const allowanceContract = isNativeEvmAsset(sellAsset.assetId) ? '' : quote.approvalTarget

return Ok({
tradeCommon: {
id: uuid(),
Expand All @@ -91,7 +93,7 @@ export const getBebopTradeContext = async ({
slippageTolerancePercentageDecimal,
},
stepCommon: {
allowanceContract: isNativeEvmAsset(sellAsset.assetId) ? '' : quote.approvalTarget,
allowanceContract,
rate,
buyAmountBeforeFeesCryptoBaseUnit,
buyAmountAfterFeesCryptoBaseUnit,
Expand All @@ -112,6 +114,7 @@ export const getBebopTradeContext = async ({
},
stepDataArgs: {
tx: quote.tx,
spenderAddress: allowanceContract,
sellAsset,
from,
deps,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { createBobGatewayOrder, toTronBase58 } from './helpers'
type BaseArgs = {
quote: GatewayQuoteV3
sellAmountCryptoBaseUnit: string
spenderAddress: string
}

export type GetBobGatewayStepDataArgs = StepDataArgs<BaseArgs>
Expand All @@ -45,7 +46,7 @@ export function getBobGatewayStepData(
export async function getBobGatewayStepData(
args: GetBobGatewayStepDataArgs,
): Promise<Result<BobGatewayRateStepData | BobGatewayQuoteStepData, SwapErrorRight>> {
const { input, quote, sellAsset, sellAmountCryptoBaseUnit, deps } = args
const { input, quote, sellAsset, sellAmountCryptoBaseUnit, spenderAddress, deps } = args
const { chainNamespace } = fromChainId(sellAsset.chainId)

// Rates estimate off the quote shape; quotes resolve the executable order once up front
Expand Down Expand Up @@ -176,7 +177,11 @@ export async function getBobGatewayStepData(
transactionData,
from,
supportsEIP1559: input.supportsEIP1559,
gasLimitBuffer: 1.2,
stateOverride: {
sellAsset,
sellAmountCryptoBaseUnit,
spenderAddress,
},
})

const stepData: BobGatewayQuoteStepData = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isEvmChainId } from '@shapeshiftoss/chain-adapters'
import type { Result } from '@sniptt/monads'
import { Err, Ok } from '@sniptt/monads'
import { v4 as uuid } from 'uuid'
Expand Down Expand Up @@ -107,6 +108,7 @@ export const getBobGatewayTradeContext = async ({
quote,
sellAmountCryptoBaseUnit: sellAmountIncludingProtocolFeesCryptoBaseUnit,
sellAsset,
spenderAddress: isEvmChainId(sellAsset.chainId) ? allowanceContract : '',
deps,
},
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ vi.mock('../xhr', () => ({
isBuildTxSuccess: () => true,
}))

// The override path reads live chain state - resolve to no override so estimation exercises the
// mocked adapter
vi.mock('../../../utils/evm/stateOverride', async importOriginal => ({
...(await importOriginal<object>()),
getMinimalStateOverride: vi.fn().mockResolvedValue(undefined),
}))

const mockEvmChainAdapter = {
getGasFeeData: () =>
Promise.resolve({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import { ROUTE_QUOTE } from '../test-data/routeQuote'
import type { BuildTxSuccessItem, RouteSuccessItem } from '../types'
import { getButterSwapStepData } from './getButterSwapStepData'

// The override path reads live chain state - resolve to no override so estimation exercises the
// mocked adapter
vi.mock('../../../utils/evm/stateOverride', async importOriginal => ({
...(await importOriginal<object>()),
getMinimalStateOverride: vi.fn().mockResolvedValue(undefined),
}))

const route = (ROUTE_QUOTE.data as RouteSuccessItem[])[0]

// The provider gas fee, in human units, that every fallback path prices off of
Expand Down Expand Up @@ -63,6 +70,7 @@ describe('getButterSwapStepData', () => {
sellAsset: WETH,
feeAsset: ETH,
sellAmountCryptoBaseUnit: '999000000000000000',
spenderAddress: '',
})

// gasEstimatedTarget 1159118 * gasPrice 1000000000
Expand All @@ -78,6 +86,7 @@ describe('getButterSwapStepData', () => {
sellAsset: WETH,
feeAsset: ETH,
sellAmountCryptoBaseUnit: '999000000000000000',
spenderAddress: '',
})

expect(actual.unwrap()).toEqual({
Expand All @@ -96,6 +105,7 @@ describe('getButterSwapStepData', () => {
sellAsset: WETH,
feeAsset: ETH,
sellAmountCryptoBaseUnit: '999000000000000000',
spenderAddress: '',
})

// gasEstimatedTarget 1159118 is ignored - the tx carries the buffered on chain estimate
Expand Down Expand Up @@ -123,6 +133,7 @@ describe('getButterSwapStepData', () => {
sellAsset: WETH,
feeAsset: ETH,
sellAmountCryptoBaseUnit: '999000000000000000',
spenderAddress: '',
})

const { transactionData, networkFeeCryptoBaseUnit } = actual.unwrap()
Expand All @@ -143,6 +154,7 @@ describe('getButterSwapStepData', () => {
sellAsset: WETH,
feeAsset: ETH,
sellAmountCryptoBaseUnit: '999000000000000000',
spenderAddress: '',
})

expect(actual.isErr()).toBe(true)
Expand All @@ -167,6 +179,7 @@ describe('getButterSwapStepData', () => {
sellAsset: BTC,
feeAsset: BTC,
sellAmountCryptoBaseUnit: '100000',
spenderAddress: '',
})

// 10 sats/byte * 200 vbyte default
Expand All @@ -184,6 +197,7 @@ describe('getButterSwapStepData', () => {
sellAsset: BTC,
feeAsset: BTC,
sellAmountCryptoBaseUnit: '100000',
spenderAddress: '',
})

expect(actual.unwrap()).toEqual({
Expand All @@ -208,6 +222,7 @@ describe('getButterSwapStepData', () => {
sellAsset: BTC,
feeAsset: BTC,
sellAmountCryptoBaseUnit: '100000',
spenderAddress: '',
})

expect(actual.isErr()).toBe(true)
Expand All @@ -227,6 +242,7 @@ describe('getButterSwapStepData', () => {
sellAsset: SOL,
feeAsset: SOL,
sellAmountCryptoBaseUnit: '1000000000',
spenderAddress: '',
})

expect(actual.unwrap()).toEqual({
Expand Down Expand Up @@ -254,6 +270,7 @@ describe('getButterSwapStepData', () => {
sellAsset: TRX,
feeAsset: TRX,
sellAmountCryptoBaseUnit: '1000000',
spenderAddress: '',
})

expect(actual.unwrap()).toEqual({
Expand All @@ -279,6 +296,7 @@ describe('getButterSwapStepData', () => {
sellAsset: RUNE,
feeAsset: RUNE,
sellAmountCryptoBaseUnit: '100000000',
spenderAddress: '',
})

expect(actual.isErr()).toBe(true)
Expand Down
Loading
Loading