Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: split trade rates and quotes final wire-up #8079

Merged
merged 69 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from 62 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
9fd8bd9
feat: let's get this chunky boi started
gomesalexandre Nov 4, 2024
d0c65db
[skip ci] wip: meaty rates vs. quotes final wire-up
gomesalexandre Nov 5, 2024
5806875
feat: progression
gomesalexandre Nov 5, 2024
0ea5753
feat: getting there
gomesalexandre Nov 5, 2024
f813200
feat: progression
gomesalexandre Nov 5, 2024
3f226ad
feat: classic zrx too
gomesalexandre Nov 5, 2024
17d75df
feat: stopping point
gomesalexandre Nov 5, 2024
c0feac6
feat: she's disgusting but she's working, fuck yeah
gomesalexandre Nov 5, 2024
e0c4124
feat: feelsgoodman.jpg
gomesalexandre Nov 5, 2024
5192de7
feat: cleanup
gomesalexandre Nov 6, 2024
2e6d337
feat: more cleanup
gomesalexandre Nov 6, 2024
c737ce0
feat: more more cleanup
gomesalexandre Nov 6, 2024
939309b
feat: more more more cleanup
gomesalexandre Nov 6, 2024
ee990ec
feat: permit2 progression
gomesalexandre Nov 6, 2024
10bec03
feat: the bloodbath continues
gomesalexandre Nov 6, 2024
318c1a9
fix: lifi receiveAddress should be undefined on rate
gomesalexandre Nov 6, 2024
65e4020
Merge remote-tracking branch 'origin/develop' into feat_chunky_boi_lfg
gomesalexandre Nov 6, 2024
9297644
feat: portals trade rates
gomesalexandre Nov 6, 2024
acb603f
feat: the bloodbath continues
gomesalexandre Nov 6, 2024
9d5598c
fix: thor getRate undefined receiveAddress
gomesalexandre Nov 7, 2024
47420ca
feat: another one bites the dust
gomesalexandre Nov 7, 2024
2b5cdcd
feat: revert portals to estimate endpoint
gomesalexandre Nov 7, 2024
662c7d5
feat: ihavenoideawhatimdoingdog.jpg
gomesalexandre Nov 7, 2024
5fa3d0c
fix: receiveAddress should be undefined for arb trade rate
gomesalexandre Nov 7, 2024
4944517
Merge remote-tracking branch 'origin/develop' into feat_chunky_boi_lfg
gomesalexandre Nov 8, 2024
7faf638
feat: move getTradeQuoteInput to react-query
gomesalexandre Nov 8, 2024
6634b9e
feat: feelsgoodman.jpg
gomesalexandre Nov 8, 2024
64d409c
feat: wip portals gas things pending product feedback
gomesalexandre Nov 8, 2024
556df27
feat: conkschitschtency
gomesalexandre Nov 8, 2024
2367bf2
feat: two hard things in software
gomesalexandre Nov 8, 2024
e6d625a
Revert "feat: permit2 progression"
gomesalexandre Nov 8, 2024
18d0542
feat: gm zrx permit2
gomesalexandre Nov 8, 2024
10fd051
feat: renamy and bring back unknown tooltip
gomesalexandre Nov 8, 2024
0534047
feat: tooltip in quote too
gomesalexandre Nov 8, 2024
0a9df4f
feat: stop passing receiveAddress in getTradeQuoteInput
gomesalexandre Nov 8, 2024
21e2306
fix: disconnected state
gomesalexandre Nov 8, 2024
907284b
Merge remote-tracking branch 'origin/develop' into feat_chunky_boi_lfg
gomesalexandre Nov 11, 2024
1a119eb
fix: ci
gomesalexandre Nov 11, 2024
6843340
feat: cleanup log
gomesalexandre Nov 11, 2024
880866b
fix: flashy flash
gomesalexandre Nov 11, 2024
a441116
feat: progression
gomesalexandre Nov 11, 2024
df90762
Merge remote-tracking branch 'origin/develop' into feat_chunky_boi_lfg
gomesalexandre Nov 13, 2024
847119d
fix: tests
gomesalexandre Nov 13, 2024
c940ce2
fix: lifi
gomesalexandre Nov 14, 2024
bbf004b
feat: flag
gomesalexandre Nov 14, 2024
d69cc53
Merge remote-tracking branch 'origin/develop' into feat_chunky_boi_lfg
gomesalexandre Nov 18, 2024
3d26027
feat: rm todo
gomesalexandre Nov 18, 2024
2150294
rate expired modal
reallybeard Nov 18, 2024
5b28687
Update RateChanged.tsx
reallybeard Nov 18, 2024
f8f2155
fix: raceish condition
gomesalexandre Nov 18, 2024
1982311
feat: rm dead comment
gomesalexandre Nov 18, 2024
cc766f9
fix: lint
gomesalexandre Nov 18, 2024
8e8b80e
feat: cleanup
gomesalexandre Nov 18, 2024
ee06a4d
feat: leverage viem
gomesalexandre Nov 18, 2024
f80dff5
feat: rm
gomesalexandre Nov 18, 2024
2bacb52
feat: cleanup
gomesalexandre Nov 18, 2024
aca6ed5
feat: remove eslint-ignore
gomesalexandre Nov 18, 2024
3622358
feat: jfc
gomesalexandre Nov 18, 2024
1cc6c8a
feat: rm todo
gomesalexandre Nov 18, 2024
add4215
feat: unbork chainflip
gomesalexandre Nov 18, 2024
00c4562
feat: cleanup
gomesalexandre Nov 18, 2024
1d5fc11
feat: better naming
gomesalexandre Nov 18, 2024
f77e9ac
fix: emptiness checks
gomesalexandre Nov 19, 2024
f8e2b7d
fix: equality checks
gomesalexandre Nov 19, 2024
358c8a7
fix: jfc 2
gomesalexandre Nov 19, 2024
7dbf87e
fix: ci
gomesalexandre Nov 19, 2024
f1249e1
Merge remote-tracking branch 'origin/develop' into feat_chunky_boi_lfg
gomesalexandre Nov 19, 2024
13beb4e
Merge remote-tracking branch 'origin/develop' into feat_chunky_boi_lfg
gomesalexandre Nov 20, 2024
f50ed9d
feat: rm log
gomesalexandre Nov 20, 2024
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
2 changes: 1 addition & 1 deletion .env.base
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ REACT_APP_FEATURE_FOX_PAGE_FOX_FARMING_SECTION=true
REACT_APP_FEATURE_FOX_PAGE_GOVERNANCE=true
REACT_APP_FEATURE_PHANTOM_WALLET=true
REACT_APP_FEATURE_ZRX_PERMIT2=true
REACT_APP_FEATURE_PUBLIC_TRADE_ROUTE=false
REACT_APP_FEATURE_PUBLIC_TRADE_ROUTE=true
gomesalexandre marked this conversation as resolved.
Show resolved Hide resolved
REACT_APP_FEATURE_THOR_FREE_FEES=true
REACT_APP_FEATURE_LIMIT_ORDERS=false

