Created
May 19, 2025 19:35
-
-
Save olegpetroveth/88ffd4d1d4c35cdc39352835a0ac3304 to your computer and use it in GitHub Desktop.
PancakeSwap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function ({ | |
sourceAddress, | |
destinationAddress, | |
sellAssetAmount, | |
buyAssetAmount, | |
// affiliateFee, | |
slipPercentage, | |
}: ProviderQuoteRequest): Promise<ProviderQuoteResponse> { | |
try { | |
// Check provider chain action enabled status | |
const shouldQuote = await isActionEnabled({ | |
action: ProviderAction.swap, | |
provider: name, | |
chains: [sellAssetAmount.chain, buyAssetAmount.chain], | |
}); | |
if (!shouldQuote) { | |
throw new SwapKitError({ | |
code: ErrorCode.quoteUnavailable, | |
args: [name], | |
}); | |
} | |
const sellProviderToken = pancakeSwapApi.helpers.toProviderToken(sellAssetAmount); | |
const buyProviderToken = pancakeSwapApi.helpers.toProviderToken(buyAssetAmount); | |
const sellTokenAmount = CurrencyAmount.fromRawAmount( | |
sellProviderToken, | |
sellAssetAmount.getBaseValue("string"), | |
); | |
// consider caching this in config? | |
const [v2Pools, v3Pools] = await Promise.all([ | |
SmartRouter.getV2CandidatePools({ | |
// @ts-expect-error ignore viem | |
onChainProvider: () => publicClient, | |
currencyA: sellProviderToken, | |
currencyB: buyProviderToken, | |
}), | |
SmartRouter.getV3CandidatePools({ | |
// @ts-expect-error ignore viem | |
onChainProvider: () => publicClient, | |
currencyA: sellProviderToken, | |
currencyB: buyProviderToken, | |
}), | |
]); | |
const bestTrade = await SmartRouter.getBestTrade( | |
sellTokenAmount, | |
buyProviderToken, | |
TradeType.EXACT_INPUT, | |
{ | |
gasPriceWei: () => publicClient.getGasPrice(), | |
maxHops: 3, | |
maxSplits: 3, | |
poolProvider: SmartRouter.createStaticPoolProvider([...v2Pools, ...v3Pools]), | |
quoteProvider, | |
quoterOptimization: false, | |
}, | |
); | |
if (!bestTrade) { | |
throw new SwapKitError({ | |
code: ErrorCode.noQuoteResponse, | |
args: [this.name, "No quote response from Pancakeswap."], | |
}); | |
} | |
const { value, calldata } = SwapRouter.swapCallParameters( | |
{ ...bestTrade, gasEstimate: bestTrade.gasEstimate }, | |
{ | |
recipient: destinationAddress as `0x${string}`, | |
slippageTolerance: new Percent(slipPercentage, 100), | |
//TODO - figure out comprehensive strategy for fee sharing between SK and partners for single chain fees | |
// fee: { | |
// fee: new Percent(Number(0), 100), | |
// recipient: "0x9F9A7D3e131eD45225396613E383D59a732f7BeB", | |
// }, | |
}, | |
); | |
const router = pancakeswapProvider.getRouterAddress({ chainId: sellAssetAmount.chainId }); | |
if (!router) { | |
throw new SwapKitError({ | |
code: ErrorCode.noRouterAddressFound, | |
args: [name, sellAssetAmount.chainId], | |
}); | |
} | |
const tx = buildTx({ | |
sellAssetAmount, | |
sourceAddress, | |
destinationAddress, | |
calldata, | |
value, | |
}); | |
const quoteAmount = bestTrade.outputAmount.toFixed(); | |
const quoteAssetAmount = buyAssetAmount.set(quoteAmount); | |
return { | |
sellAssetAmount, | |
buyAssetAmount: quoteAssetAmount, | |
buyAssetAmountMaxSlippage: quoteAssetAmount, | |
slippageBps: slipPercentage * 100, | |
sourceAddress, | |
destinationAddress, | |
routerAddress: router, | |
tx, | |
estimatedTime: this.estimateTime!({ | |
inboundAsset: sellAssetAmount, | |
outboundAsset: buyAssetAmount, | |
}), | |
}; | |
} catch (error) { | |
logger.error({ error }, `${name}: Error fetching quote`); | |
throw error; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment