diff --git a/docs/docs.json b/docs/docs.json
index ab6128b2b..41503f645 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -27,6 +27,14 @@
"learning-lit/backup-and-recovery",
"learning-lit/threshold-cryptography"
]
+ },
+ {
+ "group": "Pricing",
+ "pages": [
+ "learning-lit/pricing/payment-model",
+ "learning-lit/pricing/current-prices",
+ "learning-lit/pricing/example-lit-action-costs"
+ ]
}
]
},
diff --git a/docs/learning-lit/communicating-with-lit-nodes.mdx b/docs/learning-lit/communicating-with-lit-nodes.mdx
index 437a947d5..3720c4986 100644
--- a/docs/learning-lit/communicating-with-lit-nodes.mdx
+++ b/docs/learning-lit/communicating-with-lit-nodes.mdx
@@ -51,6 +51,6 @@ The following is the complete request lifecycle when communicating with the Lit
## Active Nodes
-The Naga node operator set was selected via a staking contest that ran following the Lit TGE. The top 10 node operators based on "[stake weight](https://github.com/LIT-Protocol/LITKEY-Token-Paper-v1/blob/main/%24LITKEY%20Whitepaper%20-%20v1.pdf)" were selected by the community.
+The Naga node operator set was selected via a staking contest that ran following the Lit TGE. The top 10 node operators based on "[stake weight](https://github.com/LIT-Protocol/LITKEY-Token-Paper-v1/blob/main/LITKEY-Whitepaper-Updated-Oct-25.pdf)" were selected by the community.
Interested in running a node? [Reach out.](https://forms.gle/n4WKtsyxaduEz8dDA)
diff --git a/docs/learning-lit/cryptoeconomic-security.mdx b/docs/learning-lit/cryptoeconomic-security.mdx
index 6f4096e50..42add479e 100644
--- a/docs/learning-lit/cryptoeconomic-security.mdx
+++ b/docs/learning-lit/cryptoeconomic-security.mdx
@@ -15,4 +15,4 @@ While threshold cryptography and TEEs provide technical security guarantees, the
Additionally, token holders who aren't node operators themselves will be able to delegate their $LITKEY tokens to a node operator(s) of their choice, curating the set of active node operators and helping distribute cryptographic security across a broader set of participants.
-You can learn more about the role and utility of the $LITKEY token by checking out the [token whitepaper](https://github.com/LIT-Protocol/LITKEY-Token-Paper-v1/blob/main/%24LITKEY%20Whitepaper%20-%20v1.pdf).
+You can learn more about the role and utility of the $LITKEY token by checking out the [token whitepaper](https://github.com/LIT-Protocol/LITKEY-Token-Paper-v1/blob/main/LITKEY-Whitepaper-Updated-Oct-25.pdf).
diff --git a/docs/learning-lit/distributed-key-generation.mdx b/docs/learning-lit/distributed-key-generation.mdx
index 3c5daf635..debfd8652 100644
--- a/docs/learning-lit/distributed-key-generation.mdx
+++ b/docs/learning-lit/distributed-key-generation.mdx
@@ -4,7 +4,7 @@ title: "Distributed Key Generation"
## Intro
-All Lit Protocol node operators use a [Distributed Key Generation (DKG)](https://github.com/LIT-Protocol/whitepaper/blob/main/Lit%20Protocol%20Whitepaper%20(2024).pdf) process to collectively generate all of the signing and encryption keys managed by the network. DKG ensures that no single node or party ever has access to any key in its entirety, as the entire key never exists at all. Instead, more than a threshold of the Lit nodes must come together (more than two-thirds of the network) to generate these keys and perform signing and decryption operations.
+All Lit Protocol node operators use a [Distributed Key Generation (DKG)](https://github.com/LIT-Protocol/LITKEY-Token-Paper-v1/blob/main/LITKEY-Whitepaper-Updated-Oct-25.pdf) process to collectively generate all of the signing and encryption keys managed by the network. DKG ensures that no single node or party ever has access to any key in its entirety, as the entire key never exists at all. Instead, more than a threshold of the Lit nodes must come together (more than two-thirds of the network) to generate these keys and perform signing and decryption operations.
## Root Keys
@@ -12,7 +12,7 @@ All signing keys are derived hierarchically from a set of root keys. These root
## Key Refresh and Resharing
-Periodically, key shares are updated with a refresh scheme. This rotates the private key shares among an existing set of participating node operators without changing the underlying private key, a process known as [Proactive Secret Sharing.](https://github.com/LIT-Protocol/whitepaper/blob/main/Lit%20Protocol%20Whitepaper%20(2024).pdf) This method helps ensure the integrity of private key material for long periods of time while minimizing the risk of key compromise.
+Periodically, key shares are updated with a refresh scheme. This rotates the private key shares among an existing set of participating node operators without changing the underlying private key, a process known as [Proactive Secret Sharing.](https://github.com/LIT-Protocol/LITKEY-Token-Paper-v1/blob/main/LITKEY-Whitepaper-Updated-Oct-25.pdf) This method helps ensure the integrity of private key material for long periods of time while minimizing the risk of key compromise.
The key refresh protocol is performed by first linearizing all of the key shares, running the same DKG algorithm with existing participants, then checking that the public key doesn't change.
diff --git a/docs/learning-lit/pricing/current-prices.mdx b/docs/learning-lit/pricing/current-prices.mdx
new file mode 100644
index 000000000..1a64bce46
--- /dev/null
+++ b/docs/learning-lit/pricing/current-prices.mdx
@@ -0,0 +1,48 @@
+---
+title: "Current Prices"
+---
+import { CurrentPricesTable } from "/snippets/CurrentPricesTable.jsx";
+import { PriceProvider } from "/snippets/PriceProvider.jsx";
+
+The following table shows the current pricing for Lit Protocol services on the **Naga Prod / Mainnet V1** network. Prices are displayed in both $LITKEY tokens and USD (based on current market rates).
+
+
+Most prices update dynamically based on network usage. The values shown below reflect real-time prices fetched from the blockchain. Note that PKP Minting cost is static and does not change with network utilization.
+
+
+
+
+## Understanding the Price Table
+
+### Base vs Max Prices
+
+- **Base Price**: The minimum price when network usage is low
+- **Max Price**: The maximum price when the network is at full capacity
+- **Current Price**: The actual price at this moment, which varies between base and max based on usage
+
+### Product Types
+
+- **PKP Sign**: Signing operations using your Programmable Key Pair
+- **Decryption and Access Control**: Decrypting data and enforcing access control conditions
+- **Lit Action**: Executing serverless JavaScript functions (pricing varies by component)
+- **Sign Session Key**: Session-based signing operations
+- **PKP Minting**: Creating a new Programmable Key Pair (static price, does not vary with network usage)
+
+### Lit Action Pricing Components
+
+Lit Actions have multiple pricing components that are charged based on resource usage:
+
+- **Base Amount**: Fixed cost per Lit Action execution
+- **Runtime Length**: Cost per second of execution time
+- **Memory Usage**: Cost per megabyte of memory used
+- **Code Length**: Cost based on the size of your Lit Action code
+- **Response Length**: Cost based on the size of the response data
+- **Signatures**: Cost per signature generated
+- **Broadcasts**: Cost per broadcast operation
+- **Contract Calls**: Cost per smart contract call
+- **Call Depth**: Cost based on call stack depth
+- **Decrypts**: Cost per decryption operation
+- **Fetches**: Cost per HTTP fetch request
+
+The total cost of a Lit Action is calculated by summing all applicable components based on your action's actual resource usage.
+
diff --git a/docs/learning-lit/pricing/example-lit-action-costs.mdx b/docs/learning-lit/pricing/example-lit-action-costs.mdx
new file mode 100644
index 000000000..99704e373
--- /dev/null
+++ b/docs/learning-lit/pricing/example-lit-action-costs.mdx
@@ -0,0 +1,26 @@
+---
+title: "Example Lit Action Costs"
+---
+import { ExampleLitActionCosts } from "/snippets/ExampleLitActionCosts.jsx";
+import { PriceProvider } from "/snippets/PriceProvider.jsx";
+
+This page demonstrates real-world cost estimates for common Lit Action operations. The costs are calculated using current real-time prices from the blockchain and show how different resource usage affects the total cost.
+
+
+These are estimates based on current prices and the specified resource usage. Actual costs may vary slightly based on network conditions and exact resource consumption.
+
+
+
+
+## Understanding the Cost Breakdown
+
+Each example shows a detailed breakdown of costs by component:
+
+- **Base Amount**: Fixed cost per Lit Action execution
+- **Runtime Length**: Cost based on execution time (charged per second)
+- **Fetches**: Cost per HTTP fetch request
+- **Signatures**: Cost per signature generated
+- **Decrypts**: Cost per decryption operation
+
+The total cost is the sum of all applicable components based on the operation's resource usage.
+
diff --git a/docs/learning-lit/pricing/payment-model.mdx b/docs/learning-lit/pricing/payment-model.mdx
new file mode 100644
index 000000000..75c2c884f
--- /dev/null
+++ b/docs/learning-lit/pricing/payment-model.mdx
@@ -0,0 +1,63 @@
+---
+title: "Payment Model"
+---
+
+Lit Protocol uses a token-based payment system to ensure the decentralized network can sustain itself for providing cryptographic services.
+
+## How Network Usage Payments Work
+
+### Token Deposit System
+
+To use Lit Protocol's services, you must first load tokens into the **Ledger Contract** on Lit Chain. This contract acts as a prepaid account that holds your [$LITKEY](/governance/litkey/overview) tokens and automatically deducts fees as you use the network.
+
+### Dynamic Pricing Model
+
+Lit Protocol uses a dynamic pricing model that adjusts based on network usage:
+
+- **Base Price**: The minimum price for each service when the network has low usage
+- **Max Price**: The maximum price when the network is at full capacity
+- **Current Price**: The actual price at any given moment, which fluctuates between the base and max price based on current network usage
+
+This pricing mechanism ensures:
+- Fair pricing during low-usage periods (you pay less when demand is low)
+- Network stability during high-usage periods (prices increase to manage demand)
+- Market price discovery for Lit network capacity
+
+### Pricing in $LITKEY Tokens
+
+All services on Lit Protocol are priced in **[$LITKEY](/governance/litkey/overview) tokens**, the native token of Lit Chain. When you use network services such as:
+
+- **PKP Signing**: Generating signatures with your Programmable Key Pair
+- **Decryption and Access Control**: Decrypting data and enforcing access control conditions
+- **Lit Actions**: Executing serverless JavaScript functions
+- **Sign Session Key**: Session-based signing operations
+
+The network automatically deducts the appropriate amount of [$LITKEY](/governance/litkey/overview) tokens from your ledger balance based on the current dynamic price.
+
+### Automatic Deduction
+
+When you make a request to the network, the system:
+1. Checks your ledger balance
+2. Calculates the current price for the requested service
+3. Deducts the required tokens from your balance
+4. Processes your request
+
+If your balance is insufficient, the request will fail. You can check your balance and deposit more tokens as needed using the [Payment Manager](/sdk/getting-started/payment-manager-setup).
+
+## Getting Started
+
+To start using Lit Protocol's paid services:
+
+1. **Acquire [$LITKEY](/governance/litkey/overview) tokens** - [Get tokens](/governance/litkey/getting-litkey) from exchanges or other sources
+2. **Set up Payment Manager** - Configure your payment system using the [Payment Manager Setup Guide](/sdk/getting-started/payment-manager-setup)
+3. **Deposit tokens** - Load tokens into the ledger contract
+4. **Use the network** - Start making requests; tokens will be deducted automatically
+
+For detailed information on current pricing, see the [Current Prices](/learning-lit/pricing/current-prices) page.
+
+## Additional Costs
+
+There are additional costs associated with using Lit Protocol's services that are not covered by the network usage payments. These include:
+
+- **Gas on Lit Chain** - Lit Chain is the database for Lit network. When you make a transaction on Lit Chain, you will need to pay for the gas used by the transaction. Examples of operations that would require a transaction on Lit Chain are things like changing PKP Permissions, transferring PKPs, and launching smart contracts on Lit Chain. Lit Chain gas is priced in $LITKEY tokens and the gas price is very low compared to other chains.
+- **PKP Minting** - When you mint a new PKP, you will need to pay a specific fee for the minting operation. This fee is not dynamic and is a fixed cost. Check out the [Current Prices page](/learning-lit/pricing/current-prices) to see the price right now.
\ No newline at end of file
diff --git a/docs/lit-pricing-constants.js b/docs/lit-pricing-constants.js
new file mode 100644
index 000000000..897219a74
--- /dev/null
+++ b/docs/lit-pricing-constants.js
@@ -0,0 +1,43 @@
+// Shared constants and helper functions for Lit Protocol pricing components
+// This file is automatically included on every page by Mintlify
+
+window.LitPricingConstants = {
+ // LitActionPriceComponent enum values
+ LitActionPriceComponent: {
+ baseAmount: 0,
+ runtimeLength: 1,
+ memoryUsage: 2,
+ codeLength: 3,
+ responseLength: 4,
+ signatures: 5,
+ broadcasts: 6,
+ contractCalls: 7,
+ callDepth: 8,
+ decrypts: 9,
+ fetches: 10,
+ },
+
+ // NodePriceMeasurement enum values
+ NodePriceMeasurement: {
+ perSecond: 0,
+ perMegabyte: 1,
+ perCount: 2,
+ },
+
+ // Helper function to convert wei to tokens
+ weiToTokens: (wei, ethers) => {
+ if (!ethers || !ethers.utils) {
+ return 0;
+ }
+ return parseFloat(ethers.utils.formatUnits(wei, 18));
+ },
+
+ // Helper function to format price display
+ formatPrice: (priceInTokens, priceInUSD) => {
+ if (priceInUSD === null) {
+ return `${priceInTokens.toFixed(6)} LITKEY`;
+ }
+ return `${priceInTokens.toFixed(6)} LITKEY ($${priceInUSD.toFixed(6)})`;
+ },
+};
+
diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx
new file mode 100644
index 000000000..cf3a24555
--- /dev/null
+++ b/docs/snippets/CurrentPricesTable.jsx
@@ -0,0 +1,394 @@
+export const CurrentPricesTable = ({ priceData }) => {
+ // Get constants and helper functions from window (populated by lit-pricing-constants.js)
+ const LitActionPriceComponent = window.LitPricingConstants?.LitActionPriceComponent || {};
+ const NodePriceMeasurement = window.LitPricingConstants?.NodePriceMeasurement || {};
+ const weiToTokens = window.LitPricingConstants?.weiToTokens || (() => 0);
+ const formatPrice = window.LitPricingConstants?.formatPrice || ((price) => String(price));
+
+ // Product IDs
+ const ProductId = {
+ PkpSign: 0,
+ EncSign: 1,
+ LitAction: 2,
+ SignSessionKey: 3,
+ };
+
+ // Product IDs array used for fetching prices
+ const PRODUCT_IDS = [
+ ProductId.PkpSign,
+ ProductId.EncSign,
+ ProductId.LitAction,
+ ProductId.SignSessionKey,
+ ];
+
+ const PRODUCT_NAMES = {
+ [ProductId.PkpSign]: 'PKP Sign',
+ [ProductId.EncSign]: 'Encrypted Sign',
+ [ProductId.LitAction]: 'Lit Action',
+ [ProductId.SignSessionKey]: 'Sign Session Key',
+ };
+
+ const LIT_ACTION_COMPONENT_NAMES = {
+ [LitActionPriceComponent.baseAmount]: 'Base Amount',
+ [LitActionPriceComponent.runtimeLength]: 'Runtime Length',
+ [LitActionPriceComponent.memoryUsage]: 'Memory Usage',
+ [LitActionPriceComponent.codeLength]: 'Code Length',
+ [LitActionPriceComponent.responseLength]: 'Response Length',
+ [LitActionPriceComponent.signatures]: 'Signatures',
+ [LitActionPriceComponent.broadcasts]: 'Broadcasts',
+ [LitActionPriceComponent.contractCalls]: 'Contract Calls',
+ [LitActionPriceComponent.callDepth]: 'Call Depth',
+ [LitActionPriceComponent.decrypts]: 'Decrypts',
+ [LitActionPriceComponent.fetches]: 'Fetches',
+ };
+
+ const MEASUREMENT_NAMES = {
+ [NodePriceMeasurement.perSecond]: '/second',
+ [NodePriceMeasurement.perMegabyte]: '/MB',
+ [NodePriceMeasurement.perCount]: '/count',
+ };
+
+ if (!priceData) {
+ return (
+
+
Price data not available. Please wrap this component with PriceProvider.
+
+ );
+ }
+
+ const {
+ loading,
+ error,
+ basePrices,
+ maxPrices,
+ currentPrices,
+ litActionConfigs,
+ litKeyPriceUSD,
+ usagePercent,
+ pkpMintCost,
+ ethers,
+ } = priceData;
+
+ if (loading) {
+ return (
+
+
Loading current prices from blockchain...
+
+ );
+ }
+
+ if (error) {
+ return (
+
+
Error loading prices: {error}
+
+ Unable to fetch pricing data. Please check your connection or try again later.
+
+
+ );
+ }
+
+ return (
+
+ {litKeyPriceUSD && (
+
+ LITKEY Price: ${litKeyPriceUSD.toFixed(4)} USD
+ {usagePercent !== null && (
+
+ Estimated Network Usage: {usagePercent}%
+
+ )}
+
+ )}
+
+
+
+
+
+ |
+ Product
+ |
+
+ Current Price
+ |
+
+ Base Price
+ |
+
+ Max Price
+ |
+
+
+
+ {PRODUCT_IDS.map((productId, index) => {
+ const basePriceInTokens = weiToTokens(basePrices[index], ethers);
+ const maxPriceInTokens = weiToTokens(maxPrices[index], ethers);
+ const currentPriceInTokens = weiToTokens(currentPrices[index], ethers);
+ const basePriceInUSD = litKeyPriceUSD
+ ? basePriceInTokens * litKeyPriceUSD
+ : null;
+ const maxPriceInUSD = litKeyPriceUSD
+ ? maxPriceInTokens * litKeyPriceUSD
+ : null;
+ const currentPriceInUSD = litKeyPriceUSD
+ ? currentPriceInTokens * litKeyPriceUSD
+ : null;
+
+ return (
+
+ |
+ {PRODUCT_NAMES[productId]}
+ |
+
+ {formatPrice(currentPriceInTokens, currentPriceInUSD)}
+ |
+
+ {formatPrice(basePriceInTokens, basePriceInUSD)}
+ |
+
+ {formatPrice(maxPriceInTokens, maxPriceInUSD)}
+ |
+
+ );
+ })}
+ {pkpMintCost !== null && (
+
+ |
+ PKP Minting{' '}
+
+ (Static)
+
+ |
+
+ {formatPrice(
+ weiToTokens(pkpMintCost, ethers),
+ litKeyPriceUSD
+ ? weiToTokens(pkpMintCost, ethers) * litKeyPriceUSD
+ : null
+ )}
+ |
+
+ {formatPrice(
+ weiToTokens(pkpMintCost, ethers),
+ litKeyPriceUSD
+ ? weiToTokens(pkpMintCost, ethers) * litKeyPriceUSD
+ : null
+ )}
+ |
+
+ {formatPrice(
+ weiToTokens(pkpMintCost, ethers),
+ litKeyPriceUSD
+ ? weiToTokens(pkpMintCost, ethers) * litKeyPriceUSD
+ : null
+ )}
+ |
+
+ )}
+
+
+
+
+
+ Lit Action Price Components
+
+
+
+
+
+ |
+ Component
+ |
+
+ Price
+ |
+
+
+
+ {litActionConfigs.map((config, index) => {
+ const priceComponentNum = Number(config.priceComponent);
+ const priceMeasurementNum = Number(config.priceMeasurement);
+ const componentName =
+ LIT_ACTION_COMPONENT_NAMES[priceComponentNum] ||
+ `Component ${priceComponentNum}`;
+ const measurementName =
+ MEASUREMENT_NAMES[priceMeasurementNum] || '';
+ const priceInTokens = weiToTokens(config.price, ethers);
+ const priceInUSD = litKeyPriceUSD
+ ? priceInTokens * litKeyPriceUSD
+ : null;
+
+ return (
+
+ |
+ {componentName}
+ {measurementName && (
+
+ {measurementName}
+
+ )}
+ |
+
+ {formatPrice(priceInTokens, priceInUSD)}
+ |
+
+ );
+ })}
+
+
+
+
+ );
+};
diff --git a/docs/snippets/ExampleLitActionCosts.jsx b/docs/snippets/ExampleLitActionCosts.jsx
new file mode 100644
index 000000000..ae241b89a
--- /dev/null
+++ b/docs/snippets/ExampleLitActionCosts.jsx
@@ -0,0 +1,371 @@
+export const ExampleLitActionCosts = ({ priceData }) => {
+ // Get constants and helper functions from window (populated by lit-pricing-constants.js)
+ const LitActionPriceComponent = window.LitPricingConstants?.LitActionPriceComponent || {};
+ const NodePriceMeasurement = window.LitPricingConstants?.NodePriceMeasurement || {};
+ const weiToTokens = window.LitPricingConstants?.weiToTokens || (() => 0);
+ const formatPrice = window.LitPricingConstants?.formatPrice || ((price) => String(price));
+ if (!priceData) {
+ return (
+
+
Price data not available. Please wrap this component with PriceProvider.
+
+ );
+ }
+
+ const {
+ loading,
+ error,
+ litActionConfigs,
+ litKeyPriceUSD,
+ ethers,
+ } = priceData;
+
+ // Helper to get price for a specific component
+ const getComponentPrice = (componentType, measurementType) => {
+ if (!litActionConfigs || litActionConfigs.length === 0) return null;
+
+ const config = litActionConfigs.find(
+ (c) =>
+ Number(c.priceComponent) === componentType &&
+ Number(c.priceMeasurement) === measurementType
+ );
+
+ if (!config) return null;
+ return weiToTokens(config.price, ethers);
+ };
+
+ // Calculate cost for a Lit Action example
+ const calculateCost = (example) => {
+ if (!litActionConfigs || litActionConfigs.length === 0) return null;
+
+ let totalCost = 0;
+ const breakdown = [];
+
+ // Base amount (always included)
+ const baseAmount = getComponentPrice(
+ LitActionPriceComponent.baseAmount,
+ NodePriceMeasurement.perCount
+ );
+ if (baseAmount !== null) {
+ totalCost += baseAmount;
+ breakdown.push({
+ component: 'Base Amount',
+ quantity: 1,
+ unitPrice: baseAmount,
+ total: baseAmount,
+ });
+ }
+
+ // Runtime length (per second)
+ if (example.runtimeSeconds) {
+ const runtimePrice = getComponentPrice(
+ LitActionPriceComponent.runtimeLength,
+ NodePriceMeasurement.perSecond
+ );
+ if (runtimePrice !== null) {
+ const runtimeCost = runtimePrice * example.runtimeSeconds;
+ totalCost += runtimeCost;
+ breakdown.push({
+ component: 'Runtime Length',
+ quantity: example.runtimeSeconds,
+ unitPrice: runtimePrice,
+ total: runtimeCost,
+ unit: 'seconds',
+ });
+ }
+ }
+
+ // Fetches (per count)
+ if (example.fetches) {
+ const fetchPrice = getComponentPrice(
+ LitActionPriceComponent.fetches,
+ NodePriceMeasurement.perCount
+ );
+ if (fetchPrice !== null) {
+ const fetchCost = fetchPrice * example.fetches;
+ totalCost += fetchCost;
+ breakdown.push({
+ component: 'Fetches',
+ quantity: example.fetches,
+ unitPrice: fetchPrice,
+ total: fetchCost,
+ unit: 'count',
+ });
+ }
+ }
+
+ // Signatures (per count)
+ if (example.signatures) {
+ const signaturePrice = getComponentPrice(
+ LitActionPriceComponent.signatures,
+ NodePriceMeasurement.perCount
+ );
+ if (signaturePrice !== null) {
+ const signatureCost = signaturePrice * example.signatures;
+ totalCost += signatureCost;
+ breakdown.push({
+ component: 'Signatures',
+ quantity: example.signatures,
+ unitPrice: signaturePrice,
+ total: signatureCost,
+ unit: 'count',
+ });
+ }
+ }
+
+ // Decrypts (per count)
+ if (example.decrypts) {
+ const decryptPrice = getComponentPrice(
+ LitActionPriceComponent.decrypts,
+ NodePriceMeasurement.perCount
+ );
+ if (decryptPrice !== null) {
+ const decryptCost = decryptPrice * example.decrypts;
+ totalCost += decryptCost;
+ breakdown.push({
+ component: 'Decrypts',
+ quantity: example.decrypts,
+ unitPrice: decryptPrice,
+ total: decryptCost,
+ unit: 'count',
+ });
+ }
+ }
+
+ return {
+ totalCost,
+ breakdown,
+ totalCostUSD: litKeyPriceUSD ? totalCost * litKeyPriceUSD : null,
+ };
+ };
+
+ const examples = [
+ {
+ title: 'Oracle Operation',
+ description: 'Fetches external data and signs the result',
+ runtimeSeconds: 10,
+ fetches: 1,
+ signatures: 1,
+ decrypts: 0,
+ },
+ {
+ title: 'Cross-Chain Swap',
+ description: 'Complex operation with multiple data fetches and signatures',
+ runtimeSeconds: 20,
+ fetches: 4,
+ signatures: 2,
+ decrypts: 0,
+ },
+ {
+ title: 'Verifiable Data Job',
+ description: 'Processes data and signs the result',
+ runtimeSeconds: 45,
+ fetches: 0,
+ signatures: 1,
+ decrypts: 0,
+ },
+ {
+ title: 'Secure API Key Usage',
+ description: 'Decrypts an API key and uses it in a fetch request',
+ runtimeSeconds: 5,
+ fetches: 1,
+ signatures: 0,
+ decrypts: 1,
+ },
+ ];
+
+ if (loading) {
+ return (
+
+
Loading price data...
+
+ );
+ }
+
+ if (error) {
+ return (
+
+
Error loading prices: {error}
+
+ );
+ }
+
+ return (
+
+ {litKeyPriceUSD && (
+
+ LITKEY Price: ${litKeyPriceUSD.toFixed(4)} USD
+
+ )}
+
+ {examples.map((example, idx) => {
+ const costData = calculateCost(example);
+ if (!costData) return null;
+
+ return (
+
+
+ {example.title}
+
+
+ {example.description}
+
+
+
+ Estimated Total Cost:{' '}
+
+ {formatPrice(costData.totalCost, costData.totalCostUSD)}
+
+
+
+
+
+
+
+ |
+ Component
+ |
+
+ Quantity
+ |
+
+ Unit Price
+ |
+
+ Total
+ |
+
+
+
+ {costData.breakdown.map((item, itemIdx) => (
+
+ |
+ {item.component}
+ |
+
+ {item.quantity} {item.unit || ''}
+ |
+
+ {formatPrice(item.unitPrice, litKeyPriceUSD ? item.unitPrice * litKeyPriceUSD : null)}
+ |
+
+ {formatPrice(item.total, litKeyPriceUSD ? item.total * litKeyPriceUSD : null)}
+ |
+
+ ))}
+
+ |
+ Total
+ |
+ |
+ |
+
+
+ {formatPrice(costData.totalCost, costData.totalCostUSD)}
+
+ |
+
+
+
+
+
+ );
+ })}
+
+ );
+};
+
diff --git a/docs/snippets/PriceProvider.jsx b/docs/snippets/PriceProvider.jsx
new file mode 100644
index 000000000..79b2d9d2b
--- /dev/null
+++ b/docs/snippets/PriceProvider.jsx
@@ -0,0 +1,275 @@
+import { useEffect, useState } from 'react';
+
+export const PriceProvider = ({ children, component: Component }) => {
+ // Constants - defined inside component for Mintlify compatibility
+ const NAGA_PROD_PRICE_FEED_ADDRESS = '0x88F5535Fa6dA5C225a3C06489fE4e3405b87608C';
+ const NAGA_PROD_PKP_ADDRESS = '0xaeEA5fE3654919c8Bb2b356aDCb5dF4eC082C168';
+ const RPC_URL = 'https://lit-chain-rpc.litprotocol.com/';
+
+ // Product IDs
+ const ProductId = {
+ PkpSign: 0,
+ EncSign: 1,
+ LitAction: 2,
+ SignSessionKey: 3,
+ };
+
+ // Product IDs array used for fetching prices
+ const PRODUCT_IDS = [
+ ProductId.PkpSign,
+ ProductId.EncSign,
+ ProductId.LitAction,
+ ProductId.SignSessionKey,
+ ];
+
+ // PriceFeed ABI (minimal - only functions we need)
+ const PRICE_FEED_ABI = [
+ {
+ inputs: [
+ {
+ internalType: 'uint256[]',
+ name: 'productIds',
+ type: 'uint256[]',
+ },
+ ],
+ name: 'baseNetworkPrices',
+ outputs: [
+ {
+ internalType: 'uint256[]',
+ name: '',
+ type: 'uint256[]',
+ },
+ ],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [
+ {
+ internalType: 'uint256[]',
+ name: 'productIds',
+ type: 'uint256[]',
+ },
+ ],
+ name: 'maxNetworkPrices',
+ outputs: [
+ {
+ internalType: 'uint256[]',
+ name: '',
+ type: 'uint256[]',
+ },
+ ],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [
+ {
+ internalType: 'uint256',
+ name: 'usagePercent',
+ type: 'uint256',
+ },
+ {
+ internalType: 'uint256[]',
+ name: 'productIds',
+ type: 'uint256[]',
+ },
+ ],
+ name: 'usagePercentToPrices',
+ outputs: [
+ {
+ internalType: 'uint256[]',
+ name: '',
+ type: 'uint256[]',
+ },
+ ],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ {
+ inputs: [],
+ name: 'getLitActionPriceConfigs',
+ outputs: [
+ {
+ components: [
+ {
+ internalType: 'enum LibPriceFeedStorage.LitActionPriceComponent',
+ name: 'priceComponent',
+ type: 'uint8',
+ },
+ {
+ internalType: 'enum LibPriceFeedStorage.NodePriceMeasurement',
+ name: 'priceMeasurement',
+ type: 'uint8',
+ },
+ {
+ internalType: 'uint256',
+ name: 'price',
+ type: 'uint256',
+ },
+ ],
+ internalType: 'struct LibPriceFeedStorage.LitActionPriceConfig[]',
+ name: '',
+ type: 'tuple[]',
+ },
+ ],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ ];
+
+ // PKP Contract ABI (for mintCost)
+ const PKP_ABI = [
+ {
+ inputs: [],
+ name: 'mintCost',
+ outputs: [
+ {
+ internalType: 'uint256',
+ name: '',
+ type: 'uint256',
+ },
+ ],
+ stateMutability: 'view',
+ type: 'function',
+ },
+ ];
+
+ // Helper function to get LITKEY price
+ const getLitKeyPrice = async () => {
+ try {
+ const response = await fetch(
+ 'https://api.coingecko.com/api/v3/simple/price?ids=lit-protocol&vs_currencies=usd'
+ );
+ const data = await response.json();
+
+ if (data['lit-protocol'] && data['lit-protocol'].usd) {
+ return data['lit-protocol'].usd;
+ }
+
+ throw new Error('LIT price not found in CoinGecko response');
+ } catch (error) {
+ console.error('Error fetching LITKEY price from CoinGecko:', error);
+ return null;
+ }
+ };
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+ const [basePrices, setBasePrices] = useState([]);
+ const [maxPrices, setMaxPrices] = useState([]);
+ const [currentPrices, setCurrentPrices] = useState([]);
+ const [litActionConfigs, setLitActionConfigs] = useState([]);
+ const [litKeyPriceUSD, setLitKeyPriceUSD] = useState(null);
+ const [usagePercent, setUsagePercent] = useState(null);
+ const [pkpMintCost, setPkpMintCost] = useState(null);
+ const [ethersLoaded, setEthersLoaded] = useState(false);
+
+ // Load ethers from CDN
+ useEffect(() => {
+ if (window.ethers) {
+ setEthersLoaded(true);
+ return;
+ }
+
+ const script = document.createElement('script');
+ script.src = 'https://cdn.jsdelivr.net/npm/ethers@5.7.2/dist/ethers.umd.min.js';
+ script.onload = () => {
+ setEthersLoaded(true);
+ };
+ script.onerror = () => {
+ const fallbackScript = document.createElement('script');
+ fallbackScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/ethers/5.7.2/ethers.umd.min.js';
+ fallbackScript.onload = () => {
+ setEthersLoaded(true);
+ };
+ fallbackScript.onerror = () => {
+ setError('Failed to load ethers library from CDN');
+ setLoading(false);
+ };
+ document.head.appendChild(fallbackScript);
+ };
+ document.head.appendChild(script);
+
+ return () => {
+ if (script.parentNode) {
+ script.parentNode.removeChild(script);
+ }
+ };
+ }, []);
+
+ useEffect(() => {
+ if (!ethersLoaded || !window.ethers) {
+ return;
+ }
+
+ async function fetchPrices() {
+ try {
+ setLoading(true);
+ setError(null);
+
+ const { ethers } = window;
+ const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
+ const contract = new ethers.Contract(NAGA_PROD_PRICE_FEED_ADDRESS, PRICE_FEED_ABI, provider);
+ const pkpContract = new ethers.Contract(NAGA_PROD_PKP_ADDRESS, PKP_ABI, provider);
+
+ const priceUSD = await getLitKeyPrice();
+ setLitKeyPriceUSD(priceUSD);
+
+ const basePricesResult = await contract.baseNetworkPrices(PRODUCT_IDS);
+ const maxPricesResult = await contract.maxNetworkPrices(PRODUCT_IDS);
+
+ const estimatedUsage = 50;
+ setUsagePercent(estimatedUsage);
+ const currentPricesResult = await contract.usagePercentToPrices(estimatedUsage, PRODUCT_IDS);
+
+ const litActionConfigsResult = await contract.getLitActionPriceConfigs();
+
+ // Fetch PKP minting cost (static price)
+ const mintCostResult = await pkpContract.mintCost();
+ setPkpMintCost(mintCostResult);
+
+ setBasePrices(basePricesResult);
+ setMaxPrices(maxPricesResult);
+ setCurrentPrices(currentPricesResult);
+ setLitActionConfigs(litActionConfigsResult);
+ } catch (err) {
+ console.error('Error fetching prices:', err);
+ setError(err.message || 'Failed to fetch prices');
+ } finally {
+ setLoading(false);
+ }
+ }
+
+ fetchPrices();
+ }, [ethersLoaded]);
+
+ const priceData = {
+ loading,
+ error,
+ basePrices,
+ maxPrices,
+ currentPrices,
+ litActionConfigs,
+ litKeyPriceUSD,
+ usagePercent,
+ pkpMintCost,
+ ethers: window.ethers,
+ };
+
+ // Render the component with price data as a prop
+ // Prefer component prop, fall back to children if provided
+ const ComponentToRender = Component || (children && typeof children === 'function' ? children : null);
+
+ if (!ComponentToRender) {
+ return null;
+ }
+
+ // Render the component with priceData prop
+ if (typeof ComponentToRender === 'function') {
+ return ;
+ }
+
+ // If children is a React element, try to render it (shouldn't happen with our usage pattern)
+ return children;
+};
+