Expand Down
4 changes: 2 additions & 2 deletions packages/contracts/src/contractManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ export const getOrCreateContractByType: <A extends KnownContractAddress, T exten
type,
chainId,
}: {
address: string | `0x${string}`
address: string | Address
type: T
chainId: ChainId
}) => KnownContractByType<A, T> = <A extends KnownContractAddress, T extends ContractType>({
address,
type,
chainId,
}: {
address: string | `0x${string}`
address: string | Address
type: T
chainId: ChainId
}): KnownContractByType<A, T> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import type {
TradeRate,
} from '../../types'
import { checkEvmSwapStatus, getHopByIndex, isExecutableTradeQuote } from '../../utils'
import { getTradeQuote, getTradeRate } from './getTradeQuote/getTradeQuote'
import { getTradeQuote } from './getTradeQuote/getTradeQuote'
import { getTradeRate } from './getTradeRate/getTradeRate'
import { fetchArbitrumBridgeQuote } from './utils/fetchArbitrumBridgeSwap'
import { assertValidTrade } from './utils/helpers'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,24 @@
import { ethChainId } from '@shapeshiftoss/caip'
import { type HDWallet, supportsETH } from '@shapeshiftoss/hdwallet-core'
import { supportsETH } from '@shapeshiftoss/hdwallet-core'
import type { Result } from '@sniptt/monads'
import { Err, Ok } from '@sniptt/monads'
import { v4 as uuid } from 'uuid'

