Skip to content

Commit

Permalink
1181 Chainflip (#1182)
Browse files Browse the repository at this point in the history
* Chainflip V1

* Docs

* TODO

* Tests

* Bug fix

* ERC20 swap e2e test

* test bug fix

* Tests bug fix

* Changeset version file
  • Loading branch information
0xp3gasus authored Jun 2, 2024
1 parent 9d4c162 commit 45e9238
Show file tree
Hide file tree
Showing 13 changed files with 1,099 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/lucky-candles-serve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@xchainjs/xchain-aggregator': minor
---

Chainflip protocol support
38 changes: 36 additions & 2 deletions packages/xchain-aggregator/__e2e__/aggregator.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import {
defaultBTCParams as defaultBtcParams,
} from '@xchainjs/xchain-bitcoin'
import { Network } from '@xchainjs/xchain-client'
import { AssetETH } from '@xchainjs/xchain-ethereum'
import { AssetETH, Client as EthClient, defaultEthParams } from '@xchainjs/xchain-ethereum'
import { AssetKUJI } from '@xchainjs/xchain-kujira'
import { CryptoAmount, assetAmount, assetToBase, assetToString } from '@xchainjs/xchain-util'
import { CryptoAmount, assetAmount, assetFromStringEx, assetToBase, assetToString } from '@xchainjs/xchain-util'
import { Wallet } from '@xchainjs/xchain-wallet'

import { Aggregator, QuoteSwap } from '../src'
Expand Down Expand Up @@ -50,6 +50,8 @@ function printQuoteSwap(quoteSwap: QuoteSwap) {
})
}

jest.deepUnmock('@chainflip/sdk/swap')

