diff --git a/README.md b/README.md index 16c21b4..c75b424 100644 --- a/README.md +++ b/README.md @@ -509,15 +509,12 @@ GET /shouldSwapAndRoute params: { poolId: string; // euphrates pool id recipient: string; // dest evm address - supplyAmount: string; // swap tokenIn amount - targetToken?: string; // swap tokenOut address, default: ACA address - targetAmount?: string; // swap tokenOut amount (with erc20 decimals) } ``` example ``` -GET /shouldSwapAndRoute?recipient=0x0085560b24769dAC4ed057F1B2ae40746AA9aAb6&supplyAmount=100000000&poolId=7&targetToken=0x0000000000000000000100000000000000000000&targetAmount=2000000000000 +GET /shouldSwapAndRoute?recipient=0x0085560b24769dAC4ed057F1B2ae40746AA9aAb6&poolId=7 => { "data": { @@ -534,10 +531,7 @@ POST /swapAndRoute data: { poolId: string; // euphrates pool id recipient: string; // dest evm address - supplyAmount: string; // swap tokenIn amount token?: string; // token to route, not required for `shouldRoute` - targetToken?: string; // swap tokenOut address, default: ACA address - targetAmount?: string; // swap tokenOut amount (with erc20 decimals) } ``` @@ -545,11 +539,8 @@ example ``` POST /swapAndRoute data: { - "recipient": "0x0085560b24769dAC4ed057F1B2ae40746AA9aAb6", - "supplyAmount": 100000000, "poolId": 7, - "targetToken": "0x0000000000000000000100000000000000000000", - "targetAmount": 2000000000000, + "recipient": "0x0085560b24769dAC4ed057F1B2ae40746AA9aAb6", "token": "0xa7fb00459f5896c3bd4df97870b44e868ae663d7" } diff --git a/src/api/swapAndRoute.ts b/src/api/swapAndRoute.ts index 6ddf5cc..a080516 100644 --- a/src/api/swapAndRoute.ts +++ b/src/api/swapAndRoute.ts @@ -3,7 +3,7 @@ import { ERC20__factory } from '@certusone/wormhole-sdk/lib/cjs/ethers-contracts import { SwapAndStakeEuphratesFactory__factory } from '@acala-network/asset-router/dist/typechain-types'; import { constants } from 'ethers'; -import { EUPHRATES_ADDR, EUPHRATES_POOLS, RELAYER_ADDR } from '../consts'; +import { EUPHRATES_ADDR, EUPHRATES_POOLS, RELAYER_ADDR, SWAP_SUPPLY_TOKENS } from '../consts'; import { Mainnet, RouteError, @@ -13,11 +13,16 @@ import { getChainConfig, getMainnetChainId, } from '../utils'; +import { parseUnits } from 'ethers/lib/utils'; +const TARGET_AMOUNT_ACA = parseUnits('3', 12); +const SUPPLY_AMOUNT_JITOSOL = parseUnits('0.0035', 9); const DEFAULT_SWAP_AND_ROUTE_PARAMS = { maker: RELAYER_ADDR, targetToken: ACA, euphrates: EUPHRATES_ADDR, + targetAmount: TARGET_AMOUNT_ACA, + supplyAmount: SUPPLY_AMOUNT_JITOSOL, }; const prepareSwapAndRoute = async (chain: Mainnet) => { @@ -34,30 +39,29 @@ const prepareSwapAndRoute = async (chain: Mainnet) => { export const shouldSwapAndRoute = async (params: SwapAndRouteParams) => { try { const { factory, feeAddr } = await prepareSwapAndRoute(Mainnet.Acala); + if (!EUPHRATES_POOLS.includes(params.poolId)) { throw new RouteError(`euphrates poolId ${params.poolId} is not supported`, params); } const insts = { ...DEFAULT_SWAP_AND_ROUTE_PARAMS, - ...params, + recipient: params.recipient, + poolId: params.poolId, }; /* ---------- TODO: remove this check later after approved max ---------- */ - const { targetAmount } = params; - if (targetAmount) { - const aca = ERC20__factory.connect(ACA, factory.signer); - const allowance = await aca.allowance(insts.maker, factory.address); - if (allowance.lt(targetAmount)) { - await (await aca.approve(factory.address, constants.MaxUint256)).wait(); - } + const aca = ERC20__factory.connect(ACA, factory.signer); + const allowance = await aca.allowance(insts.maker, factory.address); + if (allowance.lt(TARGET_AMOUNT_ACA)) { + await (await aca.approve(factory.address, constants.MaxUint256)).wait(); } /* ----------------------------------------------------------------------- */ const routerAddr = await factory.callStatic.deploySwapAndStakeEuphratesRouter( feeAddr, insts, - params.targetAmount ?? 0, + TARGET_AMOUNT_ACA ); return { @@ -77,9 +81,14 @@ export const swapAndRoute = async (params: SwapAndRouteParams) => { throw new RouteError(' param is required for swap and route', params); } + if (!SWAP_SUPPLY_TOKENS.includes(params.token)) { + throw new RouteError(`token ${params.token} is not supported for swapping`, params); + } + const insts = { ...DEFAULT_SWAP_AND_ROUTE_PARAMS, - ...params, + recipient: params.recipient, + poolId: params.poolId, }; const { factory, feeAddr } = await prepareSwapAndRoute(Mainnet.Acala); @@ -87,7 +96,7 @@ export const swapAndRoute = async (params: SwapAndRouteParams) => { feeAddr, insts, params.token, - params.targetAmount ?? 0, + TARGET_AMOUNT_ACA, ); const receipt = await tx.wait(); diff --git a/src/consts.ts b/src/consts.ts index 9548c0f..23a6c2a 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -252,6 +252,9 @@ export const TESTNET_MODE_WARNING = ` export const EUPHRATES_ADDR = '0x7Fe92EC600F15cD25253b421bc151c51b0276b7D'; export const EUPHRATES_POOLS = ['0', '1', '2', '3', '7']; +export const SWAP_SUPPLY_TOKENS = [ + '0xa7fb00459f5896c3bd4df97870b44e868ae663d7', +]; export const RELAYER_ADDR = '0x8B5C2F71eFa2d88A20E0e1c8EDFeA3767B2ab230'; diff --git a/src/middlewares/router.ts b/src/middlewares/router.ts index bd62894..54ffbd9 100644 --- a/src/middlewares/router.ts +++ b/src/middlewares/router.ts @@ -1,6 +1,17 @@ import { NextFunction, Request, Response } from 'express'; import { Schema } from 'yup'; +import { + NoRouteError, + logger, + relayAndRouteSchema, + routeEuphratesSchema, + routeHomaSchema, + routeStatusSchema, + routeWormholeSchema, + routeXcmSchema, + swapAndRouteSchema, +} from '../utils'; import { getAllRouteStatus, getRouteStatus, @@ -17,17 +28,6 @@ import { shouldRouteWormhole, shouldRouteXcm, } from '../api'; -import { - relayAndRouteSchema, - routeEuphratesSchema, - routeHomaSchema, - routeWormholeSchema, - routeXcmSchema, - logger, - NoRouteError, - routeStatusSchema, - swapAndRouteSchema, -} from '../utils'; import { shouldSwapAndRoute, swapAndRoute } from '../api/swapAndRoute'; interface RouterConfig { diff --git a/src/utils/validate.ts b/src/utils/validate.ts index 4b8c1d4..f22adcd 100644 --- a/src/utils/validate.ts +++ b/src/utils/validate.ts @@ -39,14 +39,8 @@ export interface RouteParamsEuphrates { token?: string; // token to route, not required for `shouldRoute` } -export interface SwapAndRouteParams { - poolId: string; // euphrates pool id - recipient: string; // dest evm address - supplyAmount: string; // swap tokenIn amount - token?: string; // token to route, not required for `shouldRoute` - targetToken?: string; // swap tokenOut address, default: ACA address - targetAmount?: string; // swap tokenOut amount (with erc20 decimals) -} +// does not support general swap yet +export type SwapAndRouteParams = RouteParamsEuphrates; export interface RelayAndRouteParams extends RouteParamsXcm { signedVAA: string; @@ -91,14 +85,7 @@ export const routeEuphratesSchema: ObjectSchema = object({ token: string(), }); -export const swapAndRouteSchema: ObjectSchema = object({ - poolId: string().required(), - recipient: string().required(), - supplyAmount: string().required(), - token: string(), - targetToken: string(), - targetAmount: string(), -}); +export const swapAndRouteSchema = routeEuphratesSchema; export const routeStatusSchema: ObjectSchema = object({ id: string(),