import { getDefaultSlippageDecimalPercentageForSwapper } from '../../../constants'
import type {
GetEvmTradeQuoteInput,
GetEvmTradeQuoteInputBase,
GetEvmTradeRateInput,
SingleHopTradeQuoteSteps,
SingleHopTradeRateSteps,
SwapErrorRight,
SwapperDeps,
TradeQuote,
TradeRate,
} from '../../../types'
import { SwapperName, TradeQuoteError } from '../../../types'
import { makeSwapErrorRight } from '../../../utils'
import type { ArbitrumBridgeTradeQuote, GetEvmTradeQuoteInputWithWallet } from '../types'
import type { FetchArbitrumBridgeQuoteInput } from '../utils/fetchArbitrumBridgeSwap'
import {
fetchArbitrumBridgePrice,
fetchArbitrumBridgeQuote,
} from '../utils/fetchArbitrumBridgeSwap'
import { fetchArbitrumBridgeQuote } from '../utils/fetchArbitrumBridgeSwap'
import { assertValidTrade } from '../utils/helpers'

export type GetEvmTradeQuoteInputWithWallet = Omit<GetEvmTradeQuoteInputBase, 'supportsEIP1559'> & {
wallet: HDWallet
}

type ArbitrumBridgeSpecificMetadata = {
direction: 'deposit' | 'withdrawal'
}

export type ArbitrumBridgeTradeQuote = TradeQuote & ArbitrumBridgeSpecificMetadata
export type ArbitrumBridgeTradeRate = TradeRate & ArbitrumBridgeSpecificMetadata

export const isArbitrumBridgeTradeQuote = (
quote: TradeQuote | undefined,
): quote is ArbitrumBridgeTradeQuote => !!quote && 'direction' in quote
Expand Down Expand Up @@ -138,86 +121,3 @@ export async function getTradeQuote(
)
}
}

export async function getTradeRate(
input: GetEvmTradeRateInput,
{ assertGetEvmChainAdapter }: SwapperDeps,
): Promise<Result<ArbitrumBridgeTradeRate, SwapErrorRight>> {
const {
chainId,
sellAsset,
buyAsset,
supportsEIP1559,
receiveAddress,
sellAmountIncludingProtocolFeesCryptoBaseUnit,
sendAddress,
} = input

const assertion = await assertValidTrade({ buyAsset, sellAsset })
if (assertion.isErr()) return Err(assertion.unwrapErr())

const isDeposit = sellAsset.chainId === ethChainId

// 15 minutes for deposits, 7 days for withdrawals
const estimatedExecutionTimeMs = isDeposit ? 15 * 60 * 1000 : 7 * 24 * 60 * 60 * 1000

// 1/1 when bridging on Arbitrum bridge
const rate = '1'

try {
const args = {
supportsEIP1559,
chainId,
buyAsset,
sellAmountIncludingProtocolFeesCryptoBaseUnit,
sellAsset,
sendAddress,
receiveAddress,
assertGetEvmChainAdapter,
quoteOrRate: 'rate',
}
const swap = await fetchArbitrumBridgePrice(args)

const buyAmountBeforeFeesCryptoBaseUnit = sellAmountIncludingProtocolFeesCryptoBaseUnit
const buyAmountAfterFeesCryptoBaseUnit = sellAmountIncludingProtocolFeesCryptoBaseUnit

return Ok({
id: uuid(),
accountNumber: undefined,
receiveAddress,
affiliateBps: '0',
potentialAffiliateBps: '0',
rate,
slippageTolerancePercentageDecimal: getDefaultSlippageDecimalPercentageForSwapper(
SwapperName.ArbitrumBridge,
),
steps: [
{
estimatedExecutionTimeMs,
allowanceContract: swap.allowanceContract,
rate,
buyAsset,
sellAsset,
accountNumber: undefined,
buyAmountBeforeFeesCryptoBaseUnit,
buyAmountAfterFeesCryptoBaseUnit,
sellAmountIncludingProtocolFeesCryptoBaseUnit,
feeData: {
protocolFees: {},
networkFeeCryptoBaseUnit: swap.networkFeeCryptoBaseUnit,
},
source: SwapperName.ArbitrumBridge,
},
] as SingleHopTradeRateSteps,
direction: isDeposit ? ('deposit' as const) : ('withdrawal' as const),
})
} catch (err) {
return Err(
makeSwapErrorRight({
message: '[ArbitrumBridge: tradeQuote] - failed to get fee data',
cause: err,
code: TradeQuoteError.NetworkFeeEstimationFailed,
}),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { ethChainId } from '@shapeshiftoss/caip'
import { type HDWallet } from '@shapeshiftoss/hdwallet-core'
import type { Result } from '@sniptt/monads'
import { Err, Ok } from '@sniptt/monads'
import { v4 as uuid } from 'uuid'

import { getDefaultSlippageDecimalPercentageForSwapper } from '../../../constants'
import type {
GetEvmTradeQuoteInputBase,
GetEvmTradeRateInput,
SingleHopTradeRateSteps,
SwapErrorRight,
SwapperDeps,
} from '../../../types'
import { SwapperName, TradeQuoteError } from '../../../types'
import { makeSwapErrorRight } from '../../../utils'
import type { ArbitrumBridgeTradeRate } from '../types'
import { fetchArbitrumBridgePrice } from '../utils/fetchArbitrumBridgeSwap'
import { assertValidTrade } from '../utils/helpers'

export type GetEvmTradeQuoteInputWithWallet = Omit<GetEvmTradeQuoteInputBase, 'supportsEIP1559'> & {
wallet: HDWallet
}

export async function getTradeRate(
input: GetEvmTradeRateInput,
{ assertGetEvmChainAdapter }: SwapperDeps,
): Promise<Result<ArbitrumBridgeTradeRate, SwapErrorRight>> {
const {
chainId,
sellAsset,
buyAsset,
supportsEIP1559,
receiveAddress,
sellAmountIncludingProtocolFeesCryptoBaseUnit,
sendAddress,
} = input

const assertion = await assertValidTrade({ buyAsset, sellAsset })
if (assertion.isErr()) return Err(assertion.unwrapErr())

const isDeposit = sellAsset.chainId === ethChainId

// 15 minutes for deposits, 7 days for withdrawals
const estimatedExecutionTimeMs = isDeposit ? 15 * 60 * 1000 : 7 * 24 * 60 * 60 * 1000

// 1/1 when bridging on Arbitrum bridge
const rate = '1'

try {
const args = {
supportsEIP1559,
chainId,
buyAsset,
sellAmountIncludingProtocolFeesCryptoBaseUnit,
sellAsset,
sendAddress,
receiveAddress,
assertGetEvmChainAdapter,
quoteOrRate: 'rate',
}
const swap = await fetchArbitrumBridgePrice(args)

const buyAmountBeforeFeesCryptoBaseUnit = sellAmountIncludingProtocolFeesCryptoBaseUnit
const buyAmountAfterFeesCryptoBaseUnit = sellAmountIncludingProtocolFeesCryptoBaseUnit

return Ok({
id: uuid(),
accountNumber: undefined,
receiveAddress: undefined,
affiliateBps: '0',
potentialAffiliateBps: '0',
rate,
slippageTolerancePercentageDecimal: getDefaultSlippageDecimalPercentageForSwapper(
SwapperName.ArbitrumBridge,
),
steps: [
{
estimatedExecutionTimeMs,
allowanceContract: swap.allowanceContract,
rate,
buyAsset,
sellAsset,
accountNumber: undefined,
buyAmountBeforeFeesCryptoBaseUnit,
buyAmountAfterFeesCryptoBaseUnit,
sellAmountIncludingProtocolFeesCryptoBaseUnit,
feeData: {
protocolFees: {},
networkFeeCryptoBaseUnit: swap.networkFeeCryptoBaseUnit,
},
source: SwapperName.ArbitrumBridge,
},
] as SingleHopTradeRateSteps,
direction: isDeposit ? ('deposit' as const) : ('withdrawal' as const),
})
} catch (err) {
return Err(
makeSwapErrorRight({
message: '[ArbitrumBridge: tradeQuote] - failed to get fee data',
cause: err,
code: TradeQuoteError.NetworkFeeEstimationFailed,
}),
)
}
}
15 changes: 15 additions & 0 deletions packages/swapper/src/swappers/ArbitrumBridgeSwapper/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
import type { HDWallet } from '@shapeshiftoss/hdwallet-core'

import type { GetEvmTradeQuoteInputBase, TradeQuote, TradeRate } from '../../types'

export enum BRIDGE_TYPE {
ETH_DEPOSIT = 'ETH Deposit',
ERC20_DEPOSIT = 'ERC20 Deposit',
ETH_WITHDRAWAL = 'ETH Withdrawal',
ERC20_WITHDRAWAL = 'ERC20 Withdrawal',
}

export type GetEvmTradeQuoteInputWithWallet = Omit<GetEvmTradeQuoteInputBase, 'supportsEIP1559'> & {
wallet: HDWallet
}

type ArbitrumBridgeSpecificMetadata = {
direction: 'deposit' | 'withdrawal'
}

export type ArbitrumBridgeTradeQuote = TradeQuote & ArbitrumBridgeSpecificMetadata
export type ArbitrumBridgeTradeRate = TradeRate & ArbitrumBridgeSpecificMetadata
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import type {
import { isExecutableTradeQuote, isExecutableTradeStep, isToken } from '../../utils'
import { CHAINFLIP_BAAS_COMMISSION } from './constants'
import type { ChainflipBaasSwapDepositAddress } from './models/ChainflipBaasSwapDepositAddress'
import { getTradeQuote, getTradeRate } from './swapperApi/getTradeQuote'
import { getTradeQuote } from './swapperApi/getTradeQuote'
import { getTradeRate } from './swapperApi/getTradeRate'
import type { ChainFlipStatus } from './types'
import { chainflipService } from './utils/chainflipService'
import { getLatestChainflipStatusMessage } from './utils/getLatestChainflipStatusMessage'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ import { v4 as uuid } from 'uuid'
import { getDefaultSlippageDecimalPercentageForSwapper } from '../../../constants'
import type {
CommonTradeQuoteInput,
GetTradeRateInput,
GetUtxoTradeQuoteInput,
SwapErrorRight,
SwapperDeps,
TradeQuote,
TradeRate,
} from '../../../types'
import {
type GetEvmTradeQuoteInput,
Expand All @@ -40,7 +38,7 @@ import { getEvmTxFees } from '../utils/getEvmTxFees'
import { getUtxoTxFees } from '../utils/getUtxoTxFees'
import { getChainFlipIdFromAssetId, isSupportedAssetId, isSupportedChainId } from '../utils/helpers'

const _getTradeQuote = async (
export const _getTradeQuote = async (
input: CommonTradeQuoteInput,
deps: SwapperDeps,
): Promise<Result<TradeQuote[], SwapErrorRight>> => {
Expand Down Expand Up @@ -343,16 +341,6 @@ const _getTradeQuote = async (
return Ok(quotes)
}

// This isn't a mistake. A trade rate *is* a trade quote. Chainflip doesn't really have a notion of a trade quote,
// they do have a notion of a "swap" (which we effectively only use to get the deposit address), which is irrelevant to the notion of quote vs. rate
export const getTradeRate = async (
input: GetTradeRateInput,
deps: SwapperDeps,
): Promise<Result<TradeRate[], SwapErrorRight>> => {
const rates = await _getTradeQuote(input as unknown as CommonTradeQuoteInput, deps)
return rates as Result<TradeRate[], SwapErrorRight>
}

export const getTradeQuote = async (
input: CommonTradeQuoteInput,
deps: SwapperDeps,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Result } from '@sniptt/monads'

import type {
CommonTradeQuoteInput,
GetTradeRateInput,
SwapErrorRight,
SwapperDeps,
TradeRate,
} from '../../../types'
import { _getTradeQuote } from './getTradeQuote'

// This isn't a mistake. A trade rate *is* a trade quote. Chainflip doesn't really have a notion of a trade quote,
// they do have a notion of a "swap" (which we effectively only use to get the deposit address), which is irrelevant to the notion of quote vs. rate
export const getTradeRate = async (
input: GetTradeRateInput,
deps: SwapperDeps,
): Promise<Result<TradeRate[], SwapErrorRight>> => {
const rates = await _getTradeQuote(input as unknown as CommonTradeQuoteInput, deps)
return rates as Result<TradeRate[], SwapErrorRight>
}
Loading
Loading