Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions src/config/data/ccip/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: "" },
Expand All @@ -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" },
},
}

Expand Down
8 changes: 5 additions & 3 deletions src/config/data/ccip/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
24 changes: 15 additions & 9 deletions src/config/data/ccip/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions src/content/ccip/billing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ The table below provides an overview of the network fees charged for different u

<Billing />

> **Note:** On the source side, "Not Ethereum" includes Solana. On the destination side, "Not Ethereum" excludes Solana.
>
> <br></br>
> 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.

<br id="network-token-calculator" />

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:
Expand Down
8 changes: 6 additions & 2 deletions src/content/ccip/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down Expand Up @@ -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.

<br id="network-token-calculator" />
> **Note:** On the source side, "Not Ethereum" includes Solana. On the destination side, "Not Ethereum" excludes Solana.
>
> <br />
>
> 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:

Expand Down
104 changes: 81 additions & 23 deletions src/features/ccip/components/billing/Billing.astro
Original file line number Diff line number Diff line change
Expand Up @@ -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")
---

<div style="overflow-x: auto;">
Expand All @@ -19,7 +37,8 @@ const messagingFeesNonEthereum = calculateMessagingNetworkFeesDirect("nonEthereu
<tr>
<th rowspan="2">Use case</th>
<th rowspan="2">Token Pool Mechanism</th>
<th rowspan="2">Lanes</th>
<th rowspan="2">Source Chain</th>
<th rowspan="2">Destination Chain</th>
<th colspan="2">Fee Token</th>
</tr>
<tr>
Expand All @@ -30,46 +49,82 @@ const messagingFeesNonEthereum = calculateMessagingNetworkFeesDirect("nonEthereu
<tbody>
<!-- Token Transfers with/without messaging -->
<tr>
<td rowspan="4">
<td rowspan="6">
<ul style="list-style-type:none; margin:0; padding:0;">
<li>Token Transfers</li>
<li>Programmable Token Transfers</li>
</ul>
</td>
<td>Lock and Unlock</td>
<td>All Lanes</td>
<td>All Chains</td>
<td>All Chains</td>
<td>{lockAndUnlockAllLanes.linkFee}</td>
<td>{lockAndUnlockAllLanes.gasTokenFee}</td>
</tr>
<tr class="section-divider">
<td rowspan="5">Lock and Mint<br />Burn and Mint<br />Burn and Unlock</td>
<td>Ethereum</td>
<td>Not Ethereum</td>
<td>{restFromEthereumToNonEthereum.linkFee}</td>
<td>{restFromEthereumToNonEthereum.gasTokenFee}</td>
</tr>
<tr>
<td>Ethereum</td>
<td>Solana</td>
<td>{restFromEthereumToSolana.linkFee}</td>
<td>{restFromEthereumToSolana.gasTokenFee}</td>
</tr>
<tr>
<td rowspan="3">Lock and Mint<br />Burn and Mint<br />Burn and Unlock</td>
<td>Non-Ethereum</td>
<td>{restMechanismNonEthereum.linkFee}</td>
<td>{restMechanismNonEthereum.gasTokenFee}</td>
<td>Not Ethereum</td>
<td>Solana</td>
<td>{restFromNonEthereumToSolana.linkFee}</td>
<td>{restFromNonEthereumToSolana.gasTokenFee}</td>
</tr>
<tr>
<td>From: Ethereum</td>
<td>{restFromEthereum.linkFee}</td>
<td>{restFromEthereum.gasTokenFee}</td>
<td>Not Ethereum</td>
<td>Ethereum</td>
<td>{restFromNonEthereumToEthereum.linkFee}</td>
<td>{restFromNonEthereumToEthereum.gasTokenFee}</td>
</tr>
<tr>
<td>To: Ethereum</td>
<td>{restToEthereum.linkFee}</td>
<td>{restToEthereum.gasTokenFee}</td>
<td>Not Ethereum</td>
<td>Not Ethereum</td>
<td>{restFromNonEthereumToNonEthereum.linkFee}</td>
<td>{restFromNonEthereumToNonEthereum.gasTokenFee}</td>
</tr>
<!-- Messaging -->
<tr class="section-divider">
<td rowspan="5">Messaging</td>
<td rowspan="5">N/A</td>
<td>Ethereum</td>
<td>Not Ethereum</td>
<td>{messagingFeesFromToEthereum.linkFee}</td>
<td>{messagingFeesFromToEthereum.gasTokenFee}</td>
</tr>
<tr>
<td rowspan="2">Messaging</td>
<td rowspan="2">N/A</td>
<td>Non-Ethereum</td>
<td>{messagingFeesNonEthereum.linkFee}</td>
<td>{messagingFeesNonEthereum.gasTokenFee}</td>
<td>Ethereum</td>
<td>Solana</td>
<td>{messagingFeesFromToEthereum.linkFee}</td>
<td>{messagingFeesFromToEthereum.gasTokenFee}</td>
</tr>
<tr>
<td>Not Ethereum</td>
<td>Solana</td>
<td>{messagingFeesFromNonEthereumToSolana.linkFee}</td>
<td>{messagingFeesFromNonEthereumToSolana.gasTokenFee}</td>
</tr>
<tr>
<td>From/To: Ethereum</td>
<td>Not Ethereum</td>
<td>Ethereum</td>
<td>{messagingFeesFromToEthereum.linkFee}</td>
<td>{messagingFeesFromToEthereum.gasTokenFee}</td>
</tr>
<tr>
<td>Not Ethereum</td>
<td>Not Ethereum</td>
<td>{messagingFeesFromNonEthereumToNonEthereum.linkFee}</td>
<td>{messagingFeesFromNonEthereumToNonEthereum.gasTokenFee}</td>
</tr>
</tbody>
</table>
</div>
Expand All @@ -86,4 +141,7 @@ const messagingFeesNonEthereum = calculateMessagingNetworkFeesDirect("nonEthereu
padding: 1em;
white-space: nowrap;
}
tr.section-divider td {
border-top: 3px solid #bbb;
}
</style>
47 changes: 34 additions & 13 deletions src/lib/markdown/componentHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Loading