From 2d4566db86e9aaa463bc237bc6b7a2678265baf5 Mon Sep 17 00:00:00 2001 From: Pere Palou Date: Thu, 27 Jun 2024 10:08:38 +0200 Subject: [PATCH 1/4] Implemented new solver to add Unizen as new aggregator --- package.json | 1 + src/Unizen/index.ts | 217 +++++++++++++++++++++++++++++++ src/Unizen/types.ts | 169 ++++++++++++++++++++++++ src/index.ts | 2 + src/types.ts | 1 + test/unit/swapper.client.test.ts | 13 +- 6 files changed, 401 insertions(+), 2 deletions(-) create mode 100644 src/Unizen/index.ts create mode 100644 src/Unizen/types.ts diff --git a/package.json b/package.json index 52507d1..88a3406 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ }, "peerDependencies": {}, "dependencies": { + "@ethersproject/experimental": "^5.7.0", "@types/qs": "^6.9.9", "dotenv": "^16.3.1", "qs": "^6.11.2" diff --git a/src/Unizen/index.ts b/src/Unizen/index.ts new file mode 100644 index 0000000..f70feac --- /dev/null +++ b/src/Unizen/index.ts @@ -0,0 +1,217 @@ +import qs from "qs"; + +import { + addEstimatesToTransactionRequest +} from "../"; + +import { + ISwapperParams, + validateQuoteParams, + ITransactionRequestWithEstimate, +} from "../types"; + +// UNIZEN speicifc types +import { + ICrossQuoteResult, + IQuoteParams, + IQuoteResult, + TransactionData, + SwapData, + CrossChainTransactionData +} from './types' + +// curl https://api.zcx.com/trade/v1/info/chains +export const networkById: { [chainId: number]: string } = { + 1: "ethereum", + 10: "optimism", + 56: "bsc", + 137: "polygon", + 250: "fantom", + 8453: "base", + 42161: "arbitrum", + 43114: "avax", +}; + +export const routerV1ByChainId: { [id: string]: string } = { + "ethereum" : "0xd3f64BAa732061F8B3626ee44bab354f854877AC", + "bsc": "0x880E0cE34F48c0cbC68BF3E745F17175BA8c650e", + "polygon": "0x07d0ac7671D4242858D0cebcd34ec03907685947", + "avax": "0x1C7F7e0258c81CF41bcEa31ea4bB5191914Bf7D7", + "fantom": "0xBE2A77399Cde40EfbBc4e89207332c4a4079c83D", + "arbitrum": "0x1C7F7e0258c81CF41bcEa31ea4bB5191914Bf7D7", + "optimism": "0xad1D43efCF92133A9a0f33e5936F5ca10f2b012E", + "base": "0x4F68248ecB782647D1E5981a181bBe1bfFee1040" +}; + +export const routerV2ByChainId: { [id: string]: string } = { + "ethereum": "0xf140bE1825520F773Ff0F469786FCA65c876885f", + "bsc": "0x12067e4473a1f00e58fa24e38e2cf3e53e21a33d", + "polygon": "0x85f8fb7ac814d0a6a0b16bc207df5bbc631f1ca6", + "avax": "0x468ae09BD4c8B4D9f7601e37B6c061776FeCFE3B", + "fantom": "0xD38559966E53B651794aD4df6DDc190d2235180E", + "arbitrum": "0x9660b95fcDBA4B0f5917C47b703179E03a28bf27", + "optimism": "0x3ce6e87922e62fc279152c841102eb2bf5497010" +}; + +export const routerV3ByChainId: { [id: string]: string } = { + "ethereum": "0xCf2DBA4e5C9f1B47AC09dc712A0F7bD8eE31A15d", + "bsc": "0xa9c430de6a91132330A09BE41f9f19bf45702f74", + "polygon": "0xCf2DBA4e5C9f1B47AC09dc712A0F7bD8eE31A15d", + "avax": "0xa9c430de6a91132330A09BE41f9f19bf45702f74", + "arbitrum": "0xa9c430de6a91132330A09BE41f9f19bf45702f74", + "optimism": "0xa9c430de6a91132330A09BE41f9f19bf45702f74", + "base": "0xa9c430de6a91132330A09BE41f9f19bf45702f74" +}; + +const apiRoot = "http://api.zcx.com/trade/v1"; +const apiKey = process.env?.UNIZEN_API_KEY; + +const getExcludedDexesList = (o: ISwapperParams): Map => { + let res = new Map(); + if (o.denyExchanges?.length){ + res.set(String(o.inputChainId), o.denyExchanges?.concat(o.denyBridges ?? [])); + if (o.outputChainId != undefined){ + res.set(String(o.outputChainId), o.denyExchanges?.concat(o.denyBridges ?? [])) + } + } + return res; +} + +const getTargetAddress = (version: string, chainId: number) : string => { + switch(version){ + case "v1": + return routerV1ByChainId[networkById[chainId]] + case "v2": + return routerV2ByChainId[networkById[chainId]] + case "v3": + return routerV3ByChainId[networkById[chainId]] + } + return ""; +} + +export const convertQuoteParams = (o: ISwapperParams): IQuoteParams => ({ + fromTokenAddress: o.input, + chainId: String(o.inputChainId), + toTokenAddress: o.output, + destinationChainId: o.outputChainId != undefined ? String(o.outputChainId) : undefined, + amount: String(o.amountWei), + sender: o.payer, + receiver: o.receiver ?? undefined, + slippage: o.maxSlippage, + deadline: o.deadline, + isSplit: false, + excludedDexes: getExcludedDexesList(o), +}); + + + +export async function getTransactionRequest(o: ISwapperParams): Promise { + const isCrossSwap = o.outputChainId != undefined; + const quotes = isCrossSwap ? await getCrossChainQuote(o) : await getSingleChainQuote(o); + if (!quotes?.length) return; + const bestQuote = quotes[0]; + const tradeType = isCrossSwap ? undefined : (bestQuote as IQuoteResult).tradeType; + const swapData = await getSwapData(o.inputChainId, bestQuote.transactionData, bestQuote.nativeValue, o.payer, o.receiver ?? o.payer, tradeType); + const tr = { + from: o.payer, + to: getTargetAddress(swapData!.contractVersion, o.inputChainId), + value: o.amountWei, + data: swapData?.data, + gasLimit: Number(BigInt(swapData!.estimateGas)) * 2 + } as ITransactionRequestWithEstimate; + + const toTokenAmount = isCrossSwap ? (bestQuote as ICrossQuoteResult).dstTrade.toTokenAmount : (bestQuote as IQuoteResult).toTokenAmount; + const tokenFromDecimals = isCrossSwap ? (bestQuote as ICrossQuoteResult).tradeParams.tokenInfo[0].decimals : (bestQuote as IQuoteResult).tokenFrom.decimals; + const tokenToDecimals = isCrossSwap ? (bestQuote as ICrossQuoteResult).tradeParams.tokenInfo[1].decimals : (bestQuote as IQuoteResult).tokenTo.decimals; + + return addEstimatesToTransactionRequest({ + tr, + inputAmountWei: BigInt(o.amountWei as string), + outputAmountWei: BigInt(toTokenAmount), + inputDecimals: tokenFromDecimals, + outputDecimals: tokenToDecimals, + approvalAddress: o.payer ?? '', + totalGasUsd: 0, + totalGasWei: swapData!.estimateGas + }); +} + +// cf. https://api.zcx.com/trade/docs#/Single%20chain%20methods/QuoteSingleController_getSingleQuote +// Get a quote for your desired transfer. +export async function getSingleChainQuote(o: ISwapperParams): Promise { + if (!apiKey) console.warn("missing env.UNIZEN_API_KEY, using public"); + if (!validateQuoteParams(o)) throw new Error("invalid input"); + const params = convertQuoteParams(o); + const url = `${apiRoot}/${params.chainId}/quote/single?${qs.stringify(params, { skipNulls: true})}`; + try { + const res = await fetch(url, { + headers: apiKey ? { "x-api-key": apiKey } : {}, + }); + if (res.status >= 400) + throw new Error(`${res.status}: ${res.statusText} - ${await res.text?.() ?? '?'}`); + return await res.json(); + } catch (e) { + console.error(`getSingleChainQuote failed: ${e}`); + } +} + +// cf. https://api.zcx.com/trade/docs#/Cross%20chain%20methods/QuoteCrossController_getCrossQuote +// Get a quote for your desired transfer. +export async function getCrossChainQuote(o: ISwapperParams): Promise { + if (!apiKey) console.warn("missing env.UNIZEN_API_KEY, using public"); + if (!validateQuoteParams(o)) throw new Error("invalid input"); + const params = convertQuoteParams(o); + const quoteType = params.destinationChainId != undefined ? "cross": "single"; + const url = `${apiRoot}/${params.chainId}/quote/cross?${qs.stringify(params, { skipNulls: true})}`; + try { + const res = await fetch(url, { + headers: apiKey ? { "x-api-key": apiKey } : {}, + }); + if (res.status >= 400) + throw new Error(`${res.status}: ${res.statusText} - ${await res.text?.() ?? '?'}`); + return await res.json(); + } catch (e) { + console.error(`getCrossChainQuote failed: ${e}`); + } +} + +// cf. https://api.zcx.com/trade/docs#/Single%20chain%20methods/SwapSingleController_getSingleSwap +// Generate trade data for an on-chain swap. +export async function getSwapData(chainId: number, transactionData: TransactionData | CrossChainTransactionData, nativeValue: string, account: string, receiver: string, tradeType?: number): Promise { + if (!apiKey) console.warn("missing env.UNIZEN_API_KEY, using public"); + const swapType = tradeType != undefined ? "single": "cross"; + const url = `${apiRoot}/${chainId}/swap/${swapType}`; + const body = tradeType != undefined + ? { + transactionData : transactionData, + nativeValue: nativeValue, + account: account, + receiver: receiver, + tradeType: tradeType + } + : { + transactionData : transactionData, + nativeValue: nativeValue, + account: account, + receiver: receiver + } ; + try { + const res = await fetch(url, { + method: "POST", + body: JSON.stringify(body), + headers: apiKey ? + { + "x-api-key": apiKey, + "Content-Type": "application/json" + } : + { + "Content-Type": "application/json" + }, + }); + if (res.status >= 400) + throw new Error(`${res.status}: ${res.statusText} - ${await res.text?.() ?? '?'}`); + return await res.json(); + } catch (e) { + console.error(`getSwapData failed: ${e}`); + } +} diff --git a/src/Unizen/types.ts b/src/Unizen/types.ts new file mode 100644 index 0000000..56d48b2 --- /dev/null +++ b/src/Unizen/types.ts @@ -0,0 +1,169 @@ +export interface IQuoteParams { + fromTokenAddress: string; + chainId: string; + toTokenAddress: string; + destinationChainId?: string; + amount: string; + sender: string; + receiver?: string; + deadline?: number; + slippage?: number; + excludedDexes?: Map; + priceImpactProtectionPercentage?: number; + isSplit?: boolean; + disableEstimate?: boolean; +} + +export interface IToken { + name: string; + symbol: string; + decimals: number; + contractAddress: string; + chainId: number; + buyTax: number; + sellTax: number; +} + +export interface IQuoteResult { + fromTokenAmount: string; + toTokenAmount: string; + deltaAmount: string; + tokenFrom: IToken; + tokenTo: IToken; + tradeType: number; + protocol: QuoteProtocol[]; + transactionData: TransactionData; + nativeValue: string; + contractVersion: string; + gasPrice: string; + estimateGas: string; + estimateGasError?: string; +} + +export interface ICrossQuoteResult { + srcTrade: IQuoteResult; + dstTrade: IQuoteResult; + transactionData: CrossChainTransactionData; + nativeValue: string; + nativeFee: string; + processingTime: number; + tradeProtocol: string; + crossChainTradeQuotesType: string; + sourceChainId: number; + destinationChainId: number, + uuid:string; + apiKeyUuid: string; + contractVersion: string; + tradeParams: TradeParams; + providerInfo: ProviderInfo; +} + +export type QuoteProtocol = { + name: string; + logo: string; + route: string[]; + percentage: number; +} + +export type TransactionData = { + info: TransactionDataInfo; + call: TransactionDataCall[]; +} + +export type TransactionDataInfo = { + srcToken: string; + dstToken: string; + deadline: number; + slippage: number; + tokenHasTaxes: boolean; + path: string[]; + tradeType: number; + amountIn: string; + amountOutMin: string; + actualQuote: string; + uuid: string; + apiId: string; + userPSFee: number; +} + +export type CrossChainTransactionData = { + srcCalls: TransactionDataCall[]; + dstCalls: TransactionDataCall[]; + params: CrossChainTransactionDataParams; + nativeFee: string; + tradeProtocol: string; +} + +export type CrossChainTransactionDataParams = { + dstChain: number; + srcPool: number; + dstPool: number; + isFromNative: boolean; + srcToken: string; + amount: string; + nativeFee: string; + gasDstChain: number; + receiver: string; + dstToken: string; + actualQuote: string; + minQuote: string; + uuid: string; + userPSFee: number; + apiId: string; + tradeType: number; +} + +export type TransactionDataCall = { + targetExchange: string; + sellToken: string; + buyToken: string; + amountDelta: string; + amount: string; + data: string; +} + +export type ProviderInfo = { + name: string; + logo: string; + contractVersion: string; + website: string; + docsLink: string; + description: string; +} + +export type TradeParams = { + tokenIn: string; + tokenOut: string; + sender: string; + slippage: number; + srcChainId: number; + dstChainId: number; + receiver: string; + inNative: boolean; + outNative: boolean; + deadline: number; + tokenInfo: IToken[]; + amount: string; + uuid: string; + userPSFee: number; + uuidPercentage: number; + excludeeDexList: any; + chainIdToCurve: any; + srcChainTokenHasTaxes: boolean; + dstChainTokenHasTaxes: boolean; +} + +export type SwapData = { + data: string; + contractVersion: string; + estimateGas: string; + estimateGasError: string; + nativeValue: string; + insufficientFunds: boolean; + insufficientGas: boolean; + insufficientAllowance: boolean; + allowance: string; + gasPrice: string; + maxFeePerGas: string; + maxPriorityFeePerGas: string; +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index bd78244..766e629 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,7 @@ import * as KyberSwap from "./KyberSwap"; import * as Squid from "./Squid"; import * as LiFi from "./LiFi"; import * as Socket from "./Socket"; +import * as Unizen from "./Unizen"; import { Aggregator, @@ -24,6 +25,7 @@ export const aggregatorById: { [key: string]: Aggregator } = { [AggregatorId.KYBERSWAP]: KyberSwap, [AggregatorId.SQUID]: Squid, [AggregatorId.LIFI]: LiFi, + [AggregatorId.UNIZEN]: Unizen, // Socket disabled until we implement the getStatus method properly // [AggregatorId.SOCKET]: Socket, }; diff --git a/src/types.ts b/src/types.ts index 5743b0c..ea18620 100644 --- a/src/types.ts +++ b/src/types.ts @@ -35,6 +35,7 @@ export enum AggregatorId { ONE_INCH = "ONE_INCH", ZERO_X = "ZERO_X", PARASWAP = "PARASWAP", + UNIZEN = "UNIZEN" } export interface Stringifiable { diff --git a/test/unit/swapper.client.test.ts b/test/unit/swapper.client.test.ts index 5a00ac3..9b4d5c2 100644 --- a/test/unit/swapper.client.test.ts +++ b/test/unit/swapper.client.test.ts @@ -7,6 +7,7 @@ import { AggregatorId, ISwapperParams } from "../../src/types"; import { getTransactionRequestByAggregatorCases } from "../utils/cases"; import { getTransactionRequest as lifiTxRequest } from "../../src/LiFi"; import { getTransactionRequest as squidTxRequest } from "../../src/Squid"; +import { getTransactionRequest as unizenTxRequest } from "../../src/Unizen"; const swapperParams: ISwapperParams = { // op:usdc -> arb:dai @@ -15,7 +16,7 @@ const swapperParams: ISwapperParams = { outputChainId: 42161, output: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", amountWei: "1000000000", - payer: '0x489ee077994B6658eAfA855C308275EAd8097C4A', + payer: '0xC373f2C4efFD31626c79eFCd891aA7759cF61886', maxSlippage: 100, } @@ -28,7 +29,7 @@ describe("swapper.client.test", function () { console.log("beforeEach"); }); - describe("Get Quote", function () { + describe("Get Quote", function () { it("Squid", async function () { for (const tr of (await getTransactionRequestByAggregatorCases(AggregatorId.SQUID))) expect(tr?.data).to.be.a("string"); @@ -49,6 +50,10 @@ describe("swapper.client.test", function () { for (const tr of (await getTransactionRequestByAggregatorCases(AggregatorId.ZERO_X))) expect(tr?.data).to.be.a("string"); }); + it("Unizen", async function () { + for (const tr of (await getTransactionRequestByAggregatorCases(AggregatorId.UNIZEN))) + expect(tr?.data).to.be.a("string"); + }); }) }); @@ -63,5 +68,9 @@ describe("swapper.client.test.estimate", function () { const tr = await lifiTxRequest(swapperParams); expect(tr?.data).to.be.a("string"); }); + it("Unizen", async function () { + const tr = await unizenTxRequest(swapperParams); + expect(tr?.data).to.be.a("string"); + }); }) }); \ No newline at end of file From fbeb19fcd9dddf22057ee815c17c482ac064448c Mon Sep 17 00:00:00 2001 From: Pere Palou Date: Fri, 28 Jun 2024 10:59:56 +0200 Subject: [PATCH 2/4] Added Unizen as available Aggregator --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 766e629..2be61be 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,7 +31,7 @@ export const aggregatorById: { [key: string]: Aggregator } = { }; export const aggregatorsWithContractCalls = [AggregatorId.LIFI]; -export const aggregatorsAvailable = [AggregatorId.LIFI, AggregatorId.SQUID]; +export const aggregatorsAvailable = [AggregatorId.LIFI, AggregatorId.SQUID, AggregatorId.UNIZEN]; /** * Extracts the `callData` from the `transactionRequest` (if any). From e31e9a69cffb3d4c3cb78d04efca838aa851a29a Mon Sep 17 00:00:00 2001 From: Josep lluis Yuste Castell Date: Tue, 2 Jul 2024 22:54:23 +0200 Subject: [PATCH 3/4] fix: added package for addresses, code style --- package.json | 1 + src/Unizen/index.ts | 74 +++++++++++---------------------------------- 2 files changed, 19 insertions(+), 56 deletions(-) diff --git a/package.json b/package.json index 88a3406..00d72b3 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ "dependencies": { "@ethersproject/experimental": "^5.7.0", "@types/qs": "^6.9.9", + "@unizen-io/unizen-contract-addresses": "^0.0.14", "dotenv": "^16.3.1", "qs": "^6.11.2" } diff --git a/src/Unizen/index.ts b/src/Unizen/index.ts index f70feac..9e632da 100644 --- a/src/Unizen/index.ts +++ b/src/Unizen/index.ts @@ -1,5 +1,7 @@ import qs from "qs"; +import contractAddresses from "@unizen-io/unizen-contract-addresses/production.json"; + import { addEstimatesToTransactionRequest } from "../"; @@ -10,7 +12,7 @@ import { ITransactionRequestWithEstimate, } from "../types"; -// UNIZEN speicifc types +// UNIZEN specific types import { ICrossQuoteResult, IQuoteParams, @@ -32,37 +34,6 @@ export const networkById: { [chainId: number]: string } = { 43114: "avax", }; -export const routerV1ByChainId: { [id: string]: string } = { - "ethereum" : "0xd3f64BAa732061F8B3626ee44bab354f854877AC", - "bsc": "0x880E0cE34F48c0cbC68BF3E745F17175BA8c650e", - "polygon": "0x07d0ac7671D4242858D0cebcd34ec03907685947", - "avax": "0x1C7F7e0258c81CF41bcEa31ea4bB5191914Bf7D7", - "fantom": "0xBE2A77399Cde40EfbBc4e89207332c4a4079c83D", - "arbitrum": "0x1C7F7e0258c81CF41bcEa31ea4bB5191914Bf7D7", - "optimism": "0xad1D43efCF92133A9a0f33e5936F5ca10f2b012E", - "base": "0x4F68248ecB782647D1E5981a181bBe1bfFee1040" -}; - -export const routerV2ByChainId: { [id: string]: string } = { - "ethereum": "0xf140bE1825520F773Ff0F469786FCA65c876885f", - "bsc": "0x12067e4473a1f00e58fa24e38e2cf3e53e21a33d", - "polygon": "0x85f8fb7ac814d0a6a0b16bc207df5bbc631f1ca6", - "avax": "0x468ae09BD4c8B4D9f7601e37B6c061776FeCFE3B", - "fantom": "0xD38559966E53B651794aD4df6DDc190d2235180E", - "arbitrum": "0x9660b95fcDBA4B0f5917C47b703179E03a28bf27", - "optimism": "0x3ce6e87922e62fc279152c841102eb2bf5497010" -}; - -export const routerV3ByChainId: { [id: string]: string } = { - "ethereum": "0xCf2DBA4e5C9f1B47AC09dc712A0F7bD8eE31A15d", - "bsc": "0xa9c430de6a91132330A09BE41f9f19bf45702f74", - "polygon": "0xCf2DBA4e5C9f1B47AC09dc712A0F7bD8eE31A15d", - "avax": "0xa9c430de6a91132330A09BE41f9f19bf45702f74", - "arbitrum": "0xa9c430de6a91132330A09BE41f9f19bf45702f74", - "optimism": "0xa9c430de6a91132330A09BE41f9f19bf45702f74", - "base": "0xa9c430de6a91132330A09BE41f9f19bf45702f74" -}; - const apiRoot = "http://api.zcx.com/trade/v1"; const apiKey = process.env?.UNIZEN_API_KEY; @@ -70,7 +41,7 @@ const getExcludedDexesList = (o: ISwapperParams): Map => { let res = new Map(); if (o.denyExchanges?.length){ res.set(String(o.inputChainId), o.denyExchanges?.concat(o.denyBridges ?? [])); - if (o.outputChainId != undefined){ + if (o.outputChainId){ res.set(String(o.outputChainId), o.denyExchanges?.concat(o.denyBridges ?? [])) } } @@ -78,22 +49,14 @@ const getExcludedDexesList = (o: ISwapperParams): Map => { } const getTargetAddress = (version: string, chainId: number) : string => { - switch(version){ - case "v1": - return routerV1ByChainId[networkById[chainId]] - case "v2": - return routerV2ByChainId[networkById[chainId]] - case "v3": - return routerV3ByChainId[networkById[chainId]] - } - return ""; + return ((contractAddresses as any)[version] as any)[networkById[chainId]]; } export const convertQuoteParams = (o: ISwapperParams): IQuoteParams => ({ fromTokenAddress: o.input, chainId: String(o.inputChainId), toTokenAddress: o.output, - destinationChainId: o.outputChainId != undefined ? String(o.outputChainId) : undefined, + destinationChainId: o.outputChainId ? String(o.outputChainId) : undefined, amount: String(o.amountWei), sender: o.payer, receiver: o.receiver ?? undefined, @@ -106,7 +69,7 @@ export const convertQuoteParams = (o: ISwapperParams): IQuoteParams => ({ export async function getTransactionRequest(o: ISwapperParams): Promise { - const isCrossSwap = o.outputChainId != undefined; + const isCrossSwap = !!o.outputChainId; const quotes = isCrossSwap ? await getCrossChainQuote(o) : await getSingleChainQuote(o); if (!quotes?.length) return; const bestQuote = quotes[0]; @@ -161,7 +124,6 @@ export async function getCrossChainQuote(o: ISwapperParams): Promise { if (!apiKey) console.warn("missing env.UNIZEN_API_KEY, using public"); - const swapType = tradeType != undefined ? "single": "cross"; + const swapType = tradeType ? "single": "cross"; const url = `${apiRoot}/${chainId}/swap/${swapType}`; - const body = tradeType != undefined + const body = tradeType ? { - transactionData : transactionData, - nativeValue: nativeValue, - account: account, - receiver: receiver, - tradeType: tradeType + transactionData, + nativeValue, + account, + receiver: receiver || account, + tradeType } : { - transactionData : transactionData, - nativeValue: nativeValue, - account: account, - receiver: receiver + transactionData, + nativeValue, + account, + receiver: receiver || account } ; try { const res = await fetch(url, { From 56f4dacd7b9c934fcb112470014dfa4f6535223b Mon Sep 17 00:00:00 2001 From: Josep lluis Yuste Castell Date: Wed, 3 Jul 2024 11:21:53 +0200 Subject: [PATCH 4/4] fix: removed hardcoded addresses and package --- package.json | 1 - src/Unizen/index.ts | 20 +++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 00d72b3..88a3406 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,6 @@ "dependencies": { "@ethersproject/experimental": "^5.7.0", "@types/qs": "^6.9.9", - "@unizen-io/unizen-contract-addresses": "^0.0.14", "dotenv": "^16.3.1", "qs": "^6.11.2" } diff --git a/src/Unizen/index.ts b/src/Unizen/index.ts index 9e632da..f94c40e 100644 --- a/src/Unizen/index.ts +++ b/src/Unizen/index.ts @@ -1,7 +1,5 @@ import qs from "qs"; -import contractAddresses from "@unizen-io/unizen-contract-addresses/production.json"; - import { addEstimatesToTransactionRequest } from "../"; @@ -48,8 +46,18 @@ const getExcludedDexesList = (o: ISwapperParams): Map => { return res; } -const getTargetAddress = (version: string, chainId: number) : string => { - return ((contractAddresses as any)[version] as any)[networkById[chainId]]; +const getTargetAddress = async (version: string, chainId: number) : Promise => { + const baseUrlSpender = `${apiRoot}/${chainId}/approval/spender?contractVersion=${version}`; + try { + const responseSpender = await fetch(baseUrlSpender, { + headers: apiKey ? { "x-api-key": apiKey } : {} + }); + const responseJson = await responseSpender.json(); + return responseJson.address; +} catch (e) { + console.error(`unizen getTargetAddress failed: ${e}`); + return undefined; + } } export const convertQuoteParams = (o: ISwapperParams): IQuoteParams => ({ @@ -75,9 +83,11 @@ export async function getTransactionRequest(o: ISwapperParams): Promise