diff --git a/src/config/data/ccip/data.ts b/src/config/data/ccip/data.ts index 45e05485c8e..ec6e6e8167e 100644 --- a/src/config/data/ccip/data.ts +++ b/src/config/data/ccip/data.ts @@ -174,19 +174,25 @@ export const networkFees: NetworkFees = { allLanes: { gasTokenFee: "0.05 %", linkFee: "0.045 %" }, }, [TokenMechanism.LockAndMint]: { - fromEthereum: { gasTokenFee: "0.50 USD", linkFee: "0.45 USD" }, - toEthereum: { gasTokenFee: "1.50 USD", linkFee: "1.35 USD" }, - nonEthereum: { gasTokenFee: "0.25 USD", linkFee: "0.225 USD" }, + fromEthereumToNonEthereum: { gasTokenFee: "0.50 USD", linkFee: "0.45 USD" }, + fromEthereumToSolana: { gasTokenFee: "0.60 USD", linkFee: "0.54 USD" }, + fromNonEthereumToEthereum: { gasTokenFee: "1.50 USD", linkFee: "1.35 USD" }, + fromNonEthereumToNonEthereum: { gasTokenFee: "0.25 USD", linkFee: "0.225 USD" }, + fromNonEthereumToSolana: { gasTokenFee: "0.35 USD", linkFee: "0.315 USD" }, }, [TokenMechanism.BurnAndMint]: { - fromEthereum: { gasTokenFee: "0.50 USD", linkFee: "0.45 USD" }, - toEthereum: { gasTokenFee: "1.50 USD", linkFee: "1.35 USD" }, - nonEthereum: { gasTokenFee: "0.25 USD", linkFee: "0.225 USD" }, + fromEthereumToNonEthereum: { gasTokenFee: "0.50 USD", linkFee: "0.45 USD" }, + fromEthereumToSolana: { gasTokenFee: "0.60 USD", linkFee: "0.54 USD" }, + fromNonEthereumToEthereum: { gasTokenFee: "1.50 USD", linkFee: "1.35 USD" }, + fromNonEthereumToNonEthereum: { gasTokenFee: "0.25 USD", linkFee: "0.225 USD" }, + fromNonEthereumToSolana: { gasTokenFee: "0.35 USD", linkFee: "0.315 USD" }, }, [TokenMechanism.BurnAndUnlock]: { - fromEthereum: { gasTokenFee: "0.50 USD", linkFee: "0.45 USD" }, - toEthereum: { gasTokenFee: "1.50 USD", linkFee: "1.35 USD" }, - nonEthereum: { gasTokenFee: "0.25 USD", linkFee: "0.225 USD" }, + fromEthereumToNonEthereum: { gasTokenFee: "0.50 USD", linkFee: "0.45 USD" }, + fromEthereumToSolana: { gasTokenFee: "0.60 USD", linkFee: "0.54 USD" }, + fromNonEthereumToEthereum: { gasTokenFee: "1.50 USD", linkFee: "1.35 USD" }, + fromNonEthereumToNonEthereum: { gasTokenFee: "0.25 USD", linkFee: "0.225 USD" }, + fromNonEthereumToSolana: { gasTokenFee: "0.35 USD", linkFee: "0.315 USD" }, }, [TokenMechanism.NoPoolDestinationChain]: { allLanes: { gasTokenFee: "", linkFee: "" }, @@ -197,7 +203,8 @@ export const networkFees: NetworkFees = { }, messaging: { fromToEthereum: { gasTokenFee: "0.50 USD", linkFee: "0.45 USD" }, - nonEthereum: { gasTokenFee: "0.10 USD", linkFee: "0.09 USD" }, + fromNonEthereumToNonEthereum: { gasTokenFee: "0.10 USD", linkFee: "0.09 USD" }, + fromNonEthereumToSolana: { gasTokenFee: "0.10 USD", linkFee: "0.09 USD" }, }, } diff --git a/src/config/data/ccip/types.ts b/src/config/data/ccip/types.ts index e12d25d1828..5b7c92e0477 100644 --- a/src/config/data/ccip/types.ts +++ b/src/config/data/ccip/types.ts @@ -117,9 +117,11 @@ export type NetworkFeeStructure = { export type LaneSpecificFees = { fromToEthereum?: NetworkFeeStructure - fromEthereum?: NetworkFeeStructure - toEthereum?: NetworkFeeStructure - nonEthereum?: NetworkFeeStructure + fromEthereumToNonEthereum?: NetworkFeeStructure + fromEthereumToSolana?: NetworkFeeStructure + fromNonEthereumToEthereum?: NetworkFeeStructure + fromNonEthereumToNonEthereum?: NetworkFeeStructure + fromNonEthereumToSolana?: NetworkFeeStructure allLanes?: NetworkFeeStructure } diff --git a/src/config/data/ccip/utils.ts b/src/config/data/ccip/utils.ts index cac553a82fe..03340d595cc 100644 --- a/src/config/data/ccip/utils.ts +++ b/src/config/data/ccip/utils.ts @@ -74,16 +74,19 @@ export const calculateNetworkFeesForTokenMechanism = ( const isSourceEthereum = sourceTechno === "ETHEREUM" const isDestinationEthereum = destinationTechno === "ETHEREUM" + const isDestinationSolana = (destinationTechno as string) === "SOLANA" let laneSpecificFeeKey: LaneSpecificFeeKey - if ((isSourceEthereum || isDestinationEthereum) && feesForMechanism.fromToEthereum) { - laneSpecificFeeKey = "fromToEthereum" - } else if (isSourceEthereum && feesForMechanism.fromEthereum) { - laneSpecificFeeKey = "fromEthereum" - } else if (isDestinationEthereum && feesForMechanism.toEthereum) { - laneSpecificFeeKey = "toEthereum" + if (isSourceEthereum && isDestinationSolana && feesForMechanism.fromEthereumToSolana) { + laneSpecificFeeKey = "fromEthereumToSolana" + } else if (isSourceEthereum && feesForMechanism.fromEthereumToNonEthereum) { + laneSpecificFeeKey = "fromEthereumToNonEthereum" + } else if (isDestinationEthereum && feesForMechanism.fromNonEthereumToEthereum) { + laneSpecificFeeKey = "fromNonEthereumToEthereum" + } else if (isDestinationSolana && feesForMechanism.fromNonEthereumToSolana) { + laneSpecificFeeKey = "fromNonEthereumToSolana" } else { - laneSpecificFeeKey = "nonEthereum" + laneSpecificFeeKey = "fromNonEthereumToNonEthereum" } return calculateNetworkFeesForTokenMechanismDirect(mechanism, laneSpecificFeeKey) @@ -99,18 +102,21 @@ export const calculateMessagingNetworkFeesDirect = (laneSpecificFeeKey: LaneSpec } } -export const calculateMessaingNetworkFees = (sourceChain: SupportedChain, destinationChain: SupportedChain) => { +export const calculateMessagingNetworkFees = (sourceChain: SupportedChain, destinationChain: SupportedChain) => { const sourceTechno = chainToTechnology[sourceChain] const destinationTechno = chainToTechnology[destinationChain] const isSourceEthereum = sourceTechno === "ETHEREUM" const isDestinationEthereum = destinationTechno === "ETHEREUM" + const isDestinationSolana = (destinationTechno as string) === "SOLANA" let laneSpecificFeeKey: LaneSpecificFeeKey if (isSourceEthereum || isDestinationEthereum) { laneSpecificFeeKey = "fromToEthereum" + } else if (isDestinationSolana && networkFees.messaging.fromNonEthereumToSolana) { + laneSpecificFeeKey = "fromNonEthereumToSolana" } else { - laneSpecificFeeKey = "nonEthereum" + laneSpecificFeeKey = "fromNonEthereumToNonEthereum" } return calculateMessagingNetworkFeesDirect(laneSpecificFeeKey) diff --git a/src/content/ccip/billing.mdx b/src/content/ccip/billing.mdx index d8facd6b324..4844bf08794 100644 --- a/src/content/ccip/billing.mdx +++ b/src/content/ccip/billing.mdx @@ -112,6 +112,12 @@ The table below provides an overview of the network fees charged for different u +> **Note:** On the source side, "Not Ethereum" includes Solana. On the destination side, "Not Ethereum" excludes Solana. +> +>

+> When Solana is the destination for Token Transfers or Programmable Token Transfers, an additional fee of 0.10 USD +> applies for [ATA](https://solana.com/docs/tokens#associated-token-account) generation. +
You can use the calculator below to learn the network fees for a specific token. Select the environment (mainnet/testnet), the token, the source blockchain, and the destination blockchain to get the network fee: diff --git a/src/content/ccip/llms-full.txt b/src/content/ccip/llms-full.txt index 072c188f740..50ef4ca8ba8 100644 --- a/src/content/ccip/llms-full.txt +++ b/src/content/ccip/llms-full.txt @@ -1017,7 +1017,6 @@ This section provides an overview of the finality methods CCIP uses to determine | Soneium | Finality tag | 27 minutes | | Sonic | [Block depth](#block-depth) (10 blocks) | 7 seconds | | Shibarium | Finality tag | 1 minute | -| Treasure | Finality tag | 7 hours | | Unichain | Finality tag | 24 minutes | | Wemix | Finality tag | \< 1 second | | Worldchain | Finality tag | 40 minutes | @@ -1133,7 +1132,12 @@ For messaging (only data): The network fee is a static amount, denominated in US The table below provides an overview of the network fees charged for different use cases on different lanes. Percentage-based fees are calculated on the value transferred in a message. USD-denominated fees are applied per message. -
+> **Note:** On the source side, "Not Ethereum" includes Solana. On the destination side, "Not Ethereum" excludes Solana. +> +>
+> +> When Solana is the destination for Token Transfers or Programmable Token Transfers, an additional fee of 0.10 USD +> applies for [ATA](https://solana.com/docs/tokens#associated-token-account) generation. You can use the calculator below to learn the network fees for a specific token. Select the environment (mainnet/testnet), the token, the source blockchain, and the destination blockchain to get the network fee: diff --git a/src/features/ccip/components/billing/Billing.astro b/src/features/ccip/components/billing/Billing.astro index ef8ca7eef19..6834f7b0842 100644 --- a/src/features/ccip/components/billing/Billing.astro +++ b/src/features/ccip/components/billing/Billing.astro @@ -6,11 +6,29 @@ import { } from "@config/data/ccip" const lockAndUnlockAllLanes = calculateNetworkFeesForTokenMechanismDirect(TokenMechanism.LockAndUnlock, "allLanes") -const restFromEthereum = calculateNetworkFeesForTokenMechanismDirect(TokenMechanism.BurnAndMint, "fromEthereum") -const restToEthereum = calculateNetworkFeesForTokenMechanismDirect(TokenMechanism.BurnAndMint, "toEthereum") -const restMechanismNonEthereum = calculateNetworkFeesForTokenMechanismDirect(TokenMechanism.BurnAndMint, "nonEthereum") +const restFromEthereumToNonEthereum = calculateNetworkFeesForTokenMechanismDirect( + TokenMechanism.BurnAndMint, + "fromEthereumToNonEthereum" +) +const restFromEthereumToSolana = calculateNetworkFeesForTokenMechanismDirect( + TokenMechanism.BurnAndMint, + "fromEthereumToSolana" +) +const restFromNonEthereumToEthereum = calculateNetworkFeesForTokenMechanismDirect( + TokenMechanism.BurnAndMint, + "fromNonEthereumToEthereum" +) +const restFromNonEthereumToNonEthereum = calculateNetworkFeesForTokenMechanismDirect( + TokenMechanism.BurnAndMint, + "fromNonEthereumToNonEthereum" +) +const restFromNonEthereumToSolana = calculateNetworkFeesForTokenMechanismDirect( + TokenMechanism.BurnAndMint, + "fromNonEthereumToSolana" +) const messagingFeesFromToEthereum = calculateMessagingNetworkFeesDirect("fromToEthereum") -const messagingFeesNonEthereum = calculateMessagingNetworkFeesDirect("nonEthereum") +const messagingFeesFromNonEthereumToNonEthereum = calculateMessagingNetworkFeesDirect("fromNonEthereumToNonEthereum") +const messagingFeesFromNonEthereumToSolana = calculateMessagingNetworkFeesDirect("fromNonEthereumToSolana") ---
@@ -19,7 +37,8 @@ const messagingFeesNonEthereum = calculateMessagingNetworkFeesDirect("nonEthereu Use case Token Pool Mechanism - Lanes + Source Chain + Destination Chain Fee Token @@ -30,46 +49,82 @@ const messagingFeesNonEthereum = calculateMessagingNetworkFeesDirect("nonEthereu - + Lock and Unlock - All Lanes + All Chains + All Chains {lockAndUnlockAllLanes.linkFee} {lockAndUnlockAllLanes.gasTokenFee} + + Lock and Mint
Burn and Mint
Burn and Unlock + Ethereum + Not Ethereum + {restFromEthereumToNonEthereum.linkFee} + {restFromEthereumToNonEthereum.gasTokenFee} + + + Ethereum + Solana + {restFromEthereumToSolana.linkFee} + {restFromEthereumToSolana.gasTokenFee} + - Lock and Mint
Burn and Mint
Burn and Unlock - Non-Ethereum - {restMechanismNonEthereum.linkFee} - {restMechanismNonEthereum.gasTokenFee} + Not Ethereum + Solana + {restFromNonEthereumToSolana.linkFee} + {restFromNonEthereumToSolana.gasTokenFee} - From: Ethereum - {restFromEthereum.linkFee} - {restFromEthereum.gasTokenFee} + Not Ethereum + Ethereum + {restFromNonEthereumToEthereum.linkFee} + {restFromNonEthereumToEthereum.gasTokenFee} - To: Ethereum - {restToEthereum.linkFee} - {restToEthereum.gasTokenFee} + Not Ethereum + Not Ethereum + {restFromNonEthereumToNonEthereum.linkFee} + {restFromNonEthereumToNonEthereum.gasTokenFee} + + Messaging + N/A + Ethereum + Not Ethereum + {messagingFeesFromToEthereum.linkFee} + {messagingFeesFromToEthereum.gasTokenFee} + - Messaging - N/A - Non-Ethereum - {messagingFeesNonEthereum.linkFee} - {messagingFeesNonEthereum.gasTokenFee} + Ethereum + Solana + {messagingFeesFromToEthereum.linkFee} + {messagingFeesFromToEthereum.gasTokenFee} + + + Not Ethereum + Solana + {messagingFeesFromNonEthereumToSolana.linkFee} + {messagingFeesFromNonEthereumToSolana.gasTokenFee} - From/To: Ethereum + Not Ethereum + Ethereum {messagingFeesFromToEthereum.linkFee} {messagingFeesFromToEthereum.gasTokenFee} + + Not Ethereum + Not Ethereum + {messagingFeesFromNonEthereumToNonEthereum.linkFee} + {messagingFeesFromNonEthereumToNonEthereum.gasTokenFee} +
@@ -86,4 +141,7 @@ const messagingFeesNonEthereum = calculateMessagingNetworkFeesDirect("nonEthereu padding: 1em; white-space: nowrap; } + tr.section-divider td { + border-top: 3px solid #bbb; + } diff --git a/src/lib/markdown/componentHandlers.ts b/src/lib/markdown/componentHandlers.ts index 47cd21c125f..9db02c21a32 100644 --- a/src/lib/markdown/componentHandlers.ts +++ b/src/lib/markdown/componentHandlers.ts @@ -481,25 +481,46 @@ export function handleBilling( try { // Calculate fees using the same logic as Billing.astro const lockAndUnlockAllLanes = calculateNetworkFeesForTokenMechanismDirect(TokenMechanism.LockAndUnlock, "allLanes") - const restFromEthereum = calculateNetworkFeesForTokenMechanismDirect(TokenMechanism.BurnAndMint, "fromEthereum") - const restToEthereum = calculateNetworkFeesForTokenMechanismDirect(TokenMechanism.BurnAndMint, "toEthereum") - const restMechanismNonEthereum = calculateNetworkFeesForTokenMechanismDirect( + const restFromEthereumToNonEthereum = calculateNetworkFeesForTokenMechanismDirect( TokenMechanism.BurnAndMint, - "nonEthereum" + "fromEthereumToNonEthereum" + ) + const restFromEthereumToSolana = calculateNetworkFeesForTokenMechanismDirect( + TokenMechanism.BurnAndMint, + "fromEthereumToSolana" + ) + const restFromNonEthereumToEthereum = calculateNetworkFeesForTokenMechanismDirect( + TokenMechanism.BurnAndMint, + "fromNonEthereumToEthereum" + ) + const restFromNonEthereumToNonEthereum = calculateNetworkFeesForTokenMechanismDirect( + TokenMechanism.BurnAndMint, + "fromNonEthereumToNonEthereum" + ) + const restFromNonEthereumToSolana = calculateNetworkFeesForTokenMechanismDirect( + TokenMechanism.BurnAndMint, + "fromNonEthereumToSolana" ) const messagingFeesFromToEthereum = calculateMessagingNetworkFeesDirect("fromToEthereum") - const messagingFeesNonEthereum = calculateMessagingNetworkFeesDirect("nonEthereum") + const messagingFeesFromNonEthereumToNonEthereum = + calculateMessagingNetworkFeesDirect("fromNonEthereumToNonEthereum") + const messagingFeesFromNonEthereumToSolana = calculateMessagingNetworkFeesDirect("fromNonEthereumToSolana") // Generate markdown table const tableRows = [ - "| Use case | Token Pool Mechanism | Lanes | LINK | Others |", - "|----------|----------------------|-------|------|--------|", - `| Token Transfers / Programmable Token Transfers | Lock and Unlock | All Lanes | ${lockAndUnlockAllLanes.linkFee} | ${lockAndUnlockAllLanes.gasTokenFee} |`, - `| Token Transfers / Programmable Token Transfers | Lock and Mint / Burn and Mint / Burn and Unlock | Non-Ethereum | ${restMechanismNonEthereum.linkFee} | ${restMechanismNonEthereum.gasTokenFee} |`, - `| Token Transfers / Programmable Token Transfers | Lock and Mint / Burn and Mint / Burn and Unlock | From: Ethereum | ${restFromEthereum.linkFee} | ${restFromEthereum.gasTokenFee} |`, - `| Token Transfers / Programmable Token Transfers | Lock and Mint / Burn and Mint / Burn and Unlock | To: Ethereum | ${restToEthereum.linkFee} | ${restToEthereum.gasTokenFee} |`, - `| Messaging | N/A | Non-Ethereum | ${messagingFeesNonEthereum.linkFee} | ${messagingFeesNonEthereum.gasTokenFee} |`, - `| Messaging | N/A | From/To: Ethereum | ${messagingFeesFromToEthereum.linkFee} | ${messagingFeesFromToEthereum.gasTokenFee} |`, + "| Use case | Token Pool Mechanism | Source Chain | Destination Chain | LINK | Others |", + "|----------|----------------------|--------------|-------------------|------|--------|", + `| Token Transfers / Programmable Token Transfers | Lock and Unlock | All Chains | All Chains | ${lockAndUnlockAllLanes.linkFee} | ${lockAndUnlockAllLanes.gasTokenFee} |`, + `| Token Transfers / Programmable Token Transfers | Lock and Mint / Burn and Mint / Burn and Unlock | Ethereum | Not Ethereum | ${restFromEthereumToNonEthereum.linkFee} | ${restFromEthereumToNonEthereum.gasTokenFee} |`, + `| Token Transfers / Programmable Token Transfers | Lock and Mint / Burn and Mint / Burn and Unlock | Ethereum | Solana | ${restFromEthereumToSolana.linkFee} | ${restFromEthereumToSolana.gasTokenFee} |`, + `| Token Transfers / Programmable Token Transfers | Lock and Mint / Burn and Mint / Burn and Unlock | Not Ethereum | Solana | ${restFromNonEthereumToSolana.linkFee} | ${restFromNonEthereumToSolana.gasTokenFee} |`, + `| Token Transfers / Programmable Token Transfers | Lock and Mint / Burn and Mint / Burn and Unlock | Not Ethereum | Ethereum | ${restFromNonEthereumToEthereum.linkFee} | ${restFromNonEthereumToEthereum.gasTokenFee} |`, + `| Token Transfers / Programmable Token Transfers | Lock and Mint / Burn and Mint / Burn and Unlock | Not Ethereum | Not Ethereum | ${restFromNonEthereumToNonEthereum.linkFee} | ${restFromNonEthereumToNonEthereum.gasTokenFee} |`, + `| Messaging | N/A | Ethereum | Not Ethereum | ${messagingFeesFromToEthereum.linkFee} | ${messagingFeesFromToEthereum.gasTokenFee} |`, + `| Messaging | N/A | Ethereum | Solana | ${messagingFeesFromToEthereum.linkFee} | ${messagingFeesFromToEthereum.gasTokenFee} |`, + `| Messaging | N/A | Not Ethereum | Solana | ${messagingFeesFromNonEthereumToSolana.linkFee} | ${messagingFeesFromNonEthereumToSolana.gasTokenFee} |`, + `| Messaging | N/A | Not Ethereum | Ethereum | ${messagingFeesFromToEthereum.linkFee} | ${messagingFeesFromToEthereum.gasTokenFee} |`, + `| Messaging | N/A | Not Ethereum | Not Ethereum | ${messagingFeesFromNonEthereumToNonEthereum.linkFee} | ${messagingFeesFromNonEthereumToNonEthereum.gasTokenFee} |`, ] const markdownTable = tableRows.join("\n")