diff --git a/defillama-openapi-free.json b/defillama-openapi-free.json
index b8a0a7141e5..14e87836b01 100644
--- a/defillama-openapi-free.json
+++ b/defillama-openapi-free.json
@@ -1,9 +1,26 @@
{
"openapi": "3.0.0",
"info": {
- "description": "\n\nNeed higher rate limits or priority support? We offer a premium plan for 300$/mo. To get it, go to https://defillama.com/subscription \n\n\n Coding with AI? Paste this link to LLM-specific docs for best results \nllms.txt",
+ "description": "\n\nNeed higher rate limits or priority support? We offer a premium plan for 300$/mo. To get it, go to https://defillama.com/subscription\n\nSDK\n\nInstall:\n```bash\nnpm install @defillama/api\npip install defillama-sdk\n```\n\nQuick start (JavaScript):\n```ts\nimport { DefiLlama } from '@defillama/api'\n\nconst client = new DefiLlama()\nconst protocols = await client.tvl.getProtocols()\n```\n\nQuick start (Python):\n```py\nfrom defillama_sdk import DefiLlama\n\nclient = DefiLlama()\nprotocols = client.tvl.getProtocols()\n```\n\nCoding with AI? Paste this link to LLM-specific docs for best results\nllms.txt",
"version": "1.0.0-oas3",
- "title": "DefiLlama API"
+ "title": "DefiLlama API",
+ "x-scalar-sdk-installation": [
+ {
+ "lang": "node",
+ "description": "Install the DefiLlama JavaScript SDK:",
+ "source": "npm install @defillama/api"
+ },
+ {
+ "lang": "js",
+ "description": "Install the DefiLlama JavaScript SDK:",
+ "source": "npm install @defillama/api"
+ },
+ {
+ "lang": "python",
+ "description": "Install the DefiLlama Python SDK:",
+ "source": "pip install defillama-sdk"
+ }
+ ]
},
"tags": [
{
@@ -102,7 +119,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.tvl.getProtocols()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.tvl.getProtocols()"
+ }
+ ]
}
},
"/protocol/{protocol}": {
@@ -216,7 +245,19 @@
"404": {
"description": "Protocol not found"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.tvl.getProtocol('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.tvl.getProtocol('')"
+ }
+ ]
}
},
"/v2/historicalChainTvl": {
@@ -249,7 +290,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.tvl.getHistoricalChainTvl()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.tvl.getHistoricalChainTvl()"
+ }
+ ]
}
},
"/v2/historicalChainTvl/{chain}": {
@@ -297,7 +350,19 @@
"404": {
"description": "Chain not found"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.tvl.getHistoricalChainTvl('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.tvl.getHistoricalChainTvl()"
+ }
+ ]
}
},
"/tvl/{protocol}": {
@@ -333,7 +398,19 @@
"404": {
"description": "Protocol not found"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.tvl.getTvl('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.tvl.getTvl('')"
+ }
+ ]
}
},
"/v2/chains": {
@@ -390,7 +467,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.tvl.getChains()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.tvl.getChains()"
+ }
+ ]
}
},
"/prices/current/{coins}": {
@@ -467,7 +556,19 @@
"502": {
"description": "Internal error"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getCurrentPrices([''])"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getCurrentPrices([''])"
+ }
+ ]
}
},
"/prices/historical/{timestamp}/{coins}": {
@@ -554,7 +655,19 @@
"502": {
"description": "Internal error"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getHistoricalPrices(1704067200, [''])"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getHistoricalPrices(1704067200, [''])"
+ }
+ ]
}
},
"/batchHistorical": {
@@ -639,7 +752,19 @@
"502": {
"description": "Internal error"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getBatchHistoricalPrices({ '': [1704067200] })"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getBatchHistoricalPrices([''], '')"
+ }
+ ]
}
},
"/chart/{coins}": {
@@ -768,7 +893,19 @@
"502": {
"description": "Internal error"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getChart([''])"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getChart([''])"
+ }
+ ]
}
},
"/percentage/{coins}": {
@@ -848,7 +985,19 @@
"502": {
"description": "Internal error"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getPercentageChange([''])"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getPercentageChange([''])"
+ }
+ ]
}
},
"/prices/first/{coins}": {
@@ -910,7 +1059,19 @@
"502": {
"description": "Internal error"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getFirstPrices([''])"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getFirstPrices([''])"
+ }
+ ]
}
},
"/block/{chain}/{timestamp}": {
@@ -971,7 +1132,19 @@
"400": {
"description": "Invalid chain or timestamp provided"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getBlockAtTimestamp('', 1704067200)"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getBlockAtTimestamp('', 1704067200)"
+ }
+ ]
}
},
"/stablecoins": {
@@ -1073,7 +1246,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.stablecoins.getStablecoins()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.stablecoins.getStablecoins()"
+ }
+ ]
}
},
"/stablecoincharts/all": {
@@ -1126,7 +1311,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.stablecoins.getAllCharts()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.stablecoins.getAllCharts()"
+ }
+ ]
}
},
"/stablecoincharts/{chain}": {
@@ -1189,7 +1386,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.stablecoins.getChartsByChain('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.stablecoins.getChartsByChain('')"
+ }
+ ]
}
},
"/stablecoin/{asset}": {
@@ -1273,7 +1482,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.stablecoins.getStablecoin('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.stablecoins.getStablecoin('')"
+ }
+ ]
}
},
"/stablecoinchains": {
@@ -1314,7 +1535,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.stablecoins.getChains()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.stablecoins.getChains()"
+ }
+ ]
}
},
"/stablecoinprices": {
@@ -1357,7 +1590,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.stablecoins.getPrices()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.stablecoins.getPrices()"
+ }
+ ]
}
},
"/pools": {
@@ -1465,7 +1710,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.yields.getPools()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.yields.getPools()"
+ }
+ ]
}
},
"/chart/{pool}": {
@@ -1534,7 +1791,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.yields.getPoolChart('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.yields.getPoolChart('')"
+ }
+ ]
}
},
"/overview/dexs": {
@@ -1644,7 +1913,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.volumes.getDexOverview()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.volumes.getDexOverview()"
+ }
+ ]
}
},
"/overview/dexs/{chain}": {
@@ -1728,7 +2009,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.volumes.getDexOverviewByChain('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.volumes.getDexOverviewByChain('')"
+ }
+ ]
}
},
"/summary/dexs/{protocol}": {
@@ -1824,7 +2117,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.volumes.getDexSummary('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.volumes.getDexSummary('')"
+ }
+ ]
}
},
"/overview/options": {
@@ -1909,7 +2214,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.volumes.getOptionsOverview()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.volumes.getOptionsOverview()"
+ }
+ ]
}
},
"/overview/options/{chain}": {
@@ -1968,7 +2285,19 @@
"200": {
"description": "successful operation"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.volumes.getOptionsOverviewByChain('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.volumes.getOptionsOverviewByChain('')"
+ }
+ ]
}
},
"/summary/options/{protocol}": {
@@ -2007,7 +2336,19 @@
"200": {
"description": "successful operation"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.volumes.getOptionsSummary('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.volumes.getOptionsSummary('')"
+ }
+ ]
}
},
"/overview/open-interest": {
@@ -2226,7 +2567,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.fees.getOverview()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.fees.getOverview()"
+ }
+ ]
}
},
"/overview/fees/{chain}": {
@@ -2345,7 +2698,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.fees.getOverviewByChain('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.fees.getOverviewByChain('')"
+ }
+ ]
}
},
"/summary/fees/{protocol}": {
@@ -2655,7 +3020,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.fees.getSummary('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.fees.getSummary('')"
+ }
+ ]
}
}
}
diff --git a/defillama-openapi-pro.json b/defillama-openapi-pro.json
index fee5344f89d..c5948d7d456 100644
--- a/defillama-openapi-pro.json
+++ b/defillama-openapi-pro.json
@@ -3,7 +3,24 @@
"info": {
"title": "DefiLlama Pro - OpenAPI 3.0",
"version": "1.0.0",
- "description": "Docs for DefiLlama's Pro API \n\n\n Coding with AI? Paste this link to LLM-specific docs for best results \nllms.txt"
+ "description": "Docs for DefiLlama's Pro API\n\nSDK\n\nInstall:\n```bash\nnpm install @defillama/api\npip install defillama-sdk\n```\n\nQuick start (JavaScript):\n```ts\nimport { DefiLlama } from '@defillama/api'\n\nconst proClient = new DefiLlama({ apiKey: 'your-api-key' })\nconst protocols = await proClient.tvl.getProtocols()\n```\n\nQuick start (Python):\n```py\nfrom defillama_sdk import DefiLlama\n\npro_client = DefiLlama({\"api_key\": \"your-api-key\"})\nprotocols = pro_client.tvl.getProtocols()\n```\n\nCoding with AI? Paste this link to LLM-specific docs for best results\nllms.txt",
+ "x-scalar-sdk-installation": [
+ {
+ "lang": "node",
+ "description": "Install the DefiLlama JavaScript SDK:",
+ "source": "npm install @defillama/api"
+ },
+ {
+ "lang": "js",
+ "description": "Install the DefiLlama JavaScript SDK:",
+ "source": "npm install @defillama/api"
+ },
+ {
+ "lang": "python",
+ "description": "Install the DefiLlama Python SDK:",
+ "source": "pip install defillama-sdk"
+ }
+ ]
},
"servers": [
{
@@ -109,7 +126,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.tvl.getTokenProtocols('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.tvl.getTokenProtocols('')"
+ }
+ ]
}
},
"/api/inflows/{protocol}/{timestamp}": {
@@ -251,7 +280,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.tvl.getInflows('', 1704067200, 1704153600)"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.tvl.getInflows('', 1704067200, 1704153600)"
+ }
+ ]
}
},
"/api/chainAssets": {
@@ -369,7 +410,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.tvl.getChainAssets()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.tvl.getChainAssets()"
+ }
+ ]
}
},
"/stablecoins/stablecoindominance/{chain}": {
@@ -453,7 +506,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.stablecoins.getDominance('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.stablecoins.getDominance('')"
+ }
+ ]
}
},
"/api/emissions": {
@@ -568,7 +633,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.emissions.getAll()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.emissions.getAll()"
+ }
+ ]
}
},
"/api/emission/{protocol}": {
@@ -841,7 +918,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.emissions.getByProtocol('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.emissions.getByProtocol('')"
+ }
+ ]
}
},
"/api/categories": {
@@ -977,7 +1066,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.ecosystem.getCategories()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.ecosystem.getCategories()"
+ }
+ ]
}
},
"/api/forks": {
@@ -1086,7 +1187,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.ecosystem.getForks()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.ecosystem.getForks()"
+ }
+ ]
}
},
"/api/oracles": {
@@ -1188,7 +1301,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.ecosystem.getOracles()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.ecosystem.getOracles()"
+ }
+ ]
}
},
"/api/hacks": {
@@ -1263,7 +1388,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.ecosystem.getHacks()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.ecosystem.getHacks()"
+ }
+ ]
}
},
"/api/raises": {
@@ -1353,7 +1490,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.ecosystem.getRaises()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.ecosystem.getRaises()"
+ }
+ ]
}
},
"/api/treasuries": {
@@ -1509,7 +1658,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.ecosystem.getTreasuries()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.ecosystem.getTreasuries()"
+ }
+ ]
}
},
"/api/entities": {
@@ -1642,7 +1803,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.ecosystem.getEntities()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.ecosystem.getEntities()"
+ }
+ ]
}
},
"/api/historicalLiquidity/{token}": {
@@ -1829,7 +2002,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.yields.getPools()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.yields.getPools()"
+ }
+ ]
}
},
"/yields/poolsOld": {
@@ -2025,7 +2210,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.yields.getPoolsOld()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.yields.getPoolsOld()"
+ }
+ ]
}
},
"/yields/chart/{pool}": {
@@ -2097,7 +2294,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.yields.getPoolChart('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.yields.getPoolChart('')"
+ }
+ ]
}
},
"/yields/poolsBorrow": {
@@ -2293,7 +2502,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.yields.getBorrowPools()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.yields.getBorrowPools()"
+ }
+ ]
}
},
"/yields/chartLendBorrow/{pool}": {
@@ -2370,7 +2591,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.yields.getLendBorrowChart('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.yields.getLendBorrowChart('')"
+ }
+ ]
}
},
"/yields/perps": {
@@ -2459,7 +2692,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.yields.getPerps()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.yields.getPerps()"
+ }
+ ]
}
},
"/yields/lsdRates": {
@@ -2527,7 +2772,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.yields.getLsdRates()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.yields.getLsdRates()"
+ }
+ ]
}
},
"/etfs/snapshot": {
@@ -2610,7 +2867,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.etfs.getOverview()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.etfs.getOverview()"
+ }
+ ]
}
},
"/etfs/flows": {
@@ -2653,7 +2922,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.etfs.getHistory()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.etfs.getHistory()"
+ }
+ ]
}
},
"/fdv/performance/{period}": {
@@ -2808,7 +3089,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.etfs.getFdvPerformance('30')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.etfs.getFdvPerformance('30')"
+ }
+ ]
}
},
"/api/overview/derivatives": {
@@ -3201,7 +3494,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.volumes.getDerivativesOverview()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.volumes.getDerivativesOverview()"
+ }
+ ]
}
},
"/api/summary/derivatives/{protocol}": {
@@ -3524,7 +3829,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.volumes.getDerivativesSummary('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.volumes.getDerivativesSummary('')"
+ }
+ ]
}
},
"/bridges/bridges": {
@@ -3660,7 +3977,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.bridges.getAll()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.bridges.getAll()"
+ }
+ ]
}
},
"/bridges/bridge/{id}": {
@@ -3930,7 +4259,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.bridges.getById(1)"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.bridges.getById('')"
+ }
+ ]
}
},
"/bridges/bridgevolume/{chain}": {
@@ -4017,7 +4358,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.bridges.getVolumeByChain('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.bridges.getVolumeByChain('')"
+ }
+ ]
}
},
"/bridges/bridgedaystats/{timestamp}/{chain}": {
@@ -4214,7 +4567,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.bridges.getDayStats(1704067200, '')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.bridges.getDayStats(1704067200, '')"
+ }
+ ]
}
},
"/bridges/transactions/{id}": {
@@ -4696,7 +5061,19 @@
}
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.bridges.getTransactions(1)"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.bridges.getTransactions('')"
+ }
+ ]
}
},
"/usage/APIKEY": {
@@ -4713,7 +5090,19 @@
"description": "credits left"
}
},
- "x-api-plan-only": true
+ "x-api-plan-only": true,
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.account.getUsage()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.account.getUsage()"
+ }
+ ]
}
},
"/api/protocols": {
@@ -4781,7 +5170,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.tvl.getProtocols()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.tvl.getProtocols()"
+ }
+ ]
}
},
"/api/protocol/{protocol}": {
@@ -4895,7 +5296,19 @@
"404": {
"description": "Protocol not found"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.tvl.getProtocol('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.tvl.getProtocol('')"
+ }
+ ]
}
},
"/api/v2/historicalChainTvl": {
@@ -4928,7 +5341,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.tvl.getHistoricalChainTvl()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.tvl.getHistoricalChainTvl()"
+ }
+ ]
}
},
"/api/v2/historicalChainTvl/{chain}": {
@@ -4976,7 +5401,19 @@
"404": {
"description": "Chain not found"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.tvl.getHistoricalChainTvl('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.tvl.getHistoricalChainTvl()"
+ }
+ ]
}
},
"/api/tvl/{protocol}": {
@@ -5012,7 +5449,19 @@
"404": {
"description": "Protocol not found"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.tvl.getTvl('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.tvl.getTvl('')"
+ }
+ ]
}
},
"/api/v2/chains": {
@@ -5069,7 +5518,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.tvl.getChains()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.tvl.getChains()"
+ }
+ ]
}
},
"/coins/prices/current/{coins}": {
@@ -5141,7 +5602,19 @@
"502": {
"description": "Internal error"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getCurrentPrices([''])"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getCurrentPrices([''])"
+ }
+ ]
}
},
"/coins/prices/historical/{timestamp}/{coins}": {
@@ -5223,7 +5696,19 @@
"502": {
"description": "Internal error"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getHistoricalPrices(1704067200, [''])"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getHistoricalPrices(1704067200, [''])"
+ }
+ ]
}
},
"/coins/batchHistorical": {
@@ -5303,7 +5788,19 @@
"502": {
"description": "Internal error"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getBatchHistoricalPrices({ '': [1704067200] })"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getBatchHistoricalPrices([''], '')"
+ }
+ ]
}
},
"/coins/chart/{coins}": {
@@ -5427,7 +5924,19 @@
"502": {
"description": "Internal error"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getChart([''])"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getChart([''])"
+ }
+ ]
}
},
"/coins/percentage/{coins}": {
@@ -5502,7 +6011,19 @@
"502": {
"description": "Internal error"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getPercentageChange([''])"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getPercentageChange([''])"
+ }
+ ]
}
},
"/coins/prices/first/{coins}": {
@@ -5559,7 +6080,19 @@
"502": {
"description": "Internal error"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getFirstPrices([''])"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getFirstPrices([''])"
+ }
+ ]
}
},
"/coins/block/{chain}/{timestamp}": {
@@ -5615,7 +6148,19 @@
"400": {
"description": "Invalid chain or timestamp provided"
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.prices.getBlockAtTimestamp('', 1704067200)"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.prices.getBlockAtTimestamp('', 1704067200)"
+ }
+ ]
}
},
"/stablecoins/stablecoins": {
@@ -5712,7 +6257,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.stablecoins.getStablecoins()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.stablecoins.getStablecoins()"
+ }
+ ]
}
},
"/stablecoins/stablecoincharts/all": {
@@ -5760,7 +6317,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.stablecoins.getAllCharts()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.stablecoins.getAllCharts()"
+ }
+ ]
}
},
"/stablecoins/stablecoincharts/{chain}": {
@@ -5818,7 +6387,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.stablecoins.getChartsByChain('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.stablecoins.getChartsByChain('')"
+ }
+ ]
}
},
"/stablecoins/stablecoin/{asset}": {
@@ -5897,7 +6478,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.stablecoins.getStablecoin('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.stablecoins.getStablecoin('')"
+ }
+ ]
}
},
"/stablecoins/stablecoinchains": {
@@ -5933,7 +6526,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.stablecoins.getChains()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.stablecoins.getChains()"
+ }
+ ]
}
},
"/stablecoins/stablecoinprices": {
@@ -5971,7 +6576,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.stablecoins.getPrices()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.stablecoins.getPrices()"
+ }
+ ]
}
},
"/api/overview/dexs": {
@@ -6076,7 +6693,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.volumes.getDexOverview()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.volumes.getDexOverview()"
+ }
+ ]
}
},
"/api/overview/dexs/{chain}": {
@@ -6155,7 +6784,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.volumes.getDexOverviewByChain('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.volumes.getDexOverviewByChain('')"
+ }
+ ]
}
},
"/api/summary/dexs/{protocol}": {
@@ -6246,7 +6887,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.volumes.getDexSummary('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.volumes.getDexSummary('')"
+ }
+ ]
}
},
"/api/overview/options": {
@@ -6326,7 +6979,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.volumes.getOptionsOverview()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.volumes.getOptionsOverview()"
+ }
+ ]
}
},
"/api/overview/options/{chain}": {
@@ -6745,7 +7410,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.volumes.getOptionsOverviewByChain('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.volumes.getOptionsOverviewByChain('')"
+ }
+ ]
}
},
"/api/summary/options/{protocol}": {
@@ -7060,7 +7737,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.volumes.getOptionsSummary('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.volumes.getOptionsSummary('')"
+ }
+ ]
}
},
"/api/overview/open-interest": {
@@ -7269,7 +7958,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.fees.getOverview()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.fees.getOverview()"
+ }
+ ]
}
},
"/api/overview/fees/{chain}": {
@@ -7383,7 +8084,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.fees.getOverviewByChain('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.fees.getOverviewByChain('')"
+ }
+ ]
}
},
"/api/summary/fees/{protocol}": {
@@ -7688,7 +8401,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await client.fees.getSummary('')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = client.fees.getSummary('')"
+ }
+ ]
}
},
"/dat/institutions": {
@@ -7978,7 +8703,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.dat.getInstitutions()"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.dat.getInstitutions()"
+ }
+ ]
}
},
"/dat/institutions/{symbol}": {
@@ -8328,7 +9065,19 @@
}
}
}
- }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "javascript",
+ "label": "JavaScript SDK",
+ "source": "const result = await proClient.dat.getInstitution('MSTR')"
+ },
+ {
+ "lang": "python",
+ "label": "Python SDK",
+ "source": "result = pro_client.dat.getInstitution('')"
+ }
+ ]
}
}
}
diff --git a/packages/api-reference/src/v2/blocks/scalar-request-example-block/components/RequestExample.vue b/packages/api-reference/src/v2/blocks/scalar-request-example-block/components/RequestExample.vue
index 2dbca96cba8..3efc0c3ea5f 100644
--- a/packages/api-reference/src/v2/blocks/scalar-request-example-block/components/RequestExample.vue
+++ b/packages/api-reference/src/v2/blocks/scalar-request-example-block/components/RequestExample.vue
@@ -173,16 +173,12 @@ const localSelectedClient = ref(
findClient(clients.value, selectedClient),
)
-/** If the globally selected client changes we can update the local one */
-watch(
- () => selectedClient,
- (newClient) => {
- const client = findClient(clients.value, newClient)
- if (client) {
- localSelectedClient.value = client
- }
- },
-)
+watch([() => selectedClient, clients], ([newClient]) => {
+ const client = findClient(clients.value, newClient)
+ if (client) {
+ localSelectedClient.value = client
+ }
+})
/** Generate the code snippet for the selected example */
const generatedCode = computed(() => {
diff --git a/packages/api-reference/src/v2/blocks/scalar-request-example-block/helpers/find-client.ts b/packages/api-reference/src/v2/blocks/scalar-request-example-block/helpers/find-client.ts
index 252927a27e3..306e755eb6b 100644
--- a/packages/api-reference/src/v2/blocks/scalar-request-example-block/helpers/find-client.ts
+++ b/packages/api-reference/src/v2/blocks/scalar-request-example-block/helpers/find-client.ts
@@ -2,6 +2,33 @@ import type { ClientOption, ClientOptionGroup } from '@/v2/blocks/scalar-request
import { AVAILABLE_CLIENTS, type AvailableClients } from '@scalar/snippetz'
const DEFAULT_CLIENT = 'shell/curl'
+const TARGET_LANG_ALIASES: Record = {
+ js: ['js', 'javascript'],
+ javascript: ['js', 'javascript'],
+ node: ['node'],
+ python: ['python'],
+ ruby: ['ruby'],
+ php: ['php'],
+ shell: ['shell', 'curl'],
+}
+
+const findCustomByTarget = (clientGroups: ClientOptionGroup[], targetKey: string) => {
+ const aliases = TARGET_LANG_ALIASES[targetKey] ?? [targetKey]
+ const normalizedAliases = aliases.map((alias) => alias.toLowerCase())
+ for (const group of clientGroups) {
+ const option = group.options.find((candidate) => {
+ if (!candidate.id.startsWith('custom/')) {
+ return false
+ }
+ const lang = `${candidate.lang ?? ''}`.toLowerCase()
+ return normalizedAliases.includes(lang)
+ })
+ if (option) {
+ return option
+ }
+ }
+ return undefined
+}
/** Type guard to check if a string is a valid client id */
export const isClient = (id: any): id is AvailableClients[number] => AVAILABLE_CLIENTS.includes(id)
@@ -48,6 +75,11 @@ export const findClient = (
// Client ID is passed in
if (clientId) {
+ const targetKey = clientId.split('/')[0]
+ const customOption = findCustomByTarget(clientGroups, targetKey)
+ if (customOption) {
+ return customOption
+ }
for (const group of clientGroups) {
const option = group.options.find((option) => option.id === clientId)
if (option) {
diff --git a/scripts/defillama-python-sdk-snippets.mjs b/scripts/defillama-python-sdk-snippets.mjs
new file mode 100644
index 00000000000..1e4c652d245
--- /dev/null
+++ b/scripts/defillama-python-sdk-snippets.mjs
@@ -0,0 +1,193 @@
+import { readFile, writeFile } from 'node:fs/promises'
+import { resolve } from 'node:path'
+
+const sdkSource = await readFile(resolve('sdks/python_sdk.xml'), 'utf8')
+
+const moduleRegex = /([\s\S]*?)<\/file>/g
+const pathMappings = new Map()
+
+const variableAliases = new Map([
+ ['coins_param', 'coins'],
+ ['start_timestamp', 'timestamp'],
+ ['api_key', 'APIKEY'],
+ ['bridge_id', 'id'],
+])
+
+const normalizeVariableName = (name) => variableAliases.get(name) ?? name
+
+const normalizeFStringPath = (value) => {
+ const withoutQuote = value.replace(/\{quote\(([^)]+)\)\}/g, (_, name) => `{${normalizeVariableName(name)}}`)
+ return withoutQuote.replace(/\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g, (_, name) => `{${normalizeVariableName(name)}}`)
+}
+
+const signatureToRequiredParams = (signature) => {
+ const start = signature.indexOf('(')
+ const end = signature.lastIndexOf(')')
+ if (start === -1 || end === -1 || end <= start) {
+ return []
+ }
+ const paramsSection = signature.slice(start + 1, end)
+ const parts = paramsSection
+ .split(',')
+ .map((part) => part.trim())
+ .filter(Boolean)
+ return parts
+ .filter((part) => !part.startsWith('self'))
+ .filter((part) => !part.includes('='))
+ .map((part) => part.split(':')[0].trim())
+}
+
+const placeholderByParam = {
+ protocol: "''",
+ chain: "''",
+ coins: "['']",
+ timestamp: '1704067200',
+ start_timestamp: '1704067200',
+ end_timestamp: '1704153600',
+ pool: "''",
+ symbol: "''",
+ asset: "''",
+ id: '1',
+ period: "'30'",
+ token: "''",
+}
+
+const buildArgs = (params) => params.map((param) => placeholderByParam[param] ?? `'<${param}>'`)
+
+const extractMethodMappings = (moduleName, content) => {
+ const lines = content.split('\n')
+ const mappings = []
+ const indices = []
+ lines.forEach((line, index) => {
+ if (/^\s*def\s+\w+\s*\(/.test(line)) {
+ indices.push(index)
+ }
+ })
+
+ indices.forEach((startIndex, index) => {
+ const endIndex = indices[index + 1] ?? lines.length
+ const blockLines = lines.slice(startIndex, endIndex)
+ const block = blockLines.join('\n')
+ const signatureLines = []
+ for (const line of blockLines) {
+ signatureLines.push(line)
+ if (line.trim().endsWith(':') && line.includes(')')) {
+ break
+ }
+ }
+ const signature = signatureLines.join(' ')
+ const methodMatch = signature.match(/def\s+(\w+)\s*\(/)
+ if (!methodMatch) {
+ return
+ }
+ const methodName = methodMatch[1]
+ const requiredParams = signatureToRequiredParams(signature)
+ const args = buildArgs(requiredParams)
+ const requiresAuth = /requires_auth=True/.test(block)
+ const getMatches = [...block.matchAll(/self\._client\.get\(\s*(f?)(["'])([\s\S]*?)\2/g)]
+ if (!getMatches.length) {
+ return
+ }
+ getMatches.forEach((match) => {
+ const isFString = match[1] === 'f'
+ const rawPath = match[3]
+ const path = isFString ? normalizeFStringPath(rawPath) : rawPath
+ mappings.push({
+ path,
+ module: moduleName,
+ method: methodName,
+ args,
+ requiresAuth,
+ })
+ })
+ })
+
+ return mappings
+}
+
+for (const match of sdkSource.matchAll(moduleRegex)) {
+ const moduleFile = match[1]
+ const content = match[2]
+ const moduleName = moduleFile.replace('.py', '')
+ const mappings = extractMethodMappings(moduleName, content)
+ mappings.forEach((mapping) => {
+ if (!pathMappings.has(mapping.path)) {
+ pathMappings.set(mapping.path, mapping)
+ }
+ })
+}
+
+const overviewMapping = pathMappings.get('/overview')
+if (overviewMapping && !pathMappings.has('/snapshot')) {
+ pathMappings.set('/snapshot', overviewMapping)
+}
+const historyMapping = pathMappings.get('/history')
+if (historyMapping && !pathMappings.has('/flows')) {
+ pathMappings.set('/flows', historyMapping)
+}
+
+pathMappings.set('/usage/APIKEY', {
+ path: '/usage/APIKEY',
+ module: 'account',
+ method: 'getUsage',
+ args: [],
+ requiresAuth: true,
+})
+
+const prefixes = ['/api', '/coins', '/stablecoins', '/bridges', '/yields', '/etfs', '/fdv', '/dat']
+
+const resolveMapping = (path) => {
+ if (pathMappings.has(path)) {
+ return pathMappings.get(path)
+ }
+ for (const prefix of prefixes) {
+ if (path.startsWith(`${prefix}/`)) {
+ const basePath = path.slice(prefix.length)
+ if (pathMappings.has(basePath)) {
+ return pathMappings.get(basePath)
+ }
+ }
+ }
+ return null
+}
+
+const buildSnippet = (mapping) => {
+ const clientName = mapping.requiresAuth ? 'pro_client' : 'client'
+ const args = mapping.args.length ? mapping.args.join(', ') : ''
+ return `result = ${clientName}.${mapping.module}.${mapping.method}(${args})`
+}
+
+const updateSpec = (spec, filePath) => {
+ const missing = []
+ for (const [path, methods] of Object.entries(spec.paths || {})) {
+ for (const [method, operation] of Object.entries(methods)) {
+ const mapping = resolveMapping(path)
+ if (!mapping) {
+ missing.push(`${method.toUpperCase()} ${path}`)
+ continue
+ }
+ const existingSamples = Array.isArray(operation['x-codeSamples']) ? operation['x-codeSamples'] : []
+ const nextSamples = existingSamples.filter((sample) => sample?.lang !== 'python')
+ nextSamples.push({
+ lang: 'python',
+ label: 'Python SDK',
+ source: buildSnippet(mapping),
+ })
+ operation['x-codeSamples'] = nextSamples
+ }
+ }
+ if (missing.length) {
+ console.log(`${filePath}: ${missing.length} unmapped operations`)
+ missing.forEach((entry) => console.log(`${filePath}: ${entry}`))
+ } else {
+ console.log(`${filePath}: all operations mapped`)
+ }
+}
+
+const files = [resolve('defillama-openapi-free.json'), resolve('defillama-openapi-pro.json')]
+
+for (const filePath of files) {
+ const spec = JSON.parse(await readFile(filePath, 'utf8'))
+ updateSpec(spec, filePath)
+ await writeFile(filePath, `${JSON.stringify(spec, null, 2)}\n`)
+}
diff --git a/scripts/defillama-sdk-snippets.mjs b/scripts/defillama-sdk-snippets.mjs
new file mode 100644
index 00000000000..f93a08ef63f
--- /dev/null
+++ b/scripts/defillama-sdk-snippets.mjs
@@ -0,0 +1,134 @@
+import { readFile, writeFile } from 'node:fs/promises'
+import { resolve } from 'node:path'
+
+const mapEntry = (module, method, args = [], requiresAuth = false) => ({
+ module,
+ method,
+ args,
+ requiresAuth,
+})
+
+const baseMappings = new Map([
+ ['/protocols', mapEntry('tvl', 'getProtocols')],
+ ['/protocol/{protocol}', mapEntry('tvl', 'getProtocol', ["''"])],
+ ['/v2/historicalChainTvl', mapEntry('tvl', 'getHistoricalChainTvl')],
+ ['/v2/historicalChainTvl/{chain}', mapEntry('tvl', 'getHistoricalChainTvl', ["''"])],
+ ['/tvl/{protocol}', mapEntry('tvl', 'getTvl', ["''"])],
+ ['/v2/chains', mapEntry('tvl', 'getChains')],
+ ['/tokenProtocols/{symbol}', mapEntry('tvl', 'getTokenProtocols', ["''"], true)],
+ [
+ '/inflows/{protocol}/{timestamp}',
+ mapEntry('tvl', 'getInflows', ["''", '1704067200', '1704153600'], true),
+ ],
+ ['/chainAssets', mapEntry('tvl', 'getChainAssets', [], true)],
+ ['/prices/current/{coins}', mapEntry('prices', 'getCurrentPrices', ["['']"])],
+ ['/prices/historical/{timestamp}/{coins}', mapEntry('prices', 'getHistoricalPrices', ['1704067200', "['']"])],
+ ['/batchHistorical', mapEntry('prices', 'getBatchHistoricalPrices', ["{ '': [1704067200] }"])],
+ ['/chart/{coins}', mapEntry('prices', 'getChart', ["['']"])],
+ ['/percentage/{coins}', mapEntry('prices', 'getPercentageChange', ["['']"])],
+ ['/prices/first/{coins}', mapEntry('prices', 'getFirstPrices', ["['']"])],
+ ['/block/{chain}/{timestamp}', mapEntry('prices', 'getBlockAtTimestamp', ["''", '1704067200'])],
+ ['/stablecoins', mapEntry('stablecoins', 'getStablecoins')],
+ ['/stablecoincharts/all', mapEntry('stablecoins', 'getAllCharts')],
+ ['/stablecoincharts/{chain}', mapEntry('stablecoins', 'getChartsByChain', ["''"])],
+ ['/stablecoin/{asset}', mapEntry('stablecoins', 'getStablecoin', ["''"])],
+ ['/stablecoinchains', mapEntry('stablecoins', 'getChains')],
+ ['/stablecoinprices', mapEntry('stablecoins', 'getPrices')],
+ ['/stablecoindominance/{chain}', mapEntry('stablecoins', 'getDominance', ["''"], true)],
+ ['/pools', mapEntry('yields', 'getPools', [], true)],
+ ['/poolsOld', mapEntry('yields', 'getPoolsOld', [], true)],
+ ['/chart/{pool}', mapEntry('yields', 'getPoolChart', ["''"], true)],
+ ['/poolsBorrow', mapEntry('yields', 'getBorrowPools', [], true)],
+ ['/chartLendBorrow/{pool}', mapEntry('yields', 'getLendBorrowChart', ["''"], true)],
+ ['/perps', mapEntry('yields', 'getPerps', [], true)],
+ ['/lsdRates', mapEntry('yields', 'getLsdRates', [], true)],
+ ['/overview/dexs', mapEntry('volumes', 'getDexOverview')],
+ ['/overview/dexs/{chain}', mapEntry('volumes', 'getDexOverviewByChain', ["''"])],
+ ['/summary/dexs/{protocol}', mapEntry('volumes', 'getDexSummary', ["''"])],
+ ['/overview/options', mapEntry('volumes', 'getOptionsOverview')],
+ ['/overview/options/{chain}', mapEntry('volumes', 'getOptionsOverviewByChain', ["''"])],
+ ['/summary/options/{protocol}', mapEntry('volumes', 'getOptionsSummary', ["''"])],
+ ['/overview/derivatives', mapEntry('volumes', 'getDerivativesOverview', [], true)],
+ ['/summary/derivatives/{protocol}', mapEntry('volumes', 'getDerivativesSummary', ["''"], true)],
+ ['/overview/fees', mapEntry('fees', 'getOverview')],
+ ['/overview/fees/{chain}', mapEntry('fees', 'getOverviewByChain', ["''"])],
+ ['/summary/fees/{protocol}', mapEntry('fees', 'getSummary', ["''"])],
+ ['/emissions', mapEntry('emissions', 'getAll', [], true)],
+ ['/emission/{protocol}', mapEntry('emissions', 'getByProtocol', ["''"], true)],
+ ['/categories', mapEntry('ecosystem', 'getCategories', [], true)],
+ ['/forks', mapEntry('ecosystem', 'getForks', [], true)],
+ ['/oracles', mapEntry('ecosystem', 'getOracles', [], true)],
+ ['/hacks', mapEntry('ecosystem', 'getHacks', [], true)],
+ ['/raises', mapEntry('ecosystem', 'getRaises', [], true)],
+ ['/treasuries', mapEntry('ecosystem', 'getTreasuries', [], true)],
+ ['/entities', mapEntry('ecosystem', 'getEntities', [], true)],
+ ['/bridges', mapEntry('bridges', 'getAll')],
+ ['/bridge/{id}', mapEntry('bridges', 'getById', ['1'])],
+ ['/bridgevolume/{chain}', mapEntry('bridges', 'getVolumeByChain', ["''"])],
+ ['/bridgedaystats/{timestamp}/{chain}', mapEntry('bridges', 'getDayStats', ['1704067200', "''"])],
+ ['/transactions/{id}', mapEntry('bridges', 'getTransactions', ['1'])],
+ ['/snapshot', mapEntry('etfs', 'getOverview', [], true)],
+ ['/flows', mapEntry('etfs', 'getHistory', [], true)],
+ ['/performance/{period}', mapEntry('etfs', 'getFdvPerformance', ["'30'"], true)],
+ ['/institutions', mapEntry('dat', 'getInstitutions', [], true)],
+ ['/institutions/{symbol}', mapEntry('dat', 'getInstitution', ["'MSTR'"], true)],
+ ['/usage/APIKEY', mapEntry('account', 'getUsage', [], true)],
+])
+
+const prefixes = ['/api', '/coins', '/stablecoins', '/bridges', '/yields', '/etfs', '/fdv', '/dat']
+
+const resolveMapping = (path) => {
+ if (baseMappings.has(path)) {
+ return baseMappings.get(path)
+ }
+ for (const prefix of prefixes) {
+ if (path.startsWith(`${prefix}/`)) {
+ const basePath = path.slice(prefix.length)
+ if (baseMappings.has(basePath)) {
+ return baseMappings.get(basePath)
+ }
+ }
+ }
+ return null
+}
+
+const buildSnippet = (mapping) => {
+ const clientName = mapping.requiresAuth ? 'proClient' : 'client'
+ const args = mapping.args.length ? mapping.args.join(', ') : ''
+ return `const result = await ${clientName}.${mapping.module}.${mapping.method}(${args})`
+}
+
+const updateSpec = (spec, filePath) => {
+ const missing = []
+ for (const [path, methods] of Object.entries(spec.paths || {})) {
+ for (const [method, operation] of Object.entries(methods)) {
+ const mapping = resolveMapping(path)
+ if (!mapping) {
+ missing.push(`${method.toUpperCase()} ${path}`)
+ continue
+ }
+ const existingSamples = Array.isArray(operation['x-codeSamples']) ? operation['x-codeSamples'] : []
+ const nextSamples = existingSamples.filter((sample) => sample?.lang !== 'javascript')
+ nextSamples.push({
+ lang: 'javascript',
+ label: 'JavaScript SDK',
+ source: buildSnippet(mapping),
+ })
+ operation['x-codeSamples'] = nextSamples
+ }
+ }
+ if (missing.length) {
+ console.log(`${filePath}: ${missing.length} unmapped operations`)
+ missing.forEach((entry) => console.log(`${filePath}: ${entry}`))
+ } else {
+ console.log(`${filePath}: all operations mapped`)
+ }
+}
+
+const files = [resolve('defillama-openapi-free.json'), resolve('defillama-openapi-pro.json')]
+
+for (const filePath of files) {
+ const spec = JSON.parse(await readFile(filePath, 'utf8'))
+ updateSpec(spec, filePath)
+ await writeFile(filePath, `${JSON.stringify(spec, null, 2)}\n`)
+}