Skip to content

Commit

Permalink
4927-One Inch config added to chain-abstraction SDK (#4955)
Browse files Browse the repository at this point in the history
* fix: One Inch authorization added

* fix: added checks

* Update typo

Co-authored-by: Rahul Sethuram <[email protected]>

---------

Co-authored-by: Rahul Sethuram <[email protected]>
  • Loading branch information
prathmeshkhandelwal1 and Rahul Sethuram authored Oct 3, 2023
1 parent d97743e commit a92687b
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 10 deletions.
33 changes: 31 additions & 2 deletions packages/agents/chain-abstraction/src/helpers/swapdata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ export type OriginSwapDataCallbackArgs = {
toAsset: string;
amountIn: string;
fromAddress: string;
config?:
| {
customURL: string;
apiKey?: string;
}
| {
customURL?: undefined;
apiKey: string;
};
slippage?: number;
};
export type OriginSwapDataCallback = (args: OriginSwapDataCallbackArgs) => Promise<string>;
Expand Down Expand Up @@ -38,14 +47,34 @@ export const getOriginSwapDataForUniV3 = async (_args: OriginSwapDataCallbackArg
* including a function signature for the 1inch aggregator.
*/
export const getOriginSwapDataForOneInch = async (args: OriginSwapDataCallbackArgs): Promise<string> => {
if (!args.config) throw new Error("No Authorization config provided for 1Inch.");
if (!args.config.apiKey && !args.config.customURL) throw new Error("No API key or custom URL passed for One Inch");
const fromAsset =
args.fromAsset == constants.AddressZero ? "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" : args.fromAsset;
const toAsset = args.toAsset == constants.AddressZero ? "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" : args.toAsset;
try {
const slippage = args.slippage ?? 1;
const apiEndpoint = `https://api.1inch.io/v5.0/${args.chainId}/swap?fromTokenAddress=${fromAsset}&toTokenAddress=${toAsset}&amount=${args.amountIn}&fromAddress=${args.fromAddress}&slippage=${slippage}&disableEstimate=true`;
const { config } = args;

const res = await axiosGet(apiEndpoint);
const url = config.customURL ?? "https://api.1inch.dev/swap/v5.2";

const apiEndpoint =
`${url}/${args.chainId}/swap` +
`?src=${fromAsset}` +
`&dst=${toAsset}` +
`&amount=${args.amountIn}` +
`&from=${args.fromAddress}` +
`&slippage=${slippage}` +
`&disableEstimate=true`;

const headers: Record<string, string> = {
accept: "application/json",
};
if (config.apiKey) {
headers["Authorization"] = `Bearer ${config.apiKey}`;
}

const res = await axiosGet(apiEndpoint, { headers: headers });
return res.data.tx.data;
} catch (error: unknown) {
throw new Error(`Getting swapdata from 1inch failed, e: ${jsonifyError(error as Error).message}`);
Expand Down
2 changes: 1 addition & 1 deletion packages/agents/chain-abstraction/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ export {
getAmountOutMinForUniV3,
} from "./libs";

export { getSupportedAssetsForDomain } from "./helpers";
export { getSupportedAssetsForDomain, OriginSwapDataFns } from "./helpers";
25 changes: 23 additions & 2 deletions packages/agents/chain-abstraction/src/libs/origin/swapandxcall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,20 @@ import { OriginSwapDataFns, OriginSwapperPerDomain, DEPLOYED_ADDRESSES } from ".
* @param calldata - (optional) The calldata to execute (can be empty: "0x").
*
* @param signerAddress - The address of the signer to send a transaction from
* @param config - (optional) Contains API key for oneInch to generate swapData
*/
export const prepareSwapAndXCall = async (
params: SwapAndXCallParams,
signerAddress: string,
config?:
| {
customURL: string;
apiKey?: string;
}
| {
customURL?: undefined;
apiKey: string;
},
): Promise<providers.TransactionRequest | undefined> => {
let txRequest: providers.TransactionRequest | undefined = undefined;

Expand Down Expand Up @@ -64,7 +74,8 @@ export const prepareSwapAndXCall = async (

const isSameAsset = utils.getAddress(toAsset) === utils.getAddress(fromAsset);
const originRoute = !isSameAsset
? _route ?? (await calculateRouteForSwapAndXCall(originDomain, fromAsset, toAsset, amountIn, swapAndXCallAddress))
? _route ??
(await calculateRouteForSwapAndXCall(originDomain, fromAsset, toAsset, amountIn, swapAndXCallAddress, config))
: null;

const feeInNativeAsset = relayerFeeInTransactingAsset.eq(0) ?? false;
Expand Down Expand Up @@ -149,6 +160,7 @@ export const prepareSwapAndXCall = async (
* @param fromAsset - The address of the asset to swap from.
* @param toAsset - The address of the asset to swap to.
* @param amountIn - The number of `fromAsset` tokens.
* @param config - (optional) Contains API key for oneInch to generate swapData
*
* @returns swapper - The address of the swapper contract, swapData - The calldata to be executed
*/
Expand All @@ -158,6 +170,15 @@ export const calculateRouteForSwapAndXCall = async (
toAsset: string,
amountIn: string,
fromAddress: string,
config?:
| {
customURL: string;
apiKey?: string;
}
| {
customURL?: undefined;
apiKey: string;
},
): Promise<{ swapper: string; swapData: string }> => {
// TODO: The `swapper` is the smart contract interacting with different types of DEXes and DEX aggregators such as UniV2, UniV3, 1inch Aggregator
// so we can have more than one `swapper` contract deployed on each domain.
Expand All @@ -177,7 +198,7 @@ export const calculateRouteForSwapAndXCall = async (
}
const chainId = domainToChainId(+domainId);
const originOriginSwapDataCallbackFn = OriginSwapDataFns[swapperConfig.type];
const swapData = await originOriginSwapDataCallbackFn({ chainId, fromAsset, toAsset, amountIn, fromAddress });
const swapData = await originOriginSwapDataCallbackFn({ chainId, fromAsset, toAsset, amountIn, fromAddress, config });

return { swapper: swapperConfig.address, swapData };
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ const mockOriginSwapDataArgs = {
toAsset: mkAddress("0x2"),
amountIn: "100",
fromAddress: mkAddress("0x11"),
config: {
apiKey: "12345",
},
};

describe("Helpers:swapdata", () => {
Expand Down Expand Up @@ -48,7 +51,7 @@ describe("Helpers:swapdata", () => {
axiosGetStub.resolves({ data: { tx: { data: "0xaaa" } } });
const swapData = await getOriginSwapDataForOneInch(mockOriginSwapDataArgs);
expect(axiosGetStub.getCall(0).args[0]).to.be.deep.eq(
"https://api.1inch.io/v5.0/1337/swap?fromTokenAddress=0x1000000000000000000000000000000000000000&toTokenAddress=0x2000000000000000000000000000000000000000&amount=100&fromAddress=0x1100000000000000000000000000000000000000&slippage=1&disableEstimate=true",
"https://api.1inch.dev/swap/v5.2/1337/swap?src=0x1000000000000000000000000000000000000000&dst=0x2000000000000000000000000000000000000000&amount=100&from=0x1100000000000000000000000000000000000000&slippage=1&disableEstimate=true",
);
expect(swapData).to.be.eq("0xaaa");
});
Expand All @@ -57,7 +60,7 @@ describe("Helpers:swapdata", () => {
axiosGetStub.resolves({ data: { tx: { data: "0xaaa" } } });
const swapData = await getOriginSwapDataForOneInch(swapDataArgs);
expect(axiosGetStub.getCall(0).args[0]).to.be.eq(
"https://api.1inch.io/v5.0/1337/swap?fromTokenAddress=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&toTokenAddress=0x2000000000000000000000000000000000000000&amount=100&fromAddress=0x1100000000000000000000000000000000000000&slippage=100&disableEstimate=true",
"https://api.1inch.dev/swap/v5.2/1337/swap?src=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&dst=0x2000000000000000000000000000000000000000&amount=100&from=0x1100000000000000000000000000000000000000&slippage=100&disableEstimate=true",
);
expect(swapData).to.be.eq("0xaaa");
});
Expand All @@ -66,7 +69,7 @@ describe("Helpers:swapdata", () => {
axiosGetStub.resolves({ data: { tx: { data: "0xaaa" } } });
const swapData = await getOriginSwapDataForOneInch(swapDataArgs);
expect(axiosGetStub.getCall(0).args[0]).to.be.eq(
"https://api.1inch.io/v5.0/1337/swap?fromTokenAddress=0x1000000000000000000000000000000000000000&toTokenAddress=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&amount=100&fromAddress=0x1100000000000000000000000000000000000000&slippage=100&disableEstimate=true",
"https://api.1inch.dev/swap/v5.2/1337/swap?src=0x1000000000000000000000000000000000000000&dst=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&amount=100&from=0x1100000000000000000000000000000000000000&slippage=100&disableEstimate=true",
);
expect(swapData).to.be.eq("0xaaa");
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ describe("Libs:origin", () => {
describe("#calculateRouteForSwapAndXCall", () => {
it("should throw if swapper config doesn't exist", async () => {
await expect(
calculateRouteForSwapAndXCall("1337", constants.AddressZero, constants.AddressZero, "100", mkAddress("0x1")),
calculateRouteForSwapAndXCall("1337", constants.AddressZero, constants.AddressZero, "100", mkAddress("0x1"), {
apiKey: "12345",
}),
).to.be.rejectedWith("Swapper config not found for domain: 1337");
});
it("should work", async () => {
Expand All @@ -42,6 +44,7 @@ describe("Libs:origin", () => {
BNB_USDC,
"100000",
mkAddress("0x1"),
{ apiKey: "12345" },
);

expect(calculatedRoute).to.be.deep.eq({
Expand All @@ -63,7 +66,7 @@ describe("Libs:origin", () => {
});
it("happy-1: should work with default params", async () => {
axiosGetStub.resolves({ data: { tx: { data: "0x1a1a1a" } } });
const res = await prepareSwapAndXCall(mockSwapAndXCallParams, mkAddress("0x123"));
const res = await prepareSwapAndXCall(mockSwapAndXCallParams, mkAddress("0x123"), { apiKey: "12345" });
expect(res).to.be.deep.eq({
to: "0x6e92344d08F8443a9C704452ac66bEFB90D32E12",
value: BigNumber.from(0),
Expand Down

0 comments on commit a92687b

Please sign in to comment.