From 03a2a2765ea0fbda3e17b3c9772d229766fe3809 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 13:45:52 -0800 Subject: [PATCH 01/32] first pass at more pricing info --- docs/docs.json | 7 + docs/learning-lit/pricing/current-prices.mdx | 47 ++ docs/learning-lit/pricing/payment-model.mdx | 57 ++ docs/snippets/CurrentPricesTable.jsx | 538 +++++++++++++++++++ 4 files changed, 649 insertions(+) create mode 100644 docs/learning-lit/pricing/current-prices.mdx create mode 100644 docs/learning-lit/pricing/payment-model.mdx create mode 100644 docs/snippets/CurrentPricesTable.jsx diff --git a/docs/docs.json b/docs/docs.json index ab6128b2b..27b02ab1d 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -27,6 +27,13 @@ "learning-lit/backup-and-recovery", "learning-lit/threshold-cryptography" ] + }, + { + "group": "Pricing", + "pages": [ + "learning-lit/pricing/payment-model", + "learning-lit/pricing/current-prices" + ] } ] }, diff --git a/docs/learning-lit/pricing/current-prices.mdx b/docs/learning-lit/pricing/current-prices.mdx new file mode 100644 index 000000000..cdd485f0d --- /dev/null +++ b/docs/learning-lit/pricing/current-prices.mdx @@ -0,0 +1,47 @@ +--- +title: "Current Prices" +--- + +The following table shows the current pricing for Lit Protocol services on the **naga-prod** network. Prices are displayed in both $LITKEY tokens and USD (based on current market rates). + + +Prices update dynamically based on network usage. The values shown below reflect real-time prices fetched from the blockchain. + + +import { CurrentPricesTable } from '../../snippets/CurrentPricesTable'; + + + +## 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 +- **Encrypted Sign**: Signing with encrypted keys +- **Lit Action**: Executing serverless JavaScript functions (pricing varies by component) +- **Sign Session Key**: Session-based signing operations + +### 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/payment-model.mdx b/docs/learning-lit/pricing/payment-model.mdx new file mode 100644 index 000000000..a1607d989 --- /dev/null +++ b/docs/learning-lit/pricing/payment-model.mdx @@ -0,0 +1,57 @@ +--- +title: "Payment Model" +--- + +Lit Protocol uses a token-based payment system to ensure the decentralized network can sustain itself and compensate node operators for providing cryptographic services. + +## How Payment Works + +### 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 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) +- Sustainable compensation for node operators + +### Pricing in $LITKEY Tokens + +All services on Lit Protocol are priced in **$LITKEY tokens**, the native token of Lit Chain. When you use network services such as: + +- **PKP Signing**: Generating signatures with your Programmable Key Pair +- **Encrypted Signing**: Signing with encrypted keys +- **Lit Actions**: Executing serverless JavaScript functions +- **Sign Session Key**: Session-based signing operations + +The network automatically deducts the appropriate amount of $LITKEY 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 tokens** - Get tokens 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. + diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx new file mode 100644 index 000000000..e7aba1f28 --- /dev/null +++ b/docs/snippets/CurrentPricesTable.jsx @@ -0,0 +1,538 @@ +import { useEffect, useState } from 'react'; +import { createPublicClient, http, formatUnits } from 'viem'; + +// Naga Prod PriceFeed contract address +const NAGA_PROD_PRICE_FEED_ADDRESS = '0x88F5535Fa6dA5C225a3C06489fE4e3405b87608C'; + +// Lit Chain configuration +const LIT_CHAIN = { + id: 175200, + name: 'Lit Chain', + network: 'lit-chain', + nativeCurrency: { + name: 'Lit Chain', + symbol: 'LITKEY', + decimals: 18, + }, + rpcUrls: { + default: { + http: ['https://lit-chain-rpc.litprotocol.com/'], + }, + public: { + http: ['https://lit-chain-rpc.litprotocol.com/'], + }, + }, + blockExplorers: { + default: { + name: 'Lit Chain Explorer', + url: 'https://lit-chain-explorer.litprotocol.com/', + }, + }, +}; + +// Product IDs +const ProductId = { + PkpSign: 0, + EncSign: 1, + LitAction: 2, + SignSessionKey: 3, +}; + +// LitActionPriceComponent enum values +const 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 +const NodePriceMeasurement = { + perSecond: 0, + perMegabyte: 1, + perCount: 2, +}; + +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', +}; + +// 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', + }, +]; + +/** + * Get LITKEY token price in USD from CoinGecko + */ +async function getLitKeyPrice() { + 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; // Return null if we can't fetch price + } +} + +/** + * Convert wei to LITKEY tokens (18 decimals) + */ +function weiToTokens(wei) { + return Number(formatUnits(wei, 18)); +} + +/** + * Format price for display + */ +function formatPrice(priceInTokens, priceInUSD) { + if (priceInUSD === null) { + return `${priceInTokens.toFixed(6)} LITKEY`; + } + return `${priceInTokens.toFixed(6)} LITKEY ($${priceInUSD.toFixed(6)})`; +} + +export function CurrentPricesTable() { + 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); + + useEffect(() => { + async function fetchPrices() { + try { + setLoading(true); + setError(null); + + // Create public client + const publicClient = createPublicClient({ + chain: LIT_CHAIN, + transport: http(LIT_CHAIN.rpcUrls.default.http[0]), + }); + + // Get LITKEY price in USD + const priceUSD = await getLitKeyPrice(); + setLitKeyPriceUSD(priceUSD); + + // Get product IDs + const productIds = [ + ProductId.PkpSign, + ProductId.EncSign, + ProductId.LitAction, + ProductId.SignSessionKey, + ]; + + // Fetch base prices + const basePricesResult = await publicClient.readContract({ + address: NAGA_PROD_PRICE_FEED_ADDRESS, + abi: PRICE_FEED_ABI, + functionName: 'baseNetworkPrices', + args: [productIds], + }); + + // Fetch max prices + const maxPricesResult = await publicClient.readContract({ + address: NAGA_PROD_PRICE_FEED_ADDRESS, + abi: PRICE_FEED_ABI, + functionName: 'maxNetworkPrices', + args: [productIds], + }); + + // Fetch current prices (we'll estimate at 50% usage for now) + // In a real implementation, you might want to fetch actual usage from the contract + const estimatedUsage = 50; + setUsagePercent(estimatedUsage); + const currentPricesResult = await publicClient.readContract({ + address: NAGA_PROD_PRICE_FEED_ADDRESS, + abi: PRICE_FEED_ABI, + functionName: 'usagePercentToPrices', + args: [estimatedUsage, productIds], + }); + + // Fetch LitAction price configs + const litActionConfigsResult = await publicClient.readContract({ + address: NAGA_PROD_PRICE_FEED_ADDRESS, + abi: PRICE_FEED_ABI, + functionName: 'getLitActionPriceConfigs', + }); + + 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(); + }, []); + + if (loading) { + return ( +
+

Loading current prices from blockchain...

+
+ ); + } + + if (error) { + return ( +
+

Error loading prices: {error}

+

+ Please ensure you have an internet connection and try refreshing the page. +

+
+ ); + } + + const productIds = [ + ProductId.PkpSign, + ProductId.EncSign, + ProductId.LitAction, + ProductId.SignSessionKey, + ]; + + return ( +
+ {litKeyPriceUSD && ( +

+ LITKEY Price: ${litKeyPriceUSD.toFixed(4)} USD + {usagePercent !== null && ( + + Estimated Network Usage: {usagePercent}% + + )} +

+ )} + +
+ + + + + + + + + + + {productIds.map((productId, index) => { + const basePriceInTokens = weiToTokens(basePrices[index]); + const maxPriceInTokens = weiToTokens(maxPrices[index]); + const currentPriceInTokens = weiToTokens(currentPrices[index]); + const basePriceInUSD = litKeyPriceUSD + ? basePriceInTokens * litKeyPriceUSD + : null; + const maxPriceInUSD = litKeyPriceUSD + ? maxPriceInTokens * litKeyPriceUSD + : null; + const currentPriceInUSD = litKeyPriceUSD + ? currentPriceInTokens * litKeyPriceUSD + : null; + + return ( + + + + + + + ); + })} + +
+ Product + + Base Price + + Max Price + + Current Price +
+ {PRODUCT_NAMES[productId]} + + {formatPrice(basePriceInTokens, basePriceInUSD)} + + {formatPrice(maxPriceInTokens, maxPriceInUSD)} + + {formatPrice(currentPriceInTokens, currentPriceInUSD)} +
+
+ +

+ Lit Action Price Components +

+
+ + + + + + + + + {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); + const priceInUSD = litKeyPriceUSD + ? priceInTokens * litKeyPriceUSD + : null; + + return ( + + + + + ); + })} + +
+ Component + + Price +
+ {componentName} + {measurementName && ( + + {measurementName} + + )} + + {formatPrice(priceInTokens, priceInUSD)} +
+
+
+ ); +} + From e6a86a6f13be0d8e4058d1549d3e1b754d89c635 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 13:51:01 -0800 Subject: [PATCH 02/32] link to getting litkey page --- docs/learning-lit/pricing/payment-model.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/learning-lit/pricing/payment-model.mdx b/docs/learning-lit/pricing/payment-model.mdx index a1607d989..68ee70ddc 100644 --- a/docs/learning-lit/pricing/payment-model.mdx +++ b/docs/learning-lit/pricing/payment-model.mdx @@ -48,7 +48,7 @@ If your balance is insufficient, the request will fail. You can check your balan To start using Lit Protocol's paid services: -1. **Acquire $LITKEY tokens** - Get tokens from exchanges or other sources +1. **Acquire $LITKEY tokens** - Get tokens from exchanges or other sources (see [Getting $LITKEY](/governance/litkey/getting-litkey)) 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 From 7a9ce0a717dcebb2a8c5c0b87dd031b276fbbaf8 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 13:52:38 -0800 Subject: [PATCH 03/32] cleanup --- docs/snippets/CurrentPricesTable.jsx | 36 +++++++++++----------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index e7aba1f28..92380ad3c 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -38,6 +38,14 @@ const ProductId = { SignSessionKey: 3, }; +// Product IDs array used for fetching prices +const PRODUCT_IDS = [ + ProductId.PkpSign, + ProductId.EncSign, + ProductId.LitAction, + ProductId.SignSessionKey, +]; + // LitActionPriceComponent enum values const LitActionPriceComponent = { baseAmount: 0, @@ -247,20 +255,12 @@ export function CurrentPricesTable() { const priceUSD = await getLitKeyPrice(); setLitKeyPriceUSD(priceUSD); - // Get product IDs - const productIds = [ - ProductId.PkpSign, - ProductId.EncSign, - ProductId.LitAction, - ProductId.SignSessionKey, - ]; - // Fetch base prices const basePricesResult = await publicClient.readContract({ address: NAGA_PROD_PRICE_FEED_ADDRESS, abi: PRICE_FEED_ABI, functionName: 'baseNetworkPrices', - args: [productIds], + args: [PRODUCT_IDS], }); // Fetch max prices @@ -268,7 +268,7 @@ export function CurrentPricesTable() { address: NAGA_PROD_PRICE_FEED_ADDRESS, abi: PRICE_FEED_ABI, functionName: 'maxNetworkPrices', - args: [productIds], + args: [PRODUCT_IDS], }); // Fetch current prices (we'll estimate at 50% usage for now) @@ -279,7 +279,7 @@ export function CurrentPricesTable() { address: NAGA_PROD_PRICE_FEED_ADDRESS, abi: PRICE_FEED_ABI, functionName: 'usagePercentToPrices', - args: [estimatedUsage, productIds], + args: [estimatedUsage, PRODUCT_IDS], }); // Fetch LitAction price configs @@ -317,19 +317,12 @@ export function CurrentPricesTable() {

