UNPKG

@stable-io/cctp-sdk-cctpr-evm

Version:

EVM support for the CCTPR corridor of the CCTP SDK

90 lines 4.26 kB
// Copyright (c) 2025 Stable Technologies Inc // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. import * as cctpr from "@stable-io/cctp-sdk-cctpr-definitions"; import { duration, v1, v2, genericGasToken } from "@stable-io/cctp-sdk-definitions"; import { assertDistinct, assertEqual } from "@stable-io/utils"; import { CctpR as CctpRContract } from "./contractSdk/index.js"; async function getFastCost(network, source, destination, corridor) { const fastBurnDestination = corridor === "avaxHop" ? "Avalanche" : destination; const { minimumFee } = await v2.fetchFastBurnFeeFactory(network)(source, fastBurnDestination); return minimumFee; } function getSensibleCorridors(network, source, destination) { const universalCorridors = ["v1"]; return !v2.isSupportedDomain(network)(source) || v2.isFastDomain(source) ? universalCorridors : [ ...universalCorridors, (v2.isSupportedDomain(network)(destination) ? "v2Direct" : "avaxHop"), ]; } const calculateSpeed = (network, source, destination, corridor) => { return duration((() => { switch (corridor) { case "v1": return v1.attestationTimeEstimates[network][source]; case "v2Direct": return v2.attestationTimeEstimates[network][source]; case "avaxHop": return v2.attestationTimeEstimates[network][source] + cctpr.relayOverheadOf[network]["Avalanche"] + v1.attestationTimeEstimates[network]["Avalanche"]; default: throw new Error("Invalid corridor"); } })() + cctpr.relayOverheadOf[network][destination], "sec"); }; async function getCorridorStats(network, cctprContract, destination, corridors, gasDropoff) { const gasDropoffRequest = genericGasToken(gasDropoff ? gasDropoff.toUnit("human") : 0); const gasDropoffLimit = genericGasToken(cctpr.gasDropoffLimitOf[network][destination]); if (gasDropoffRequest.gt(gasDropoffLimit)) throw new Error("Gas Drop Off Limit Exceeded"); const source = cctprContract.client.domain; const fastCostsPromise = Promise.all(corridors.map(corridor => corridor === "v1" ? undefined : getFastCost(network, source, destination, corridor))); const variants = ["inUsdc", "inGasToken"]; const quoteRelays = corridors.flatMap(corridor => variants.map(variant => ({ quoteRelay: variant, destinationDomain: destination, corridor, gasDropoff: gasDropoffRequest, }))); const allQuotesPromise = cctprContract.quoteOnChainRelay(quoteRelays); const [fastCosts, allQuotes,] = await Promise.all([fastCostsPromise, allQuotesPromise]); assertEqual(allQuotes.length, corridors.length * variants.length, "Invalid number of quotes"); const stats = corridors.map((corridor, i) => { const quotesIndex = i * variants.length; const [usdcCost, gasCost] = allQuotes.slice(quotesIndex, quotesIndex + variants.length); const costWithRelay = { relay: [usdcCost, gasCost] }; const fastCost = fastCosts[i]; const cost = (fastCost ? { ...costWithRelay, fast: fastCost } : costWithRelay); const transferTime = calculateSpeed(network, source, destination, corridor); return { corridor, cost, transferTime, }; }); return [...stats]; } export const getCorridors = () => async function (client, destination, gasDropoff) { const network = client.network; const source = client.domain; assertDistinct(source, destination); const corridors = getSensibleCorridors(network, source, destination); const cctprContract = new CctpRContract(client); const [{ allowance: fastBurnAllowance }, stats] = await Promise.all([ v2.fetchFastBurnAllowanceFactory(network)(), getCorridorStats(network, cctprContract, destination, corridors, gasDropoff), ]); return { fastBurnAllowance, stats, }; }; //# sourceMappingURL=getCorridors.js.map