describe('Aggregator', () => {
let aggregator: Aggregator
let wallet: Wallet
Expand All @@ -58,6 +60,11 @@ describe('Aggregator', () => {
const phrase = process.env.PHRASE_MAINNET
wallet = new Wallet({
BTC: new BtcClient({ ...defaultBtcParams, phrase, network: Network.Mainnet }),
ETH: new EthClient({
...defaultEthParams,
phrase,
network: Network.Mainnet,
}),
AVAX: new AvaxClient({ ...defaultAvaxParams, phrase, network: Network.Mainnet }),
BNB: new BnbClient({ phrase, network: Network.Mainnet }),
})
Expand Down Expand Up @@ -117,6 +124,33 @@ describe('Aggregator', () => {
console.log(txSubmitted)
})

it('Should do ERC20 swap using chosen protocol', async () => {
const txEstimatedSwap = await aggregator.estimateSwap({
fromAsset: assetFromStringEx('ETH.USDT-0xdAC17F958D2ee523a2206206994597C13D831ec7'),
destinationAsset: AssetETH,
amount: new CryptoAmount(
assetToBase(assetAmount(20, 6)),
assetFromStringEx('ETH.USDT-0xdAC17F958D2ee523a2206206994597C13D831ec7'),
),
destinationAddress: await wallet.getAddress(AssetETH.chain),
})

printQuoteSwap(txEstimatedSwap)

const txSubmitted = await aggregator.doSwap({
protocol: txEstimatedSwap.protocol,
fromAsset: assetFromStringEx('ETH.USDT-0xdAC17F958D2ee523a2206206994597C13D831ec7'),
destinationAsset: AssetETH,
amount: new CryptoAmount(
assetToBase(assetAmount(20, 6)),
assetFromStringEx('ETH.USDT-0xdAC17F958D2ee523a2206206994597C13D831ec7'),
),
destinationAddress: await wallet.getAddress(AssetETH.chain),
})

console.log(txSubmitted)
})

it('Should do swap without selecting protocol', async () => {
const txSubmitted = await aggregator.doSwap({
fromAsset: AssetBNB,
Expand Down
322 changes: 322 additions & 0 deletions packages/xchain-aggregator/__mocks__/@chainflip/sdk/swap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,322 @@
import {
Asset,
AssetData,
ChainData,
Chains,
DepositAddressRequest,
DepositAddressResponse,
QuoteRequest,
QuoteResponse,
} from '@chainflip/sdk/swap'

class SwapSDK {
async getChains(): Promise<ChainData[]> {
return [
{
chain: 'Ethereum',
name: 'Ethereum',
evmChainId: 11155111,
isMainnet: false,
requiredBlockConfirmations: 7,
},
{
chain: 'Polkadot',
name: 'Polkadot',
evmChainId: undefined,
isMainnet: false,
requiredBlockConfirmations: undefined,
},
{
chain: 'Bitcoin',
name: 'Bitcoin',
evmChainId: undefined,
isMainnet: false,
requiredBlockConfirmations: 6,
},
]
}

async getAssets(): Promise<AssetData[]> {
return [
{
chainflipId: 'Eth',
asset: 'ETH',
chain: 'Ethereum',
contractAddress: undefined,
decimals: 18,
name: 'Ether',
symbol: 'ETH',
isMainnet: true,
minimumSwapAmount: '10000000000000000',
maximumSwapAmount: null,
minimumEgressAmount: '1',
},
{
chainflipId: 'Flip',
asset: 'FLIP',
chain: 'Ethereum',
contractAddress: '0x826180541412D574cf1336d22c0C0a287822678A',
decimals: 18,
name: 'FLIP',
symbol: 'FLIP',
isMainnet: true,
minimumSwapAmount: '4000000000000000000',
maximumSwapAmount: null,
minimumEgressAmount: '1',
},
{
chainflipId: 'Usdc',
asset: 'USDC',
chain: 'Ethereum',
contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
decimals: 6,
name: 'USDC',
symbol: 'USDC',
isMainnet: true,
minimumSwapAmount: '20000000',
maximumSwapAmount: null,
minimumEgressAmount: '1',
},
{
chainflipId: 'Usdt',
asset: 'USDT',
chain: 'Ethereum',
contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
decimals: 6,
name: 'USDT',
symbol: 'USDT',
isMainnet: true,
minimumSwapAmount: '20000000',
maximumSwapAmount: null,
minimumEgressAmount: '1',
},
{
chainflipId: 'Dot',
asset: 'DOT',
chain: 'Polkadot',
contractAddress: undefined,
decimals: 10,
name: 'Polkadot',
symbol: 'DOT',
isMainnet: true,
minimumSwapAmount: '40000000000',
maximumSwapAmount: null,
minimumEgressAmount: '1',
},
{
chainflipId: 'Btc',
asset: 'BTC',
chain: 'Bitcoin',
contractAddress: undefined,
decimals: 8,
name: 'Bitcoin',
symbol: 'BTC',
isMainnet: true,
minimumSwapAmount: '70000',
maximumSwapAmount: null,
minimumEgressAmount: '600',
},
]
}

async requestDepositAddress(params: DepositAddressRequest): Promise<DepositAddressResponse> {
if (params.srcChain === 'Bitcoin')
return {
...params,
depositAddress: 'BITCOINfakeaddress',
depositChannelId: 'bitcoin-channel-id',
brokerCommissionBps: 0,
depositChannelExpiryBlock: BigInt(10000),
estimatedDepositChannelExpiryTime: 1716889354,
channelOpeningFee: BigInt(100),
}
if (params.srcChain === 'Ethereum' || params.srcChain === 'Arbitrum')
return {
...params,
depositAddress: 'ETHEREUMfakeaddress',
depositChannelId: 'ethereum-channel-id',
brokerCommissionBps: 0,
depositChannelExpiryBlock: BigInt(20000),
estimatedDepositChannelExpiryTime: 1716889354,
channelOpeningFee: BigInt(100),
}
if (params.srcChain === 'Polkadot')
return {
...params,
depositAddress: 'POLKADOTfakeaddress',
depositChannelId: 'polkadot-channel-id',
brokerCommissionBps: 0,
depositChannelExpiryBlock: BigInt(30000),
estimatedDepositChannelExpiryTime: 1716889354,
channelOpeningFee: BigInt(100),
}
throw Error('Can not get deposit address')
}

async getQuote({ srcAsset, srcChain, destAsset, destChain, amount }: QuoteRequest): Promise<QuoteResponse> {
if (
srcChain === 'Ethereum' &&
srcAsset === 'ETH' &&
destChain === 'Bitcoin' &&
destAsset === 'BTC' &&
amount === '10000000000000000'
) {
return {
srcAsset,
srcChain,
destAsset,
destChain,
amount,
quote: {
intermediateAmount: '36115119',
egressAmount: '51193',
includedFees: [
{
type: 'INGRESS',
chain: 'Ethereum',
asset: 'ETH',
amount: '689176257450000',
},
{
type: 'NETWORK',
chain: 'Ethereum',
asset: 'USDC',
amount: '36115',
},
{
type: 'LIQUIDITY',
chain: 'Ethereum',
asset: 'ETH',
amount: '4655411871275',
},
{
type: 'LIQUIDITY',
chain: 'Ethereum',
asset: 'USDC',
amount: '18057',
},
{
type: 'EGRESS',
chain: 'Bitcoin',
asset: 'BTC',
amount: '1599',
},
],
lowLiquidityWarning: false,
estimatedDurationSeconds: 702,
},
}
}

if (
srcChain === 'Ethereum' &&
srcAsset === 'USDT' &&
destChain === 'Ethereum' &&
destAsset === 'ETH' &&
amount === '20000000'
) {
return {
srcAsset,
srcChain,
destAsset,
destChain,
amount,
quote: {
intermediateAmount: '13560635',
egressAmount: '2063188201000691',
includedFees: [
{
type: 'INGRESS',
chain: 'Ethereum',
asset: 'USDT',
amount: '6433935',
},
{
type: 'NETWORK',
chain: 'Ethereum',
asset: 'USDC',
amount: '13560',
},
{
type: 'LIQUIDITY',
chain: 'Ethereum',
asset: 'USDT',
amount: '6783',
},
{
type: 'LIQUIDITY',
chain: 'Ethereum',
asset: 'USDC',
amount: '6780',
},
{
type: 'EGRESS',
chain: 'Ethereum',
asset: 'ETH',
amount: '1447621978320000',
},
],
lowLiquidityWarning: false,
estimatedDurationSeconds: 114,
},
}
}

if (
srcChain === 'Ethereum' &&
srcAsset === 'ETH' &&
destChain === 'Ethereum' &&
destAsset === 'USDT' &&
amount === '10000000000000000'
) {
return {
srcAsset,
srcChain,
destAsset,
destChain,
amount,
quote: {
intermediateAmount: '33919877',
egressAmount: '24884030',
includedFees: [
{
type: 'INGRESS',
chain: 'Ethereum',
asset: 'ETH',
amount: '1284811335100000',
},
{
type: 'NETWORK',
chain: 'Ethereum',
asset: 'USDC',
amount: '33919',
},
{
type: 'LIQUIDITY',
chain: 'Ethereum',
asset: 'ETH',
amount: '4357594332450',
},
{
type: 'LIQUIDITY',
chain: 'Ethereum',
asset: 'USDC',
amount: '16959',
},
{
type: 'EGRESS',
chain: 'Ethereum',
asset: 'USDT',
amount: '8988369',
},
],
lowLiquidityWarning: false,
estimatedDurationSeconds: 114,
},
}
}
throw Error('Quote not mocked')
}
}

export { SwapSDK, Asset, AssetData, Chains }
Loading

0 comments on commit 45e9238

Please sign in to comment.