Error loading prices: {error}

- Please ensure you have an internet connection and try refreshing the page. + Unable to fetch pricing data. Please check your connection or try again later.

); } - const productIds = [ - ProductId.PkpSign, - ProductId.EncSign, - ProductId.LitAction, - ProductId.SignSessionKey, - ]; - return (
{litKeyPriceUSD && ( @@ -392,7 +385,7 @@ export function CurrentPricesTable() { - {productIds.map((productId, index) => { + {PRODUCT_IDS.map((productId, index) => { const basePriceInTokens = weiToTokens(basePrices[index]); const maxPriceInTokens = weiToTokens(maxPrices[index]); const currentPriceInTokens = weiToTokens(currentPrices[index]); @@ -534,5 +527,4 @@ export function CurrentPricesTable() {
); -} - +} \ No newline at end of file From 38503cffae62ac7425582306993412bba950ecee Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 13:53:23 -0800 Subject: [PATCH 04/32] import react --- docs/snippets/CurrentPricesTable.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 92380ad3c..44f6daf3c 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useState, React } from 'react'; import { createPublicClient, http, formatUnits } from 'viem'; // Naga Prod PriceFeed contract address From e36bb205c3bd8e73345d0ac45d6f39c10887a1cb Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 13:53:54 -0800 Subject: [PATCH 05/32] naming fix --- docs/snippets/CurrentPricesTable.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 44f6daf3c..eb354a042 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -10,7 +10,7 @@ const LIT_CHAIN = { name: 'Lit Chain', network: 'lit-chain', nativeCurrency: { - name: 'Lit Chain', + name: 'Lit Protocol', symbol: 'LITKEY', decimals: 18, }, From 9eab07fea2c06233cd6262cab633095a8ba37863 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 13:58:38 -0800 Subject: [PATCH 06/32] fix component import --- docs/learning-lit/pricing/current-prices.mdx | 3 +-- docs/learning-lit/pricing/payment-model.mdx | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/learning-lit/pricing/current-prices.mdx b/docs/learning-lit/pricing/current-prices.mdx index cdd485f0d..1cbfd4e94 100644 --- a/docs/learning-lit/pricing/current-prices.mdx +++ b/docs/learning-lit/pricing/current-prices.mdx @@ -1,6 +1,7 @@ --- title: "Current Prices" --- +import { CurrentPricesTable } from '../../snippets/CurrentPricesTable'; The following table shows the current pricing for Lit Protocol services on the **naga-prod** network. Prices are displayed in both $LITKEY tokens and USD (based on current market rates). @@ -8,8 +9,6 @@ The following table shows the current pricing for Lit Protocol services on the * Prices update dynamically based on network usage. The values shown below reflect real-time prices fetched from the blockchain. -import { CurrentPricesTable } from '../../snippets/CurrentPricesTable'; - ## Understanding the Price Table diff --git a/docs/learning-lit/pricing/payment-model.mdx b/docs/learning-lit/pricing/payment-model.mdx index 68ee70ddc..06b027043 100644 --- a/docs/learning-lit/pricing/payment-model.mdx +++ b/docs/learning-lit/pricing/payment-model.mdx @@ -48,7 +48,7 @@ If your balance is insufficient, the request will fail. You can check your balan To start using Lit Protocol's paid services: -1. **Acquire $LITKEY tokens** - Get tokens from exchanges or other sources (see [Getting $LITKEY](/governance/litkey/getting-litkey)) +1. **Acquire $LITKEY 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 From 5b85266f4566ea95b0dd74bd48ef6037e01acbb1 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 14:06:27 -0800 Subject: [PATCH 07/32] trying to fix current prices table component --- docs/learning-lit/pricing/current-prices.mdx | 2 +- docs/snippets/CurrentPricesTable.jsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/learning-lit/pricing/current-prices.mdx b/docs/learning-lit/pricing/current-prices.mdx index 1cbfd4e94..fe846bfe6 100644 --- a/docs/learning-lit/pricing/current-prices.mdx +++ b/docs/learning-lit/pricing/current-prices.mdx @@ -1,7 +1,7 @@ --- title: "Current Prices" --- -import { CurrentPricesTable } from '../../snippets/CurrentPricesTable'; +import { CurrentPricesTable } from "/snippets/CurrentPricesTable.jsx"; The following table shows the current pricing for Lit Protocol services on the **naga-prod** network. Prices are displayed in both $LITKEY tokens and USD (based on current market rates). diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index eb354a042..365ab6a98 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -1,4 +1,4 @@ -import { useEffect, useState, React } from 'react'; +import { useEffect, useState } from 'react'; import { createPublicClient, http, formatUnits } from 'viem'; // Naga Prod PriceFeed contract address @@ -229,7 +229,7 @@ function formatPrice(priceInTokens, priceInUSD) { return `${priceInTokens.toFixed(6)} LITKEY ($${priceInUSD.toFixed(6)})`; } -export function CurrentPricesTable() { +export const CurrentPricesTable = () => { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [basePrices, setBasePrices] = useState([]); From b39bec582fa47199619c9a9f875df5c436a70456 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 14:18:18 -0800 Subject: [PATCH 08/32] trying to import viem from cdn --- docs/snippets/CurrentPricesTable.jsx | 46 +++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 365ab6a98..00d8e98b5 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -1,5 +1,4 @@ import { useEffect, useState } from 'react'; -import { createPublicClient, http, formatUnits } from 'viem'; // Naga Prod PriceFeed contract address const NAGA_PROD_PRICE_FEED_ADDRESS = '0x88F5535Fa6dA5C225a3C06489fE4e3405b87608C'; @@ -215,8 +214,12 @@ async function getLitKeyPrice() { /** * Convert wei to LITKEY tokens (18 decimals) */ -function weiToTokens(wei) { - return Number(formatUnits(wei, 18)); +function weiToTokens(wei, viem) { + if (!viem || !viem.formatUnits) { + // Fallback if viem isn't loaded yet + return Number(wei) / 1e18; + } + return Number(viem.formatUnits(wei, 18)); } /** @@ -238,13 +241,40 @@ export const CurrentPricesTable = () => { const [litActionConfigs, setLitActionConfigs] = useState([]); const [litKeyPriceUSD, setLitKeyPriceUSD] = useState(null); const [usagePercent, setUsagePercent] = useState(null); + const [viemLoaded, setViemLoaded] = useState(false); + + // Load viem from CDN + useEffect(() => { + // Check if viem is already loaded + if (window.viem) { + setViemLoaded(true); + return; + } + + // Load viem from esm.sh CDN (supports ES modules) + import('https://esm.sh/viem@2.38.3').then((viemModule) => { + window.viem = viemModule; + setViemLoaded(true); + }).catch((err) => { + console.error('Error loading viem:', err); + setError('Failed to load viem library from CDN'); + setLoading(false); + }); + }, []); useEffect(() => { + if (!viemLoaded || !window.viem) { + return; + } + async function fetchPrices() { try { setLoading(true); setError(null); + const viem = window.viem; + const { createPublicClient, http } = viem; + // Create public client const publicClient = createPublicClient({ chain: LIT_CHAIN, @@ -302,7 +332,7 @@ export const CurrentPricesTable = () => { } fetchPrices(); - }, []); + }, [viemLoaded]); if (loading) { return ( @@ -386,9 +416,9 @@ export const CurrentPricesTable = () => { {PRODUCT_IDS.map((productId, index) => { - const basePriceInTokens = weiToTokens(basePrices[index]); - const maxPriceInTokens = weiToTokens(maxPrices[index]); - const currentPriceInTokens = weiToTokens(currentPrices[index]); + const basePriceInTokens = weiToTokens(basePrices[index], window.viem); + const maxPriceInTokens = weiToTokens(maxPrices[index], window.viem); + const currentPriceInTokens = weiToTokens(currentPrices[index], window.viem); const basePriceInUSD = litKeyPriceUSD ? basePriceInTokens * litKeyPriceUSD : null; @@ -489,7 +519,7 @@ export const CurrentPricesTable = () => { `Component ${priceComponentNum}`; const measurementName = MEASUREMENT_NAMES[priceMeasurementNum] || ''; - const priceInTokens = weiToTokens(config.price); + const priceInTokens = weiToTokens(config.price, window.viem); const priceInUSD = litKeyPriceUSD ? priceInTokens * litKeyPriceUSD : null; From c3b0654383e51e509ff8b3bfaab609e75f41196d Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 14:24:49 -0800 Subject: [PATCH 09/32] trying ethers --- docs/snippets/CurrentPricesTable.jsx | 99 ++++++++++++---------------- 1 file changed, 43 insertions(+), 56 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 00d8e98b5..297d338dc 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -212,14 +212,15 @@ async function getLitKeyPrice() { } /** - * Convert wei to LITKEY tokens (18 decimals) + * Convert wei to LITKEY tokens (18 decimals) using ethers */ -function weiToTokens(wei, viem) { - if (!viem || !viem.formatUnits) { - // Fallback if viem isn't loaded yet - return Number(wei) / 1e18; +function weiToTokens(wei, ethers) { + if (!ethers || !ethers.utils) { + // Fallback if ethers isn't loaded yet + return 0; } - return Number(viem.formatUnits(wei, 18)); + // Use ethers' formatUnits which handles BigNumber conversion safely + return parseFloat(ethers.utils.formatUnits(wei, 18)); } /** @@ -232,6 +233,7 @@ function formatPrice(priceInTokens, priceInUSD) { return `${priceInTokens.toFixed(6)} LITKEY ($${priceInUSD.toFixed(6)})`; } + export const CurrentPricesTable = () => { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -241,29 +243,37 @@ export const CurrentPricesTable = () => { const [litActionConfigs, setLitActionConfigs] = useState([]); const [litKeyPriceUSD, setLitKeyPriceUSD] = useState(null); const [usagePercent, setUsagePercent] = useState(null); - const [viemLoaded, setViemLoaded] = useState(false); + const [ethersLoaded, setEthersLoaded] = useState(false); - // Load viem from CDN + // Load ethers from CDN useEffect(() => { - // Check if viem is already loaded - if (window.viem) { - setViemLoaded(true); + // Check if ethers is already loaded + if (window.ethers) { + setEthersLoaded(true); return; } - // Load viem from esm.sh CDN (supports ES modules) - import('https://esm.sh/viem@2.38.3').then((viemModule) => { - window.viem = viemModule; - setViemLoaded(true); - }).catch((err) => { - console.error('Error loading viem:', err); - setError('Failed to load viem library from CDN'); + // Load ethers from CDN + const script = document.createElement('script'); + script.src = 'https://cdn.ethers.io/lib/ethers-5.7.umd.min.js'; + script.onload = () => { + setEthersLoaded(true); + }; + script.onerror = () => { + setError('Failed to load ethers library from CDN'); setLoading(false); - }); + }; + document.head.appendChild(script); + + return () => { + if (script.parentNode) { + script.parentNode.removeChild(script); + } + }; }, []); useEffect(() => { - if (!viemLoaded || !window.viem) { + if (!ethersLoaded || !window.ethers) { return; } @@ -272,52 +282,29 @@ export const CurrentPricesTable = () => { setLoading(true); setError(null); - const viem = window.viem; - const { createPublicClient, http } = viem; - - // Create public client - const publicClient = createPublicClient({ - chain: LIT_CHAIN, - transport: http(LIT_CHAIN.rpcUrls.default.http[0]), - }); + const { ethers } = window; + const rpcUrl = LIT_CHAIN.rpcUrls.default.http[0]; + const provider = new ethers.providers.JsonRpcProvider(rpcUrl); + const contract = new ethers.Contract(NAGA_PROD_PRICE_FEED_ADDRESS, PRICE_FEED_ABI, provider); // Get LITKEY price in USD const priceUSD = await getLitKeyPrice(); setLitKeyPriceUSD(priceUSD); // Fetch base prices - const basePricesResult = await publicClient.readContract({ - address: NAGA_PROD_PRICE_FEED_ADDRESS, - abi: PRICE_FEED_ABI, - functionName: 'baseNetworkPrices', - args: [PRODUCT_IDS], - }); + const basePricesResult = await contract.baseNetworkPrices(PRODUCT_IDS); // Fetch max prices - const maxPricesResult = await publicClient.readContract({ - address: NAGA_PROD_PRICE_FEED_ADDRESS, - abi: PRICE_FEED_ABI, - functionName: 'maxNetworkPrices', - args: [PRODUCT_IDS], - }); + const maxPricesResult = await contract.maxNetworkPrices(PRODUCT_IDS); // Fetch current prices (we'll estimate at 50% usage for now) // In a real implementation, you might want to fetch actual usage from the contract const estimatedUsage = 50; setUsagePercent(estimatedUsage); - const currentPricesResult = await publicClient.readContract({ - address: NAGA_PROD_PRICE_FEED_ADDRESS, - abi: PRICE_FEED_ABI, - functionName: 'usagePercentToPrices', - args: [estimatedUsage, PRODUCT_IDS], - }); + const currentPricesResult = await contract.usagePercentToPrices(estimatedUsage, PRODUCT_IDS); // Fetch LitAction price configs - const litActionConfigsResult = await publicClient.readContract({ - address: NAGA_PROD_PRICE_FEED_ADDRESS, - abi: PRICE_FEED_ABI, - functionName: 'getLitActionPriceConfigs', - }); + const litActionConfigsResult = await contract.getLitActionPriceConfigs(); setBasePrices(basePricesResult); setMaxPrices(maxPricesResult); @@ -332,7 +319,7 @@ export const CurrentPricesTable = () => { } fetchPrices(); - }, [viemLoaded]); + }, [ethersLoaded]); if (loading) { return ( @@ -416,9 +403,9 @@ export const CurrentPricesTable = () => { {PRODUCT_IDS.map((productId, index) => { - const basePriceInTokens = weiToTokens(basePrices[index], window.viem); - const maxPriceInTokens = weiToTokens(maxPrices[index], window.viem); - const currentPriceInTokens = weiToTokens(currentPrices[index], window.viem); + const basePriceInTokens = weiToTokens(basePrices[index], window.ethers); + const maxPriceInTokens = weiToTokens(maxPrices[index], window.ethers); + const currentPriceInTokens = weiToTokens(currentPrices[index], window.ethers); const basePriceInUSD = litKeyPriceUSD ? basePriceInTokens * litKeyPriceUSD : null; @@ -519,7 +506,7 @@ export const CurrentPricesTable = () => { `Component ${priceComponentNum}`; const measurementName = MEASUREMENT_NAMES[priceMeasurementNum] || ''; - const priceInTokens = weiToTokens(config.price, window.viem); + const priceInTokens = weiToTokens(config.price, window.ethers); const priceInUSD = litKeyPriceUSD ? priceInTokens * litKeyPriceUSD : null; From 0654041bfb748544c6ddd093bfd585085cf85e38 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 14:29:09 -0800 Subject: [PATCH 10/32] ethers cdn not working - trying jsdelivr --- docs/snippets/CurrentPricesTable.jsx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 297d338dc..cfb107096 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -253,15 +253,25 @@ export const CurrentPricesTable = () => { return; } - // Load ethers from CDN + // Load ethers from jsdelivr CDN (fallback to cdnjs if needed) const script = document.createElement('script'); - script.src = 'https://cdn.ethers.io/lib/ethers-5.7.umd.min.js'; + // Try jsdelivr first + script.src = 'https://cdn.jsdelivr.net/npm/ethers@5.7.2/dist/ethers.umd.min.js'; script.onload = () => { setEthersLoaded(true); }; script.onerror = () => { - setError('Failed to load ethers library from CDN'); - setLoading(false); + // Fallback to cdnjs if jsdelivr fails + 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); From 3f89eb3fcc7554e5daa83c3826644ca8668e7ce9 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 14:57:11 -0800 Subject: [PATCH 11/32] fix lit_chain import --- docs/snippets/CurrentPricesTable.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index cfb107096..5051a028e 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -293,7 +293,7 @@ export const CurrentPricesTable = () => { setError(null); const { ethers } = window; - const rpcUrl = LIT_CHAIN.rpcUrls.default.http[0]; + const rpcUrl = 'https://lit-chain-rpc.litprotocol.com/'; const provider = new ethers.providers.JsonRpcProvider(rpcUrl); const contract = new ethers.Contract(NAGA_PROD_PRICE_FEED_ADDRESS, PRICE_FEED_ABI, provider); From 0417ecd5cd7e2258685dda8594d72a4066ad665f Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 15:03:50 -0800 Subject: [PATCH 12/32] move everything into component --- docs/snippets/CurrentPricesTable.jsx | 434 ++++++++++++--------------- 1 file changed, 193 insertions(+), 241 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 5051a028e..e972c31c2 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -1,240 +1,204 @@ import { useEffect, useState } from 'react'; -// Naga Prod PriceFeed contract address -const NAGA_PROD_PRICE_FEED_ADDRESS = '0x88F5535Fa6dA5C225a3C06489fE4e3405b87608C'; - -// Lit Chain configuration -const LIT_CHAIN = { - id: 175200, - name: 'Lit Chain', - network: 'lit-chain', - nativeCurrency: { - name: 'Lit Protocol', - symbol: 'LITKEY', - decimals: 18, - }, - rpcUrls: { - default: { - http: ['https://lit-chain-rpc.litprotocol.com/'], +export const CurrentPricesTable = () => { + // Constants - defined inside component for Mintlify compatibility + const NAGA_PROD_PRICE_FEED_ADDRESS = '0x88F5535Fa6dA5C225a3C06489fE4e3405b87608C'; + 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, + ]; + + // LitActionPriceComponent enum values + const 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 + const NodePriceMeasurement = { + perSecond: 0, + perMegabyte: 1, + perCount: 2, + }; + + 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', + }; + + // 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', }, - public: { - http: ['https://lit-chain-rpc.litprotocol.com/'], + { + inputs: [ + { + internalType: 'uint256[]', + name: 'productIds', + type: 'uint256[]', + }, + ], + name: 'maxNetworkPrices', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', }, - }, - blockExplorers: { - default: { - name: 'Lit Chain Explorer', - url: 'https://lit-chain-explorer.litprotocol.com/', + { + 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', }, - }, -}; - -// 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, -]; - -// LitActionPriceComponent enum values -const 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 -const NodePriceMeasurement = { - perSecond: 0, - perMegabyte: 1, - perCount: 2, -}; - -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', -}; - -// 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', - }, -]; - -/** - * Get LITKEY token price in USD from CoinGecko - */ -async function getLitKeyPrice() { - try { - const response = await fetch( - 'https://api.coingecko.com/api/v3/simple/price?ids=lit-protocol&vs_currencies=usd' - ); - const data = await response.json(); + { + 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', + }, + ]; + + // Helper functions + 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; + } - 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; } + }; - throw new Error('LIT price not found in CoinGecko response'); - } catch (error) { - console.error('Error fetching LITKEY price from CoinGecko:', error); - return null; // Return null if we can't fetch price - } -} - -/** - * Convert wei to LITKEY tokens (18 decimals) using ethers - */ -function weiToTokens(wei, ethers) { - if (!ethers || !ethers.utils) { - // Fallback if ethers isn't loaded yet - return 0; - } - // Use ethers' formatUnits which handles BigNumber conversion safely - return parseFloat(ethers.utils.formatUnits(wei, 18)); -} - -/** - * Format price for display - */ -function formatPrice(priceInTokens, priceInUSD) { - if (priceInUSD === null) { - return `${priceInTokens.toFixed(6)} LITKEY`; - } - return `${priceInTokens.toFixed(6)} LITKEY ($${priceInUSD.toFixed(6)})`; -} + const weiToTokens = (wei, ethers) => { + if (!ethers || !ethers.utils) { + return 0; + } + return parseFloat(ethers.utils.formatUnits(wei, 18)); + }; + const formatPrice = (priceInTokens, priceInUSD) => { + if (priceInUSD === null) { + return `${priceInTokens.toFixed(6)} LITKEY`; + } + return `${priceInTokens.toFixed(6)} LITKEY ($${priceInUSD.toFixed(6)})`; + }; -export const CurrentPricesTable = () => { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [basePrices, setBasePrices] = useState([]); @@ -247,21 +211,17 @@ export const CurrentPricesTable = () => { // Load ethers from CDN useEffect(() => { - // Check if ethers is already loaded if (window.ethers) { setEthersLoaded(true); return; } - // Load ethers from jsdelivr CDN (fallback to cdnjs if needed) const script = document.createElement('script'); - // Try jsdelivr first script.src = 'https://cdn.jsdelivr.net/npm/ethers@5.7.2/dist/ethers.umd.min.js'; script.onload = () => { setEthersLoaded(true); }; script.onerror = () => { - // Fallback to cdnjs if jsdelivr fails const fallbackScript = document.createElement('script'); fallbackScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/ethers/5.7.2/ethers.umd.min.js'; fallbackScript.onload = () => { @@ -293,27 +253,19 @@ export const CurrentPricesTable = () => { setError(null); const { ethers } = window; - const rpcUrl = 'https://lit-chain-rpc.litprotocol.com/'; - const provider = new ethers.providers.JsonRpcProvider(rpcUrl); + const provider = new ethers.providers.JsonRpcProvider(RPC_URL); const contract = new ethers.Contract(NAGA_PROD_PRICE_FEED_ADDRESS, PRICE_FEED_ABI, provider); - // Get LITKEY price in USD const priceUSD = await getLitKeyPrice(); setLitKeyPriceUSD(priceUSD); - // Fetch base prices const basePricesResult = await contract.baseNetworkPrices(PRODUCT_IDS); - - // Fetch max prices const maxPricesResult = await contract.maxNetworkPrices(PRODUCT_IDS); - // Fetch current prices (we'll estimate at 50% usage for now) - // In a real implementation, you might want to fetch actual usage from the contract const estimatedUsage = 50; setUsagePercent(estimatedUsage); const currentPricesResult = await contract.usagePercentToPrices(estimatedUsage, PRODUCT_IDS); - // Fetch LitAction price configs const litActionConfigsResult = await contract.getLitActionPriceConfigs(); setBasePrices(basePricesResult); @@ -554,4 +506,4 @@ export const CurrentPricesTable = () => { ); -} \ No newline at end of file +}; From 286725e3b417660bc15661a3e506768dbe9cbf9c Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 15:17:35 -0800 Subject: [PATCH 13/32] fix table width --- docs/snippets/CurrentPricesTable.jsx | 40 +++++++++++++++++++--------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index e972c31c2..3681c0819 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -319,44 +319,50 @@ export const CurrentPricesTable = () => {
Product Base Price Max Price Current Price @@ -382,40 +388,44 @@ export const CurrentPricesTable = () => {
{PRODUCT_NAMES[productId]} {formatPrice(basePriceInTokens, basePriceInUSD)} {formatPrice(maxPriceInTokens, maxPriceInUSD)} {formatPrice(currentPriceInTokens, currentPriceInUSD)} @@ -434,25 +444,29 @@ export const CurrentPricesTable = () => { - + - + - + ))} - +
Component Price @@ -477,8 +491,9 @@ export const CurrentPricesTable = () => {
{componentName} @@ -490,10 +505,11 @@ export const CurrentPricesTable = () => { {formatPrice(priceInTokens, priceInUSD)} From 17bbd3ea5cd1f8329f433c968ef035b989a85978 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 15:39:47 -0800 Subject: [PATCH 14/32] table width fix round 2 --- docs/snippets/CurrentPricesTable.jsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 3681c0819..7fd4c24fa 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -303,7 +303,7 @@ export const CurrentPricesTable = () => { } return ( -
+
{litKeyPriceUSD && (

LITKEY Price: ${litKeyPriceUSD.toFixed(4)} USD @@ -315,13 +315,15 @@ export const CurrentPricesTable = () => {

)} -
+
@@ -329,7 +331,7 @@ export const CurrentPricesTable = () => { {PRODUCT_IDS.map((productId, index) => { - const basePriceInTokens = weiToTokens(basePrices[index], window.ethers); - const maxPriceInTokens = weiToTokens(maxPrices[index], window.ethers); - const currentPriceInTokens = weiToTokens(currentPrices[index], window.ethers); + const basePriceInTokens = weiToTokens(basePrices[index], ethers); + const maxPriceInTokens = weiToTokens(maxPrices[index], ethers); + const currentPriceInTokens = weiToTokens(currentPrices[index], ethers); const basePriceInUSD = litKeyPriceUSD ? basePriceInTokens * litKeyPriceUSD : null; @@ -492,9 +242,9 @@ export const CurrentPricesTable = () => { }} > {formatPrice( - weiToTokens(pkpMintCost, window.ethers), + weiToTokens(pkpMintCost, ethers), litKeyPriceUSD - ? weiToTokens(pkpMintCost, window.ethers) * litKeyPriceUSD + ? weiToTokens(pkpMintCost, ethers) * litKeyPriceUSD : null )} @@ -508,9 +258,9 @@ export const CurrentPricesTable = () => { }} > {formatPrice( - weiToTokens(pkpMintCost, window.ethers), + weiToTokens(pkpMintCost, ethers), litKeyPriceUSD - ? weiToTokens(pkpMintCost, window.ethers) * litKeyPriceUSD + ? weiToTokens(pkpMintCost, ethers) * litKeyPriceUSD : null )} @@ -524,9 +274,9 @@ export const CurrentPricesTable = () => { }} > {formatPrice( - weiToTokens(pkpMintCost, window.ethers), + weiToTokens(pkpMintCost, ethers), litKeyPriceUSD - ? weiToTokens(pkpMintCost, window.ethers) * litKeyPriceUSD + ? weiToTokens(pkpMintCost, ethers) * litKeyPriceUSD : null )} @@ -583,7 +333,7 @@ export const CurrentPricesTable = () => { `Component ${priceComponentNum}`; const measurementName = MEASUREMENT_NAMES[priceMeasurementNum] || ''; - const priceInTokens = weiToTokens(config.price, window.ethers); + const priceInTokens = weiToTokens(config.price, ethers); const priceInUSD = litKeyPriceUSD ? priceInTokens * litKeyPriceUSD : null; diff --git a/docs/snippets/ExampleLitActionCosts.jsx b/docs/snippets/ExampleLitActionCosts.jsx new file mode 100644 index 000000000..ca073b296 --- /dev/null +++ b/docs/snippets/ExampleLitActionCosts.jsx @@ -0,0 +1,356 @@ +import { usePrices, weiToTokens, formatPrice, LitActionPriceComponent, NodePriceMeasurement } from './PriceProvider'; + +export const ExampleLitActionCosts = () => { + const { + loading, + error, + litActionConfigs, + litKeyPriceUSD, + ethers, + } = usePrices(); + + // 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)} + +
+ +
+
{
{

Lit Action Price Components

-
+
From bc52e981975c34ffed0cc83c404698f9b8bc39f8 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 15:55:41 -0800 Subject: [PATCH 15/32] move column --- docs/snippets/CurrentPricesTable.jsx | 40 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 7fd4c24fa..e5b29e9d9 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -331,23 +331,23 @@ export const CurrentPricesTable = () => { @@ -390,24 +390,25 @@ export const CurrentPricesTable = () => { ); From 3fb44f672f8532daa391d0351fffbd01a0d4ae80 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 16:28:02 -0800 Subject: [PATCH 16/32] litkey links --- docs/learning-lit/pricing/payment-model.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/learning-lit/pricing/payment-model.mdx b/docs/learning-lit/pricing/payment-model.mdx index 06b027043..50e7a12f3 100644 --- a/docs/learning-lit/pricing/payment-model.mdx +++ b/docs/learning-lit/pricing/payment-model.mdx @@ -8,7 +8,7 @@ Lit Protocol uses a token-based payment system to ensure the decentralized netwo ### 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 tokens and automatically deducts fees as you use the network. +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 @@ -25,14 +25,14 @@ This pricing mechanism ensures: ### Pricing in $LITKEY Tokens -All services on Lit Protocol are priced in **$LITKEY tokens**, the native token of Lit Chain. When you use network services such as: +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 - **Encrypted Signing**: Signing with encrypted keys - **Lit Actions**: Executing serverless JavaScript functions - **Sign Session Key**: Session-based signing operations -The network automatically deducts the appropriate amount of $LITKEY tokens from your ledger balance based on the current dynamic price. +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 @@ -48,7 +48,7 @@ If your balance is insufficient, the request will fail. You can check your balan To start using Lit Protocol's paid services: -1. **Acquire $LITKEY tokens** - [Get tokens](/governance/litkey/getting-litkey) from exchanges or other sources +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 From ae7eb7bd678207a373e8290a3765942b8cfcdbbe Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 17:02:26 -0800 Subject: [PATCH 17/32] some more edits --- docs/learning-lit/pricing/current-prices.mdx | 4 ++-- docs/learning-lit/pricing/payment-model.mdx | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/learning-lit/pricing/current-prices.mdx b/docs/learning-lit/pricing/current-prices.mdx index fe846bfe6..4af9b562b 100644 --- a/docs/learning-lit/pricing/current-prices.mdx +++ b/docs/learning-lit/pricing/current-prices.mdx @@ -3,7 +3,7 @@ title: "Current Prices" --- import { CurrentPricesTable } from "/snippets/CurrentPricesTable.jsx"; -The following table shows the current pricing for Lit Protocol services on the **naga-prod** network. Prices are displayed in both $LITKEY tokens and USD (based on current market rates). +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). Prices update dynamically based on network usage. The values shown below reflect real-time prices fetched from the blockchain. @@ -22,7 +22,7 @@ Prices update dynamically based on network usage. The values shown below reflect ### Product Types - **PKP Sign**: Signing operations using your Programmable Key Pair -- **Encrypted Sign**: Signing with encrypted keys +- **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 diff --git a/docs/learning-lit/pricing/payment-model.mdx b/docs/learning-lit/pricing/payment-model.mdx index 50e7a12f3..55ee43b44 100644 --- a/docs/learning-lit/pricing/payment-model.mdx +++ b/docs/learning-lit/pricing/payment-model.mdx @@ -2,7 +2,7 @@ title: "Payment Model" --- -Lit Protocol uses a token-based payment system to ensure the decentralized network can sustain itself and compensate node operators for providing cryptographic services. +Lit Protocol uses a token-based payment system to ensure the decentralized network can sustain itself for providing cryptographic services. ## How Payment Works @@ -21,14 +21,14 @@ Lit Protocol uses a dynamic pricing model that adjusts based on 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) -- Sustainable compensation for node operators +- 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 -- **Encrypted Signing**: Signing with encrypted keys +- **Decryption and Access Control**: Decrypting data and enforcing access control conditions - **Lit Actions**: Executing serverless JavaScript functions - **Sign Session Key**: Session-based signing operations From 8d8b8a35a286fdeef80753a7a22d928238f7ce21 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Wed, 26 Nov 2025 17:03:50 -0800 Subject: [PATCH 18/32] column ordering --- docs/snippets/CurrentPricesTable.jsx | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index e5b29e9d9..bc77f085c 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -331,23 +331,23 @@ export const CurrentPricesTable = () => { ); })} + {pkpMintCost !== null && ( + + + + + + + )}
- Product + Current Price - Base Price + Product { fontSize: '0.9em', }} > - Max Price + Base Price { fontSize: '0.9em', }} > - Current Price + Max Price
- {PRODUCT_NAMES[productId]} + {formatPrice(currentPriceInTokens, currentPriceInUSD)} - {formatPrice(basePriceInTokens, basePriceInUSD)} + {PRODUCT_NAMES[productId]} { fontSize: '0.85em', }} > - {formatPrice(maxPriceInTokens, maxPriceInUSD)} + {formatPrice(basePriceInTokens, basePriceInUSD)} { textAlign: 'right', border: '1px solid #ddd', fontFamily: 'monospace', - fontWeight: '600', fontSize: '0.85em', }} > - {formatPrice(currentPriceInTokens, currentPriceInUSD)} + {formatPrice(maxPriceInTokens, maxPriceInUSD)}
- Current Price + Product - Product + Current Price {
- {formatPrice(currentPriceInTokens, currentPriceInUSD)} + {PRODUCT_NAMES[productId]} - {PRODUCT_NAMES[productId]} + {formatPrice(currentPriceInTokens, currentPriceInUSD)} Date: Fri, 5 Dec 2025 14:18:21 -0800 Subject: [PATCH 19/32] update whitepaper links --- docs/learning-lit/communicating-with-lit-nodes.mdx | 2 +- docs/learning-lit/cryptoeconomic-security.mdx | 2 +- docs/learning-lit/distributed-key-generation.mdx | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) 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. From 057c38506885aa9b6edc1739566b50a5550c5b35 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Fri, 5 Dec 2025 14:31:27 -0800 Subject: [PATCH 20/32] some fixes --- docs/learning-lit/pricing/payment-model.mdx | 8 +++++++- docs/snippets/CurrentPricesTable.jsx | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/learning-lit/pricing/payment-model.mdx b/docs/learning-lit/pricing/payment-model.mdx index 55ee43b44..e9538c062 100644 --- a/docs/learning-lit/pricing/payment-model.mdx +++ b/docs/learning-lit/pricing/payment-model.mdx @@ -4,7 +4,7 @@ title: "Payment Model" Lit Protocol uses a token-based payment system to ensure the decentralized network can sustain itself for providing cryptographic services. -## How Payment Works +## How Network Usage Payments Work ### Token Deposit System @@ -55,3 +55,9 @@ To start using Lit Protocol's paid services: 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. 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/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index bc77f085c..b861d6437 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -331,7 +331,7 @@ export const CurrentPricesTable = () => {
Date: Fri, 5 Dec 2025 14:34:15 -0800 Subject: [PATCH 21/32] fix padding, bold --- docs/learning-lit/pricing/payment-model.mdx | 2 +- docs/snippets/CurrentPricesTable.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/learning-lit/pricing/payment-model.mdx b/docs/learning-lit/pricing/payment-model.mdx index e9538c062..b4d34b8cd 100644 --- a/docs/learning-lit/pricing/payment-model.mdx +++ b/docs/learning-lit/pricing/payment-model.mdx @@ -60,4 +60,4 @@ For detailed information on current pricing, see the [Current Prices](/learning- 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. Check out the [Current Prices page](/learning-lit/pricing/current-prices) to see the price right now. \ No newline at end of file +- **PKP Minting** - When you mint a new PKP, you will need to pay a specific fee for the minting operation. 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/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index b861d6437..134a435f6 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -390,7 +390,7 @@ export const CurrentPricesTable = () => {
Date: Fri, 5 Dec 2025 14:39:47 -0800 Subject: [PATCH 22/32] add pkp minting row --- docs/learning-lit/pricing/current-prices.mdx | 3 +- docs/learning-lit/pricing/payment-model.mdx | 2 +- docs/snippets/CurrentPricesTable.jsx | 97 ++++++++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/docs/learning-lit/pricing/current-prices.mdx b/docs/learning-lit/pricing/current-prices.mdx index 4af9b562b..bde55b63c 100644 --- a/docs/learning-lit/pricing/current-prices.mdx +++ b/docs/learning-lit/pricing/current-prices.mdx @@ -6,7 +6,7 @@ import { CurrentPricesTable } from "/snippets/CurrentPricesTable.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). -Prices update dynamically based on network usage. The values shown below reflect real-time prices fetched from the blockchain. +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. @@ -25,6 +25,7 @@ Prices update dynamically based on network usage. The values shown below reflect - **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 diff --git a/docs/learning-lit/pricing/payment-model.mdx b/docs/learning-lit/pricing/payment-model.mdx index b4d34b8cd..75c2c884f 100644 --- a/docs/learning-lit/pricing/payment-model.mdx +++ b/docs/learning-lit/pricing/payment-model.mdx @@ -60,4 +60,4 @@ For detailed information on current pricing, see the [Current Prices](/learning- 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. Check out the [Current Prices page](/learning-lit/pricing/current-prices) to see the price right now. \ No newline at end of file +- **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/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 134a435f6..50692d5ad 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -3,6 +3,7 @@ import { useEffect, useState } from 'react'; export const CurrentPricesTable = () => { // 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 @@ -166,6 +167,23 @@ export const CurrentPricesTable = () => { }, ]; + // PKP Contract ABI (for mintCost) + const PKP_ABI = [ + { + inputs: [], + name: 'mintCost', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ]; + // Helper functions const getLitKeyPrice = async () => { try { @@ -207,6 +225,7 @@ export const CurrentPricesTable = () => { 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 @@ -255,6 +274,7 @@ export const CurrentPricesTable = () => { 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); @@ -268,6 +288,10 @@ export const CurrentPricesTable = () => { const litActionConfigsResult = await contract.getLitActionPriceConfigs(); + // Fetch PKP minting cost (static price) + const mintCostResult = await pkpContract.mintCost(); + setPkpMintCost(mintCostResult); + setBasePrices(basePricesResult); setMaxPrices(maxPricesResult); setCurrentPrices(currentPricesResult); @@ -435,6 +459,79 @@ export const CurrentPricesTable = () => {
+ PKP Minting{' '} + + (Static) + + + {formatPrice( + weiToTokens(pkpMintCost, window.ethers), + litKeyPriceUSD + ? weiToTokens(pkpMintCost, window.ethers) * litKeyPriceUSD + : null + )} + + {formatPrice( + weiToTokens(pkpMintCost, window.ethers), + litKeyPriceUSD + ? weiToTokens(pkpMintCost, window.ethers) * litKeyPriceUSD + : null + )} + + {formatPrice( + weiToTokens(pkpMintCost, window.ethers), + litKeyPriceUSD + ? weiToTokens(pkpMintCost, window.ethers) * litKeyPriceUSD + : null + )} +
From 56de8e54a3ebd8681962fae941fdaf7b3bc670ca Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Fri, 5 Dec 2025 15:26:56 -0800 Subject: [PATCH 23/32] examples costs --- docs/docs.json | 3 +- docs/learning-lit/pricing/current-prices.mdx | 5 +- .../pricing/example-lit-action-costs.mdx | 28 ++ docs/snippets/CurrentPricesTable.jsx | 296 ++------------- docs/snippets/ExampleLitActionCosts.jsx | 356 ++++++++++++++++++ docs/snippets/PriceProvider.jsx | 309 +++++++++++++++ 6 files changed, 722 insertions(+), 275 deletions(-) create mode 100644 docs/learning-lit/pricing/example-lit-action-costs.mdx create mode 100644 docs/snippets/ExampleLitActionCosts.jsx create mode 100644 docs/snippets/PriceProvider.jsx diff --git a/docs/docs.json b/docs/docs.json index 27b02ab1d..41503f645 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -32,7 +32,8 @@ "group": "Pricing", "pages": [ "learning-lit/pricing/payment-model", - "learning-lit/pricing/current-prices" + "learning-lit/pricing/current-prices", + "learning-lit/pricing/example-lit-action-costs" ] } ] diff --git a/docs/learning-lit/pricing/current-prices.mdx b/docs/learning-lit/pricing/current-prices.mdx index bde55b63c..6585346fa 100644 --- a/docs/learning-lit/pricing/current-prices.mdx +++ b/docs/learning-lit/pricing/current-prices.mdx @@ -2,6 +2,7 @@ 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). @@ -9,7 +10,9 @@ The following table shows the current pricing for Lit Protocol services on the * 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 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..7e81b91ca --- /dev/null +++ b/docs/learning-lit/pricing/example-lit-action-costs.mdx @@ -0,0 +1,28 @@ +--- +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/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 50692d5ad..5c2cb6d7f 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -1,11 +1,6 @@ -import { useEffect, useState } from 'react'; +import { usePrices, weiToTokens, formatPrice, LitActionPriceComponent, NodePriceMeasurement } from './PriceProvider'; export const CurrentPricesTable = () => { - // 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, @@ -22,28 +17,6 @@ export const CurrentPricesTable = () => { ProductId.SignSessionKey, ]; - // LitActionPriceComponent enum values - const 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 - const NodePriceMeasurement = { - perSecond: 0, - perMegabyte: 1, - perCount: 2, - }; - const PRODUCT_NAMES = { [ProductId.PkpSign]: 'PKP Sign', [ProductId.EncSign]: 'Encrypted Sign', @@ -71,241 +44,18 @@ export const CurrentPricesTable = () => { [NodePriceMeasurement.perCount]: '/count', }; - // 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 functions - 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 weiToTokens = (wei, ethers) => { - if (!ethers || !ethers.utils) { - return 0; - } - return parseFloat(ethers.utils.formatUnits(wei, 18)); - }; - - const formatPrice = (priceInTokens, priceInUSD) => { - if (priceInUSD === null) { - return `${priceInTokens.toFixed(6)} LITKEY`; - } - return `${priceInTokens.toFixed(6)} LITKEY ($${priceInUSD.toFixed(6)})`; - }; - - 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 { + loading, + error, + basePrices, + maxPrices, + currentPrices, + litActionConfigs, + litKeyPriceUSD, + usagePercent, + pkpMintCost, + ethers, + } = usePrices(); if (loading) { return ( @@ -397,9 +147,9 @@ export const CurrentPricesTable = () => {
+ + + + + + + + + + {costData.breakdown.map((item, itemIdx) => ( + + + + + + + ))} + + + + + + + +
+ Component + + Quantity + + Unit Price + + Total +
+ {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..452f7b488 --- /dev/null +++ b/docs/snippets/PriceProvider.jsx @@ -0,0 +1,309 @@ +import { createContext, useContext, useEffect, useState } from 'react'; + +// Create context +const PriceContext = createContext(null); + +// 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, +]; + +// LitActionPriceComponent enum values +export const 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 +export const NodePriceMeasurement = { + perSecond: 0, + perMegabyte: 1, + perCount: 2, +}; + +// 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 functions +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; + } +}; + +export const weiToTokens = (wei, ethers) => { + if (!ethers || !ethers.utils) { + return 0; + } + return parseFloat(ethers.utils.formatUnits(wei, 18)); +}; + +export const formatPrice = (priceInTokens, priceInUSD) => { + if (priceInUSD === null) { + return `${priceInTokens.toFixed(6)} LITKEY`; + } + return `${priceInTokens.toFixed(6)} LITKEY ($${priceInUSD.toFixed(6)})`; +}; + +export const PriceProvider = ({ children }) => { + 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 value = { + loading, + error, + basePrices, + maxPrices, + currentPrices, + litActionConfigs, + litKeyPriceUSD, + usagePercent, + pkpMintCost, + ethers: window.ethers, + }; + + return {children}; +}; + +export const usePrices = () => { + const context = useContext(PriceContext); + if (!context) { + throw new Error('usePrices must be used within a PriceProvider'); + } + return context; +}; + From 3326c6a965e2d9d523e552592ec4d7f3b94857df Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Fri, 5 Dec 2025 15:33:09 -0800 Subject: [PATCH 24/32] trying to DRY current prices without react context --- docs/snippets/CurrentPricesTable.jsx | 14 ++++++++++--- docs/snippets/ExampleLitActionCosts.jsx | 14 ++++++++++--- docs/snippets/PriceProvider.jsx | 26 ++++++++++++------------- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 5c2cb6d7f..3e3e03588 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -1,6 +1,6 @@ -import { usePrices, weiToTokens, formatPrice, LitActionPriceComponent, NodePriceMeasurement } from './PriceProvider'; +import { weiToTokens, formatPrice, LitActionPriceComponent, NodePriceMeasurement } from './PriceProvider'; -export const CurrentPricesTable = () => { +export const CurrentPricesTable = ({ priceData }) => { // Product IDs const ProductId = { PkpSign: 0, @@ -44,6 +44,14 @@ export const CurrentPricesTable = () => { [NodePriceMeasurement.perCount]: '/count', }; + if (!priceData) { + return ( +
+

Price data not available. Please wrap this component with PriceProvider.

+
+ ); + } + const { loading, error, @@ -55,7 +63,7 @@ export const CurrentPricesTable = () => { usagePercent, pkpMintCost, ethers, - } = usePrices(); + } = priceData; if (loading) { return ( diff --git a/docs/snippets/ExampleLitActionCosts.jsx b/docs/snippets/ExampleLitActionCosts.jsx index ca073b296..fc6734d97 100644 --- a/docs/snippets/ExampleLitActionCosts.jsx +++ b/docs/snippets/ExampleLitActionCosts.jsx @@ -1,13 +1,21 @@ -import { usePrices, weiToTokens, formatPrice, LitActionPriceComponent, NodePriceMeasurement } from './PriceProvider'; +import { weiToTokens, formatPrice, LitActionPriceComponent, NodePriceMeasurement } from './PriceProvider'; + +export const ExampleLitActionCosts = ({ priceData }) => { + if (!priceData) { + return ( +
+

Price data not available. Please wrap this component with PriceProvider.

+
+ ); + } -export const ExampleLitActionCosts = () => { const { loading, error, litActionConfigs, litKeyPriceUSD, ethers, - } = usePrices(); + } = priceData; // Helper to get price for a specific component const getComponentPrice = (componentType, measurementType) => { diff --git a/docs/snippets/PriceProvider.jsx b/docs/snippets/PriceProvider.jsx index 452f7b488..b4a4a7337 100644 --- a/docs/snippets/PriceProvider.jsx +++ b/docs/snippets/PriceProvider.jsx @@ -1,7 +1,4 @@ -import { createContext, useContext, useEffect, useState } from 'react'; - -// Create context -const PriceContext = createContext(null); +import { useEffect, useState, Children, cloneElement } from 'react'; // Constants - defined inside component for Mintlify compatibility const NAGA_PROD_PRICE_FEED_ADDRESS = '0x88F5535Fa6dA5C225a3C06489fE4e3405b87608C'; @@ -283,7 +280,7 @@ export const PriceProvider = ({ children }) => { fetchPrices(); }, [ethersLoaded]); - const value = { + const priceData = { loading, error, basePrices, @@ -296,14 +293,17 @@ export const PriceProvider = ({ children }) => { ethers: window.ethers, }; - return {children}; -}; - -export const usePrices = () => { - const context = useContext(PriceContext); - if (!context) { - throw new Error('usePrices must be used within a PriceProvider'); + // Clone children and pass price data as props + // Handle both single child and multiple children + if (!children) { + return null; } - return context; + + return Children.map(children, (child) => { + if (child && typeof child === 'object' && 'type' in child && typeof child.type !== 'string') { + return cloneElement(child, { priceData }); + } + return child; + }); }; From cf4fa5dc7d34a537a95c986a00f4645c968b8421 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Fri, 5 Dec 2025 15:39:52 -0800 Subject: [PATCH 25/32] pass child to priceprovider --- docs/learning-lit/pricing/current-prices.mdx | 4 +-- .../pricing/example-lit-action-costs.mdx | 4 +-- docs/snippets/PriceProvider.jsx | 25 +++++++++++-------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/docs/learning-lit/pricing/current-prices.mdx b/docs/learning-lit/pricing/current-prices.mdx index 6585346fa..1a64bce46 100644 --- a/docs/learning-lit/pricing/current-prices.mdx +++ b/docs/learning-lit/pricing/current-prices.mdx @@ -10,9 +10,7 @@ The following table shows the current pricing for Lit Protocol services on the * 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 diff --git a/docs/learning-lit/pricing/example-lit-action-costs.mdx b/docs/learning-lit/pricing/example-lit-action-costs.mdx index 7e81b91ca..99704e373 100644 --- a/docs/learning-lit/pricing/example-lit-action-costs.mdx +++ b/docs/learning-lit/pricing/example-lit-action-costs.mdx @@ -10,9 +10,7 @@ This page demonstrates real-world cost estimates for common Lit Action operation 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 diff --git a/docs/snippets/PriceProvider.jsx b/docs/snippets/PriceProvider.jsx index b4a4a7337..f4a925701 100644 --- a/docs/snippets/PriceProvider.jsx +++ b/docs/snippets/PriceProvider.jsx @@ -1,4 +1,4 @@ -import { useEffect, useState, Children, cloneElement } from 'react'; +import { useEffect, useState } from 'react'; // Constants - defined inside component for Mintlify compatibility const NAGA_PROD_PRICE_FEED_ADDRESS = '0x88F5535Fa6dA5C225a3C06489fE4e3405b87608C'; @@ -189,7 +189,7 @@ export const formatPrice = (priceInTokens, priceInUSD) => { return `${priceInTokens.toFixed(6)} LITKEY ($${priceInUSD.toFixed(6)})`; }; -export const PriceProvider = ({ children }) => { +export const PriceProvider = ({ children, component: Component }) => { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [basePrices, setBasePrices] = useState([]); @@ -293,17 +293,20 @@ export const PriceProvider = ({ children }) => { ethers: window.ethers, }; - // Clone children and pass price data as props - // Handle both single child and multiple children - if (!children) { + // 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; } - return Children.map(children, (child) => { - if (child && typeof child === 'object' && 'type' in child && typeof child.type !== 'string') { - return cloneElement(child, { priceData }); - } - return child; - }); + // 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; }; From 09a9be888597a9a65fcc6969aa1bde2fd8b76e20 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Fri, 5 Dec 2025 16:19:07 -0800 Subject: [PATCH 26/32] remove import of LitActionPriceComponent --- docs/snippets/CurrentPricesTable.jsx | 24 +++++++++++++++++++++++- docs/snippets/ExampleLitActionCosts.jsx | 23 ++++++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 3e3e03588..422b96433 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -1,4 +1,4 @@ -import { weiToTokens, formatPrice, LitActionPriceComponent, NodePriceMeasurement } from './PriceProvider'; +import { weiToTokens, formatPrice } from './PriceProvider'; export const CurrentPricesTable = ({ priceData }) => { // Product IDs @@ -17,6 +17,28 @@ export const CurrentPricesTable = ({ priceData }) => { ProductId.SignSessionKey, ]; + // LitActionPriceComponent enum values + const 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 + const NodePriceMeasurement = { + perSecond: 0, + perMegabyte: 1, + perCount: 2, + }; + const PRODUCT_NAMES = { [ProductId.PkpSign]: 'PKP Sign', [ProductId.EncSign]: 'Encrypted Sign', diff --git a/docs/snippets/ExampleLitActionCosts.jsx b/docs/snippets/ExampleLitActionCosts.jsx index fc6734d97..edc490344 100644 --- a/docs/snippets/ExampleLitActionCosts.jsx +++ b/docs/snippets/ExampleLitActionCosts.jsx @@ -1,6 +1,27 @@ -import { weiToTokens, formatPrice, LitActionPriceComponent, NodePriceMeasurement } from './PriceProvider'; +import { weiToTokens, formatPrice } from './PriceProvider'; export const ExampleLitActionCosts = ({ priceData }) => { + // LitActionPriceComponent enum values + const 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 + const NodePriceMeasurement = { + perSecond: 0, + perMegabyte: 1, + perCount: 2, + }; if (!priceData) { return (
From e8a553f32223d0f1fc27288dd0ace85da8f2860e Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Fri, 5 Dec 2025 16:30:38 -0800 Subject: [PATCH 27/32] do arrow functions work? --- docs/snippets/CurrentPricesTable.jsx | 26 ++++--------------------- docs/snippets/ExampleLitActionCosts.jsx | 26 ++++--------------------- docs/snippets/PriceProvider.jsx | 8 ++++---- 3 files changed, 12 insertions(+), 48 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 422b96433..4a473154e 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -1,4 +1,4 @@ -import { weiToTokens, formatPrice } from './PriceProvider'; +import { weiToTokens, formatPrice, getLitActionPriceComponent, getNodePriceMeasurement } from './PriceProvider'; export const CurrentPricesTable = ({ priceData }) => { // Product IDs @@ -17,27 +17,9 @@ export const CurrentPricesTable = ({ priceData }) => { ProductId.SignSessionKey, ]; - // LitActionPriceComponent enum values - const 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 - const NodePriceMeasurement = { - perSecond: 0, - perMegabyte: 1, - perCount: 2, - }; + // Get enum values from functions + const LitActionPriceComponent = getLitActionPriceComponent(); + const NodePriceMeasurement = getNodePriceMeasurement(); const PRODUCT_NAMES = { [ProductId.PkpSign]: 'PKP Sign', diff --git a/docs/snippets/ExampleLitActionCosts.jsx b/docs/snippets/ExampleLitActionCosts.jsx index edc490344..959d8f774 100644 --- a/docs/snippets/ExampleLitActionCosts.jsx +++ b/docs/snippets/ExampleLitActionCosts.jsx @@ -1,27 +1,9 @@ -import { weiToTokens, formatPrice } from './PriceProvider'; +import { weiToTokens, formatPrice, getLitActionPriceComponent, getNodePriceMeasurement } from './PriceProvider'; export const ExampleLitActionCosts = ({ priceData }) => { - // LitActionPriceComponent enum values - const 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 - const NodePriceMeasurement = { - perSecond: 0, - perMegabyte: 1, - perCount: 2, - }; + // Get enum values from functions + const LitActionPriceComponent = getLitActionPriceComponent(); + const NodePriceMeasurement = getNodePriceMeasurement(); if (!priceData) { return (
diff --git a/docs/snippets/PriceProvider.jsx b/docs/snippets/PriceProvider.jsx index f4a925701..17211e3e5 100644 --- a/docs/snippets/PriceProvider.jsx +++ b/docs/snippets/PriceProvider.jsx @@ -22,7 +22,7 @@ const PRODUCT_IDS = [ ]; // LitActionPriceComponent enum values -export const LitActionPriceComponent = { +export const getLitActionPriceComponent = () => ({ baseAmount: 0, runtimeLength: 1, memoryUsage: 2, @@ -34,14 +34,14 @@ export const LitActionPriceComponent = { callDepth: 8, decrypts: 9, fetches: 10, -}; +}); // NodePriceMeasurement enum values -export const NodePriceMeasurement = { +export const getNodePriceMeasurement = () => ({ perSecond: 0, perMegabyte: 1, perCount: 2, -}; +}); // PriceFeed ABI (minimal - only functions we need) const PRICE_FEED_ABI = [ From 981d7938b2e93f09c895b0f6f2e45b747d9acb6b Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Fri, 5 Dec 2025 17:13:36 -0800 Subject: [PATCH 28/32] trying a single export --- docs/snippets/CurrentPricesTable.jsx | 4 +++- docs/snippets/PriceProvider.jsx | 15 +-------------- docs/snippets/utils.jsx | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 15 deletions(-) create mode 100644 docs/snippets/utils.jsx diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 4a473154e..a9ec44b9b 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -1,4 +1,6 @@ -import { weiToTokens, formatPrice, getLitActionPriceComponent, getNodePriceMeasurement } from './PriceProvider'; +import { weiToTokens, formatPrice, getNodePriceMeasurement } from './PriceProvider'; + +import { getLitActionPriceComponent } from './utils'; export const CurrentPricesTable = ({ priceData }) => { // Product IDs diff --git a/docs/snippets/PriceProvider.jsx b/docs/snippets/PriceProvider.jsx index 17211e3e5..d76ce640a 100644 --- a/docs/snippets/PriceProvider.jsx +++ b/docs/snippets/PriceProvider.jsx @@ -21,20 +21,7 @@ const PRODUCT_IDS = [ ProductId.SignSessionKey, ]; -// LitActionPriceComponent enum values -export const getLitActionPriceComponent = () => ({ - 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 export const getNodePriceMeasurement = () => ({ diff --git a/docs/snippets/utils.jsx b/docs/snippets/utils.jsx new file mode 100644 index 000000000..51614c66f --- /dev/null +++ b/docs/snippets/utils.jsx @@ -0,0 +1,14 @@ +// LitActionPriceComponent enum values +export const getLitActionPriceComponent = () => ({ + baseAmount: 0, + runtimeLength: 1, + memoryUsage: 2, + codeLength: 3, + responseLength: 4, + signatures: 5, + broadcasts: 6, + contractCalls: 7, + callDepth: 8, + decrypts: 9, + fetches: 10, +}); \ No newline at end of file From db4a21346545df5fb8a27ec3616349ac26a74209 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Fri, 5 Dec 2025 17:41:10 -0800 Subject: [PATCH 29/32] trying another approach of globals for the consts --- docs/lit-pricing-constants.js | 27 +++++++++++++++++++++++++ docs/snippets/CurrentPricesTable.jsx | 12 +++++------ docs/snippets/ExampleLitActionCosts.jsx | 8 ++++---- docs/snippets/PriceProvider.jsx | 9 +-------- docs/snippets/utils.jsx | 14 ------------- 5 files changed, 37 insertions(+), 33 deletions(-) create mode 100644 docs/lit-pricing-constants.js delete mode 100644 docs/snippets/utils.jsx diff --git a/docs/lit-pricing-constants.js b/docs/lit-pricing-constants.js new file mode 100644 index 000000000..9e85f76d2 --- /dev/null +++ b/docs/lit-pricing-constants.js @@ -0,0 +1,27 @@ +// Shared constants 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, + }, +}; + diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index a9ec44b9b..c3c76587c 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -1,8 +1,10 @@ -import { weiToTokens, formatPrice, getNodePriceMeasurement } from './PriceProvider'; - -import { getLitActionPriceComponent } from './utils'; +import { weiToTokens, formatPrice } from './PriceProvider'; export const CurrentPricesTable = ({ priceData }) => { + // Get constants from window (populated by lit-pricing-constants.js) + const LitActionPriceComponent = window.LitPricingConstants?.LitActionPriceComponent || {}; + const NodePriceMeasurement = window.LitPricingConstants?.NodePriceMeasurement || {}; + // Product IDs const ProductId = { PkpSign: 0, @@ -19,10 +21,6 @@ export const CurrentPricesTable = ({ priceData }) => { ProductId.SignSessionKey, ]; - // Get enum values from functions - const LitActionPriceComponent = getLitActionPriceComponent(); - const NodePriceMeasurement = getNodePriceMeasurement(); - const PRODUCT_NAMES = { [ProductId.PkpSign]: 'PKP Sign', [ProductId.EncSign]: 'Encrypted Sign', diff --git a/docs/snippets/ExampleLitActionCosts.jsx b/docs/snippets/ExampleLitActionCosts.jsx index 959d8f774..a69495646 100644 --- a/docs/snippets/ExampleLitActionCosts.jsx +++ b/docs/snippets/ExampleLitActionCosts.jsx @@ -1,9 +1,9 @@ -import { weiToTokens, formatPrice, getLitActionPriceComponent, getNodePriceMeasurement } from './PriceProvider'; +import { weiToTokens, formatPrice } from './PriceProvider'; export const ExampleLitActionCosts = ({ priceData }) => { - // Get enum values from functions - const LitActionPriceComponent = getLitActionPriceComponent(); - const NodePriceMeasurement = getNodePriceMeasurement(); + // Get constants from window (populated by lit-pricing-constants.js) + const LitActionPriceComponent = window.LitPricingConstants?.LitActionPriceComponent || {}; + const NodePriceMeasurement = window.LitPricingConstants?.NodePriceMeasurement || {}; if (!priceData) { return (
diff --git a/docs/snippets/PriceProvider.jsx b/docs/snippets/PriceProvider.jsx index d76ce640a..da0d35fe0 100644 --- a/docs/snippets/PriceProvider.jsx +++ b/docs/snippets/PriceProvider.jsx @@ -21,14 +21,7 @@ const PRODUCT_IDS = [ ProductId.SignSessionKey, ]; - - -// NodePriceMeasurement enum values -export const getNodePriceMeasurement = () => ({ - perSecond: 0, - perMegabyte: 1, - perCount: 2, -}); +// Constants are now in lit-pricing-constants.js and available via window.LitPricingConstants // PriceFeed ABI (minimal - only functions we need) const PRICE_FEED_ABI = [ diff --git a/docs/snippets/utils.jsx b/docs/snippets/utils.jsx deleted file mode 100644 index 51614c66f..000000000 --- a/docs/snippets/utils.jsx +++ /dev/null @@ -1,14 +0,0 @@ -// LitActionPriceComponent enum values -export const getLitActionPriceComponent = () => ({ - baseAmount: 0, - runtimeLength: 1, - memoryUsage: 2, - codeLength: 3, - responseLength: 4, - signatures: 5, - broadcasts: 6, - contractCalls: 7, - callDepth: 8, - decrypts: 9, - fetches: 10, -}); \ No newline at end of file From a7b0dc831f33eb675e2a98c24939454323b2614f Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Fri, 5 Dec 2025 17:46:30 -0800 Subject: [PATCH 30/32] move variables into component --- docs/snippets/PriceProvider.jsx | 307 ++++++++++++++++---------------- 1 file changed, 152 insertions(+), 155 deletions(-) diff --git a/docs/snippets/PriceProvider.jsx b/docs/snippets/PriceProvider.jsx index da0d35fe0..1b1187fa1 100644 --- a/docs/snippets/PriceProvider.jsx +++ b/docs/snippets/PriceProvider.jsx @@ -1,160 +1,5 @@ import { useEffect, useState } from 'react'; -// 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, -]; - -// Constants are now in lit-pricing-constants.js and available via window.LitPricingConstants - -// 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 functions -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; - } -}; - export const weiToTokens = (wei, ethers) => { if (!ethers || !ethers.utils) { return 0; @@ -170,6 +15,158 @@ export const formatPrice = (priceInTokens, priceInUSD) => { }; 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([]); From 6c253a1da5201b19a0705478e34e33be0f90f38b Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Fri, 5 Dec 2025 17:51:21 -0800 Subject: [PATCH 31/32] move utils --- docs/lit-pricing-constants.js | 18 +++++++++++++++++- docs/snippets/CurrentPricesTable.jsx | 6 +++--- docs/snippets/ExampleLitActionCosts.jsx | 6 +++--- docs/snippets/PriceProvider.jsx | 14 -------------- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/docs/lit-pricing-constants.js b/docs/lit-pricing-constants.js index 9e85f76d2..897219a74 100644 --- a/docs/lit-pricing-constants.js +++ b/docs/lit-pricing-constants.js @@ -1,4 +1,4 @@ -// Shared constants for Lit Protocol pricing components +// Shared constants and helper functions for Lit Protocol pricing components // This file is automatically included on every page by Mintlify window.LitPricingConstants = { @@ -23,5 +23,21 @@ window.LitPricingConstants = { 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 index c3c76587c..17c9fd605 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -1,9 +1,9 @@ -import { weiToTokens, formatPrice } from './PriceProvider'; - export const CurrentPricesTable = ({ priceData }) => { - // Get constants from window (populated by lit-pricing-constants.js) + // 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 = { diff --git a/docs/snippets/ExampleLitActionCosts.jsx b/docs/snippets/ExampleLitActionCosts.jsx index a69495646..5128c6bf4 100644 --- a/docs/snippets/ExampleLitActionCosts.jsx +++ b/docs/snippets/ExampleLitActionCosts.jsx @@ -1,9 +1,9 @@ -import { weiToTokens, formatPrice } from './PriceProvider'; - export const ExampleLitActionCosts = ({ priceData }) => { - // Get constants from window (populated by lit-pricing-constants.js) + // 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 (
diff --git a/docs/snippets/PriceProvider.jsx b/docs/snippets/PriceProvider.jsx index 1b1187fa1..79b2d9d2b 100644 --- a/docs/snippets/PriceProvider.jsx +++ b/docs/snippets/PriceProvider.jsx @@ -1,19 +1,5 @@ import { useEffect, useState } from 'react'; -export const weiToTokens = (wei, ethers) => { - if (!ethers || !ethers.utils) { - return 0; - } - return parseFloat(ethers.utils.formatUnits(wei, 18)); -}; - -export const formatPrice = (priceInTokens, priceInUSD) => { - if (priceInUSD === null) { - return `${priceInTokens.toFixed(6)} LITKEY`; - } - return `${priceInTokens.toFixed(6)} LITKEY ($${priceInUSD.toFixed(6)})`; -}; - export const PriceProvider = ({ children, component: Component }) => { // Constants - defined inside component for Mintlify compatibility const NAGA_PROD_PRICE_FEED_ADDRESS = '0x88F5535Fa6dA5C225a3C06489fE4e3405b87608C'; From e0caab781ce16ea76c749ddf8c01cc6a5cd416b3 Mon Sep 17 00:00:00 2001 From: Chris Cassano Date: Fri, 5 Dec 2025 21:07:18 -0800 Subject: [PATCH 32/32] dark mode fixes --- docs/snippets/CurrentPricesTable.jsx | 48 ++++++++++++++----------- docs/snippets/ExampleLitActionCosts.jsx | 40 +++++++++++---------- 2 files changed, 49 insertions(+), 39 deletions(-) diff --git a/docs/snippets/CurrentPricesTable.jsx b/docs/snippets/CurrentPricesTable.jsx index 17c9fd605..cf3a24555 100644 --- a/docs/snippets/CurrentPricesTable.jsx +++ b/docs/snippets/CurrentPricesTable.jsx @@ -91,7 +91,7 @@ export const CurrentPricesTable = ({ priceData }) => { return (
{litKeyPriceUSD && ( -

+

LITKEY Price: ${litKeyPriceUSD.toFixed(4)} USD {usagePercent !== null && ( @@ -114,13 +114,14 @@ export const CurrentPricesTable = ({ priceData }) => { }} >

Product @@ -129,8 +130,9 @@ export const CurrentPricesTable = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontSize: '0.9em', + color: 'var(--mint-text, inherit)', }} > Current Price @@ -139,8 +141,9 @@ export const CurrentPricesTable = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontSize: '0.9em', + color: 'var(--mint-text, inherit)', }} > Base Price @@ -149,8 +152,9 @@ export const CurrentPricesTable = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontSize: '0.9em', + color: 'var(--mint-text, inherit)', }} > Max Price @@ -177,7 +181,7 @@ export const CurrentPricesTable = ({ priceData }) => { { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontFamily: 'monospace', fontWeight: '600', fontSize: '0.85em', @@ -200,7 +204,7 @@ export const CurrentPricesTable = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontFamily: 'monospace', fontSize: '0.85em', }} @@ -211,7 +215,7 @@ export const CurrentPricesTable = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontFamily: 'monospace', fontSize: '0.85em', }} @@ -226,7 +230,7 @@ export const CurrentPricesTable = ({ priceData }) => { { PKP Minting{' '} { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontFamily: 'monospace', fontWeight: '600', fontSize: '0.85em', @@ -264,7 +268,7 @@ export const CurrentPricesTable = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontFamily: 'monospace', fontSize: '0.85em', }} @@ -280,7 +284,7 @@ export const CurrentPricesTable = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontFamily: 'monospace', fontSize: '0.85em', }} @@ -313,13 +317,14 @@ export const CurrentPricesTable = ({ priceData }) => { }} >
Component @@ -328,8 +333,9 @@ export const CurrentPricesTable = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontSize: '0.9em', + color: 'var(--mint-text, inherit)', }} > Price @@ -355,13 +361,13 @@ export const CurrentPricesTable = ({ priceData }) => { {componentName} {measurementName && ( - + {measurementName} )} @@ -370,7 +376,7 @@ export const CurrentPricesTable = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontFamily: 'monospace', fontSize: '0.85em', }} diff --git a/docs/snippets/ExampleLitActionCosts.jsx b/docs/snippets/ExampleLitActionCosts.jsx index 5128c6bf4..ae241b89a 100644 --- a/docs/snippets/ExampleLitActionCosts.jsx +++ b/docs/snippets/ExampleLitActionCosts.jsx @@ -193,7 +193,7 @@ export const ExampleLitActionCosts = ({ priceData }) => { return (
{litKeyPriceUSD && ( -

+

LITKEY Price: ${litKeyPriceUSD.toFixed(4)} USD

)} @@ -208,15 +208,15 @@ export const ExampleLitActionCosts = ({ priceData }) => { style={{ marginBottom: '40px', padding: '20px', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', borderRadius: '8px', - backgroundColor: '#fafafa', + backgroundColor: 'var(--mint-bg-secondary, #fafafa)', }} >

{example.title}

-

+

{example.description}

@@ -236,12 +236,13 @@ export const ExampleLitActionCosts = ({ priceData }) => { }} >
Component @@ -250,7 +251,8 @@ export const ExampleLitActionCosts = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', + color: 'var(--mint-text, inherit)', }} > Quantity @@ -259,7 +261,8 @@ export const ExampleLitActionCosts = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', + color: 'var(--mint-text, inherit)', }} > Unit Price @@ -268,7 +271,8 @@ export const ExampleLitActionCosts = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', + color: 'var(--mint-text, inherit)', }} > Total @@ -281,7 +285,7 @@ export const ExampleLitActionCosts = ({ priceData }) => { {item.component} @@ -290,7 +294,7 @@ export const ExampleLitActionCosts = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontFamily: 'monospace', }} > @@ -300,7 +304,7 @@ export const ExampleLitActionCosts = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontFamily: 'monospace', }} > @@ -310,7 +314,7 @@ export const ExampleLitActionCosts = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', fontFamily: 'monospace', fontWeight: '600', }} @@ -319,11 +323,11 @@ export const ExampleLitActionCosts = ({ priceData }) => {
Total @@ -332,21 +336,21 @@ export const ExampleLitActionCosts = ({ priceData }) => { style={{ padding: '8px 10px', textAlign: 'right', - border: '1px solid #ddd', + border: '1px solid var(--mint-border, #ddd)', }} >