@robertprp/intents-sdk
Version:
Shogun Network Intent-based cross-chain swaps SDK
87 lines (73 loc) • 2.75 kB
text/typescript
import { constructSimpleSDK, type OptimalRate } from '@paraswap/sdk';
import { ChainID, type SupportedEvmChain } from '../../chains.js';
import { ChainProvider } from '../../core/evm/chain-provider.js';
import { getContract, type Address } from 'viem';
import { ERC20ABI } from '../../core/evm/abi/erc20.js';
import { isNativeEvmToken, WRAPPED_ETH_ADDRESSES } from '../../constants.js';
const rpcProvidersUrl: Record<SupportedEvmChain, string> = {
[ChainID.Arbitrum]: 'https://arbitrum-one-rpc.publicnode.com',
[ChainID.Optimism]: 'https://optimism-rpc.publicnode.com',
[ChainID.Base]: 'https://base-rpc.publicnode.com',
[ChainID.Hyperliquid]: 'https://rpc.hyperliquid.xyz/evm',
};
export type ParaswapQuoteRequestParams = {
srcToken: string;
destToken: string;
amount: bigint;
side: 'SELL' | 'BUY';
};
export type SwapEstimateResult = {
amountOut: bigint;
amountIn: bigint;
amountOutUsd: number;
amountInUsd: number;
quote: OptimalRate;
};
export class ParaswapQuoteProvider {
protected chainId: SupportedEvmChain;
constructor(chainId: SupportedEvmChain) {
this.chainId = chainId;
}
private async getTokenDecimals(tokenAddress: Address): Promise<number> {
const rpcUrl = rpcProvidersUrl[this.chainId];
const client = ChainProvider.getClient(this.chainId, rpcUrl);
const erc20Contract = getContract({
abi: ERC20ABI,
address: tokenAddress,
client,
});
return erc20Contract.read.decimals();
}
private async getQuote(params: ParaswapQuoteRequestParams): Promise<OptimalRate> {
if (isNativeEvmToken(params.destToken)) {
params.destToken = WRAPPED_ETH_ADDRESSES[this.chainId];
}
const [srcTokenDecimals, destTokenDecimals] = await Promise.all([
this.getTokenDecimals(params.srcToken as Address),
this.getTokenDecimals(params.destToken as Address),
]);
const sdk = constructSimpleSDK({ chainId: this.chainId, fetch: fetch });
return sdk.swap.getRate({
amount: params.amount.toString(),
destDecimals: destTokenDecimals,
destToken: params.destToken,
side: params.side,
srcDecimals: srcTokenDecimals,
srcToken: params.srcToken,
});
}
public async getSwapEstimation(params: ParaswapQuoteRequestParams): Promise<SwapEstimateResult> {
const optimalRate = await this.getQuote(params);
const amountOut = optimalRate.destAmount;
const amountIn = optimalRate.srcAmount;
const amountOutUsd = optimalRate.destUSD ?? 0;
const amountInUsd = optimalRate.srcUSD ?? 0;
return {
amountIn: BigInt(amountIn),
amountOut: BigInt(amountOut),
amountOutUsd: Number(amountOutUsd),
amountInUsd: Number(amountInUsd),
quote: optimalRate,
};
}
}