@defillama/sdk 5.0.234 → 5.0.236

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/build/ChainApi.d.ts +23 -1
  2. package/build/ChainApi.js +1 -0
  3. package/build/abi/multicall3.js +4 -0
  4. package/build/chains/algorand.d.ts +277 -0
  5. package/build/chains/algorand.js +618 -0
  6. package/build/chains/aptos.d.ts +230 -0
  7. package/build/chains/aptos.js +612 -0
  8. package/build/chains/cardano.d.ts +242 -0
  9. package/build/chains/cardano.js +407 -0
  10. package/build/chains/cosmos.d.ts +252 -0
  11. package/build/chains/cosmos.js +618 -0
  12. package/build/chains/icp.d.ts +235 -0
  13. package/build/chains/icp.js +1040 -0
  14. package/build/chains/index.d.ts +23 -0
  15. package/build/chains/index.js +59 -0
  16. package/build/chains/near.d.ts +192 -0
  17. package/build/chains/near.js +446 -0
  18. package/build/chains/rpc.d.ts +125 -0
  19. package/build/chains/rpc.js +326 -0
  20. package/build/chains/starknet.d.ts +205 -0
  21. package/build/chains/starknet.js +884 -0
  22. package/build/chains/stellar.d.ts +410 -0
  23. package/build/chains/stellar.js +1082 -0
  24. package/build/chains/substrate.d.ts +333 -0
  25. package/build/chains/substrate.js +1042 -0
  26. package/build/chains/sui.d.ts +365 -0
  27. package/build/chains/sui.js +1135 -0
  28. package/build/chains/svm.d.ts +340 -0
  29. package/build/chains/svm.js +760 -0
  30. package/build/chains/tezos.d.ts +225 -0
  31. package/build/chains/tezos.js +412 -0
  32. package/build/chains/ton.d.ts +353 -0
  33. package/build/chains/ton.js +788 -0
  34. package/build/chains/tron.d.ts +45 -0
  35. package/build/chains/tron.js +110 -0
  36. package/build/chains/utxo.d.ts +202 -0
  37. package/build/chains/utxo.js +592 -0
  38. package/build/chains/xrpl.d.ts +179 -0
  39. package/build/chains/xrpl.js +467 -0
  40. package/build/index.d.ts +2 -1
  41. package/build/index.js +3 -1
  42. package/build/providers.json +1 -1
  43. package/build/util/chainUtils/data.json +16 -1
  44. package/build/util/chainUtils/index.d.ts +1 -0
  45. package/build/util/chainUtils/index.js +23 -0
  46. package/build/util/common.js +2 -3
  47. package/build/util/cosmos.d.ts +1 -11
  48. package/build/util/cosmos.js +6 -66
  49. package/build/util/env.js +1 -0
  50. package/build/util/indexer.compatibility.d.ts +6 -0
  51. package/build/util/indexer.compatibility.js +64 -0
  52. package/build/util/indexer.d.ts +24 -2
  53. package/build/util/indexer.js +215 -285
  54. package/build/util/indexerSql.d.ts +8 -1
  55. package/build/util/indexerSql.js +53 -22
  56. package/build/util/logs.decode.shared.js +5 -4
  57. package/build/util/logs.js +1 -2
  58. package/build/util/transactions.d.ts +23 -1
  59. package/build/util/updateChainLabels.d.ts +1 -0
  60. package/build/util/updateChainLabels.js +5 -0
  61. package/build/util/updateProviderList.js +40 -17
  62. package/package.json +20 -7
  63. package/README.md +0 -41
@@ -1,2 +1,9 @@
1
+ export type IndexerSqlOptions = {
2
+ /** Accepted for compatibility with dimension-adapters; all chains use the same gateway. */
3
+ chain?: string;
4
+ signal?: AbortSignal;
5
+ };
1
6
  export declare function isIndexerSqlEnabled(): boolean;
2
- export declare function queryClickhouse<T = any>(sql: string, params?: Record<string, unknown>, settings?: Record<string, string | number>): Promise<T[]>;
7
+ export declare function queryClickhouse<T = any>(sql: string, params?: Record<string, unknown>, settings?: Record<string, string | number>, options?: IndexerSqlOptions): Promise<T[]>;
8
+ /** Gateway-oriented name; queryClickhouse remains available for existing consumers. */
9
+ export declare const queryIndexerSql: typeof queryClickhouse;
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.queryIndexerSql = void 0;
6
7
  exports.isIndexerSqlEnabled = isIndexerSqlEnabled;
7
8
  exports.queryClickhouse = queryClickhouse;
8
9
  const axios_1 = __importDefault(require("axios"));
@@ -11,40 +12,76 @@ const https_1 = __importDefault(require("https"));
11
12
  const env_1 = require("./env");
12
13
  const httpAgent = new http_1.default.Agent({ keepAlive: true, maxSockets: 64, maxFreeSockets: 16 });
13
14
  const httpsAgent = new https_1.default.Agent({ keepAlive: true, maxSockets: 64, maxFreeSockets: 16 });
14
- function sqlConfig() {
15
+ function getSqlConfig() {
16
+ const v4Endpoint = (0, env_1.getEnvValue)("LLAMA_INDEXER_V4_ENDPOINT");
15
17
  return {
16
- endpoint: (0, env_1.getEnvValue)("LLAMA_INDEXER_SQL_ENDPOINT"),
18
+ endpoint: (0, env_1.getEnvValue)("LLAMA_INDEXER_SQL_ENDPOINT") || (v4Endpoint ? `${v4Endpoint.replace(/\/+$/, "")}/sql` : undefined),
17
19
  user: (0, env_1.getEnvValue)("LLAMA_INDEXER_SQL_USER"),
18
20
  password: (0, env_1.getEnvValue)("LLAMA_INDEXER_SQL_PASSWORD"),
19
- timeoutMs: +(0, env_1.getEnvValue)("LLAMA_INDEXER_SQL_TIMEOUT_MS") || 180000,
20
21
  };
21
22
  }
23
+ // ClickHouse HTTP query parameters use escaped text, not JSON. Nested strings
24
+ // must be quoted, and UInt64/UInt256 values must never pass through Number().
25
+ function serializeQueryParameter(value, nested = false) {
26
+ if (value === null || value === undefined)
27
+ return nested ? "NULL" : "\\N";
28
+ if (typeof value === "string") {
29
+ const escaped = value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")
30
+ .replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
31
+ return nested ? `'${escaped}'` : escaped;
32
+ }
33
+ if (typeof value === "boolean")
34
+ return nested ? (value ? "TRUE" : "FALSE") : (value ? "1" : "0");
35
+ if (typeof value === "number") {
36
+ if (Number.isNaN(value))
37
+ return "nan";
38
+ if (!Number.isFinite(value))
39
+ return value > 0 ? "+inf" : "-inf";
40
+ return String(value);
41
+ }
42
+ if (typeof value === "bigint")
43
+ return String(value);
44
+ if (Array.isArray(value))
45
+ return `[${value.map((v) => serializeQueryParameter(v, true)).join(",")}]`;
46
+ if (value instanceof Date) {
47
+ const seconds = String(Math.floor(value.getTime() / 1000)).padStart(10, "0");
48
+ return value.getUTCMilliseconds() ? `${seconds}.${String(value.getUTCMilliseconds()).padStart(3, "0")}` : seconds;
49
+ }
50
+ if (typeof value === "object") {
51
+ const entries = value instanceof Map ? [...value.entries()] : Object.entries(value);
52
+ return `{${entries.map(([k, v]) => `${serializeQueryParameter(k, true)}:${serializeQueryParameter(v, true)}`).join(",")}}`;
53
+ }
54
+ throw new Error("Unsupported SQL query parameter type");
55
+ }
22
56
  function isIndexerSqlEnabled() {
23
- const c = sqlConfig();
57
+ const c = getSqlConfig();
24
58
  return !!(c.endpoint && c.user && c.password);
25
59
  }
26
- async function queryClickhouse(sql, params, settings) {
60
+ async function queryClickhouse(sql, params, settings, options = {}) {
27
61
  var _a, _b;
28
- const { endpoint, user, password, timeoutMs } = sqlConfig();
62
+ const { endpoint, user, password } = getSqlConfig();
29
63
  if (!endpoint || !user || !password) {
30
64
  throw new Error("Llama indexer SQL gateway not configured (LLAMA_INDEXER_SQL_ENDPOINT/USER/PASSWORD)");
31
65
  }
32
- const search = new URLSearchParams();
66
+ const url = new URL(endpoint);
67
+ const search = url.searchParams;
33
68
  search.set("default_format", "JSONEachRow");
34
- for (const [k, v] of Object.entries(params !== null && params !== void 0 ? params : {})) {
35
- search.set(`param_${k}`, typeof v === "object" ? JSON.stringify(v) : String(v));
69
+ for (const [name, value] of Object.entries(params !== null && params !== void 0 ? params : {})) {
70
+ search.set(`param_${name}`, serializeQueryParameter(value));
36
71
  }
37
- for (const [k, v] of Object.entries(settings !== null && settings !== void 0 ? settings : {})) {
38
- search.set(k, String(v));
72
+ for (const [name, value] of Object.entries(settings !== null && settings !== void 0 ? settings : {})) {
73
+ search.set(name, String(value));
39
74
  }
40
75
  let res;
41
76
  try {
42
- res = await axios_1.default.post(`${endpoint}?${search.toString()}`, sql, {
77
+ res = await axios_1.default.post(url.toString(), sql, {
43
78
  auth: { username: user, password },
44
79
  headers: { "Content-Type": "text/plain; charset=utf-8" },
45
80
  responseType: "text",
46
81
  transformResponse: (d) => d,
47
- timeout: timeoutMs,
82
+ // The gateway owns execution deadlines. Callers can still cancel a request.
83
+ timeout: 0,
84
+ signal: options.signal,
48
85
  maxBodyLength: Infinity,
49
86
  maxContentLength: Infinity,
50
87
  httpAgent,
@@ -59,13 +96,7 @@ async function queryClickhouse(sql, params, settings) {
59
96
  return parseJsonEachRow(res.data);
60
97
  }
61
98
  function parseJsonEachRow(text) {
62
- if (!text)
63
- return [];
64
- const out = [];
65
- for (const line of text.split("\n")) {
66
- if (!line)
67
- continue;
68
- out.push(JSON.parse(line));
69
- }
70
- return out;
99
+ return text.split("\n").filter(line => line.trim()).map(line => JSON.parse(line));
71
100
  }
101
+ /** Gateway-oriented name; queryClickhouse remains available for existing consumers. */
102
+ exports.queryIndexerSql = queryClickhouse;
@@ -19,11 +19,12 @@ function padTopic32(t) {
19
19
  return ('0x' + hex.padStart(64, '0'));
20
20
  }
21
21
  function normalizeLog(log, isIndexerCall = false) {
22
+ var _a, _b, _c, _d;
22
23
  if (isIndexerCall || log.source) {
23
- log.address = log.source;
24
- log.logIndex = log.log_index;
25
- log.index = log.log_index;
26
- log.transactionHash = log.transaction_hash;
24
+ log.address = (_a = log.source) !== null && _a !== void 0 ? _a : log.address;
25
+ log.logIndex = (_c = (_b = log.log_index) !== null && _b !== void 0 ? _b : log.logIndex) !== null && _c !== void 0 ? _c : log.index;
26
+ log.index = log.logIndex;
27
+ log.transactionHash = (_d = log.transaction_hash) !== null && _d !== void 0 ? _d : log.transactionHash;
27
28
  log.blockNumber = parseInt(log.block_number || log.blockNumber || 0);
28
29
  const topics = [log.topic0, log.topic1, log.topic2, log.topic3]
29
30
  .filter(Boolean)
@@ -366,8 +366,7 @@ async function getLogParams(options, isIndexerCall = false) {
366
366
  }
367
367
  if (!parsed && !parseFailureTolerated)
368
368
  throw new Error(`Failed to parse log: ${JSON.stringify(log.transactionHash)}`);
369
- // tolerated failures must stay visible: a targeted call where logs silently fail
370
- // to decode is usually a bug in the caller eventAbi (warn once per call)
369
+ // keep tolerated failures visible (once per call)
371
370
  if (!parsed && !allowParseFailure && !parseFailureWarned) {
372
371
  parseFailureWarned = true;
373
372
  console.warn(`[sdk.getLogs] some logs did not decode against the provided eventAbi and were returned without .args ` +
@@ -10,4 +10,26 @@ export interface GetTransactionOptions {
10
10
  debugMode?: boolean;
11
11
  transactionType?: 'from' | 'to' | 'all';
12
12
  }
13
- export declare function getTransactions(params: GetTransactionOptions): Promise<any>;
13
+ export declare function getTransactions(params: GetTransactionOptions): Promise<{
14
+ hash: any;
15
+ blockNumber: number;
16
+ transactionIndex: number;
17
+ from: any;
18
+ to: any;
19
+ value: any;
20
+ gasPrice: any;
21
+ gas: any;
22
+ input: any;
23
+ nonce: number;
24
+ data: any;
25
+ type: any;
26
+ maxFeePerGas: any;
27
+ maxPriorityFeePerGas: any;
28
+ baseFeePerGas: any;
29
+ effectiveGasPrice: any;
30
+ gasUsed: any;
31
+ cumulativeGasUsed: any;
32
+ status: number;
33
+ contractCreated: any;
34
+ timestamp: any;
35
+ }[] | null>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const chainUtils_1 = require("./chainUtils");
4
+ // pulls latest chain key <-> label mappings and dead chain list from the llama api and writes them to chainUtils/data.json
5
+ (0, chainUtils_1.updateChainLabels)();
@@ -29,27 +29,19 @@ async function getChainData() {
29
29
  }
30
30
  }
31
31
  async function main() {
32
- const chainKeyLabelMapCountBefore = Object.keys(chainUtils_1.chainKeyToChainLabelMap).length;
33
- const chainLabelsKeyMapCountBefore = Object.keys(chainUtils_1.chainLabelsToKeyMap).length;
34
- await (0, chainUtils_1.updateData)();
35
- const chainKeyLabelMapCountAfter = Object.keys(chainUtils_1.chainKeyToChainLabelMap).length;
36
- const chainLabelsKeyMapCountAfter = Object.keys(chainUtils_1.chainLabelsToKeyMap).length;
37
- if (chainKeyLabelMapCountAfter > chainKeyLabelMapCountBefore) {
38
- console.log(`Updated chainKeyToChainLabelMap: ${chainKeyLabelMapCountBefore} -> ${chainKeyLabelMapCountAfter}`);
39
- }
40
- if (chainLabelsKeyMapCountAfter > chainLabelsKeyMapCountBefore) {
41
- console.log(`Updated chainLabelsToKeyMap: ${chainLabelsKeyMapCountBefore} -> ${chainLabelsKeyMapCountAfter}`);
42
- }
43
- if (chainKeyLabelMapCountAfter < chainKeyLabelMapCountBefore)
44
- throw new Error('chainKeyToChainLabelMap count decreased, please investigate');
45
- if (chainLabelsKeyMapCountAfter < chainLabelsKeyMapCountBefore)
46
- throw new Error('chainLabelsToKeyMap count decreased, please investigate');
32
+ await (0, chainUtils_1.updateChainLabels)();
47
33
  const oldProviders = await (0, generalUtil_1.fetchJson)(`https://unpkg.com/@defillama/sdk@latest/build/providers.json`);
48
34
  const currentChains = await (0, generalUtil_1.fetchJson)(`https://raw.githubusercontent.com/DefiLlama/DefiLlama-Adapters/refs/heads/main/projects/helper/chains.json`);
49
35
  const currentChainsSet = new Set(currentChains);
50
36
  let chainData = await getChainData();
51
37
  const providerIDMap = {};
52
- Object.values(providerList).forEach((i) => providerIDMap[i.chainId] = i.rpc);
38
+ const chainIdToKeyMap = {};
39
+ Object.entries(providerList).forEach(([key, i]) => {
40
+ providerIDMap[i.chainId] = i.rpc;
41
+ chainIdToKeyMap[i.chainId] = key;
42
+ });
43
+ const shortNameToKeyMap = {};
44
+ Object.entries(chainShortNameMapping).forEach(([key, shortName]) => shortNameToKeyMap[shortName] = key);
53
45
  chainData = chainData
54
46
  .filter((i) => i.rpc.length)
55
47
  // .filter((i: any) => !i.status || (i.status === 'active' || i.status === 'incubating'))
@@ -93,12 +85,39 @@ async function main() {
93
85
  });
94
86
  // shuffle the array
95
87
  chainData.sort(() => Math.random() - 0.5);
88
+ // chain keys this chain could end up under in providers.json
89
+ const getCandidateKeys = (i) => {
90
+ const keys = [i.shortName.toLowerCase().replace(/-/g, '_')];
91
+ if (chainIdToKeyMap[i.chainId])
92
+ keys.push(chainIdToKeyMap[i.chainId]);
93
+ if (shortNameToKeyMap[i.shortName])
94
+ keys.push(shortNameToKeyMap[i.shortName]);
95
+ return keys;
96
+ };
97
+ // only check rpc health for chains we track and that are not dead, the rest are only filtered statically
98
+ const shouldCheckRPCs = (i) => {
99
+ const keys = getCandidateKeys(i);
100
+ const isTracked = keys.some((k) => currentChainsSet.has(k));
101
+ const isDead = keys.some((k) => (0, chainUtils_1.isDeadChain)(k));
102
+ return isTracked && !isDead;
103
+ };
104
+ const skippedRPCChecks = { dead: 0, untracked: 0 };
96
105
  await promise_pool_1.default
97
106
  .withConcurrency(concurrentCheckChains)
98
107
  .for(chainData)
99
108
  .process(async (i) => {
100
109
  var _a, _b;
101
- i.rpc = await filterForWorkingRPCs(i.rpc.map((j) => j.url), i.name, i.chainId);
110
+ const rpcs = i.rpc.map((j) => j.url);
111
+ if (shouldCheckRPCs(i)) {
112
+ i.rpc = await filterForWorkingRPCs(rpcs, i.name, i.chainId);
113
+ }
114
+ else {
115
+ if (getCandidateKeys(i).some((k) => (0, chainUtils_1.isDeadChain)(k)))
116
+ skippedRPCChecks.dead++;
117
+ else
118
+ skippedRPCChecks.untracked++;
119
+ i.rpc = rpcs.length < 4 ? rpcs : filterRPCs(rpcs);
120
+ }
102
121
  if (!i.rpc.length)
103
122
  return;
104
123
  if (providerIDMap[i.chainId]) {
@@ -158,6 +177,8 @@ async function main() {
158
177
  const rpcCountOld = Object.values(oldProviders).reduce((acc, i) => { var _a; return acc + ((_a = i === null || i === void 0 ? void 0 : i.rpc.length) !== null && _a !== void 0 ? _a : 0); }, 0);
159
178
  const newlyAddedChains = Object.keys(providerList).filter(chain => oldProviders[chain] === undefined);
160
179
  console.log('Final provider list:');
180
+ console.log('Skipped rpc checks (dead chains):', skippedRPCChecks.dead);
181
+ console.log('Skipped rpc checks (untracked chains):', skippedRPCChecks.untracked);
161
182
  console.log('Chain count:', Object.keys(providerList).length);
162
183
  console.log('Newly added chains count:', newlyAddedChains.length);
163
184
  console.log('Dropped chain count:', filteredDroppedChains.length);
@@ -213,6 +234,8 @@ const chainShortNameMapping = {
213
234
  mantra: 'mantrachain',
214
235
  saga: 'sagaevm',
215
236
  robinhood: 'robinhoodchain',
237
+ bcypher: 'bchyper',
238
+ area: 'areum',
216
239
  };
217
240
  async function filterForWorkingRPCs(rpc, chain, chainId) {
218
241
  if (rpc.length < 4)
package/package.json CHANGED
@@ -1,21 +1,21 @@
1
1
  {
2
2
  "name": "@defillama/sdk",
3
- "version": "5.0.234",
3
+ "version": "5.0.236",
4
4
  "description": "SDK for calculating TVL",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
7
7
  "start": "npm run build && node build/index.js",
8
8
  "pack-and-publish": "bash ./scripts/skipTestPatchAndPublish.sh",
9
9
  "build": "tsc",
10
- "watch": "tsc --watch",
11
10
  "load-providers": "mkdir -p build && wget https://unpkg.com/@defillama/sdk@latest/build/providers.json -O build/providers.json",
12
11
  "test": "npm run load-providers && TEST_MODE=true LLAMA_DEBUG_MODE='' SDK_DEBUG='' LLAMA_DEBUG_LEVEL2='' LLAMA_DEBUG_LEVEL3='' jest",
13
12
  "test-only": "echo 'skipped building providers.json' && TEST_MODE=true LLAMA_DEBUG_MODE='' SDK_DEBUG='' LLAMA_DEBUG_LEVEL2='' LLAMA_DEBUG_LEVEL3='' jest",
14
- "test-debug": "TEST_MODE=true jest",
15
- "test-indexer": "TEST_MODE=true jest src/util/indexer.routing.test.ts src/util/indexer.test.ts src/util/indexer.robinhood.test.ts src/util/indexer.e2e.test.ts --runInBand",
13
+ "test-debug": "TEST_MODE=true JEST_VERBOSE=true jest",
14
+ "test-indexer": "jest --runInBand --runTestsByPath src/util/indexer.test.ts src/util/indexer.e2e.test.ts src/util/indexerSql.test.ts src/util/indexerSql.parity.test.ts",
15
+ "test-indexer-unit": "jest --runInBand --runTestsByPath src/util/indexer.test.ts src/util/indexerSql.test.ts",
16
16
  "update-providers": "ts-node src/util/updateProviderList.ts",
17
+ "update-chain-labels": "ts-node src/util/updateChainLabels.ts",
17
18
  "remove-rpcs": "ts-node src/util/removeRedundantRPCs.ts",
18
- "format": "prettier --write \"src/**/*.ts\"",
19
19
  "prepublishOnly": "npm run build"
20
20
  },
21
21
  "repository": {
@@ -23,10 +23,14 @@
23
23
  "url": "git+https://github.com/DefiLlama/defillama-sdk.git"
24
24
  },
25
25
  "author": "",
26
- "license": "ISC",
27
26
  "types": "build/index.d.ts",
28
27
  "files": [
29
- "build"
28
+ "build",
29
+ "!build/**/*.test.js",
30
+ "!build/abi/largeMulticall.d.ts",
31
+ "!build/abi/largeMulticall.js",
32
+ "!build/**/*.test.d.ts",
33
+ "!build/**/*.test.js.map"
30
34
  ],
31
35
  "dependencies": {
32
36
  "@aws-sdk/client-s3": "^3.400.0",
@@ -39,8 +43,17 @@
39
43
  "tron-format-address": "^0.1.11",
40
44
  "viem": "^2.38.6"
41
45
  },
46
+ "peerDependencies": {
47
+ "@solana/web3.js": ">=1.73.0"
48
+ },
49
+ "peerDependenciesMeta": {
50
+ "@solana/web3.js": {
51
+ "optional": true
52
+ }
53
+ },
42
54
  "devDependencies": {
43
55
  "@types/jest": "^29.2.3",
56
+ "@types/node": "^24.8.1",
44
57
  "@types/stream-json": "^1.7.8",
45
58
  "jest": "^29.3.1",
46
59
  "ts-jest": "^29.1.1",
package/README.md DELETED
@@ -1,41 +0,0 @@
1
- # sdk
2
-
3
- ```
4
- npm i
5
- npm run build
6
- npm t
7
- npm run format
8
- ```
9
-
10
- ### Publish
11
- ```
12
- bash patchAndPublish.sh
13
- ```
14
-
15
- ### Keys
16
-
17
- ```
18
- POLYGON_RPC="https://..."
19
- ETHEREUM_RPC="https://..."
20
- BSC_RPC="https://..."
21
- ```
22
-
23
- ### Environment variables
24
-
25
- Most settings can be overridden per chain via environment variables. The chain
26
- name is uppercased and used as a prefix, e.g. `ETHEREUM_RPC`, `BSC_RPC_MULTICALL_V3`.
27
- Every key is also resolved with an `SDK_` or `LLAMA_SDK_` prefix (checked in the
28
- order `LLAMA_SDK_<KEY>` → `SDK_<KEY>` → `<KEY>`), so `SDK_ETHEREUM_RPC` works too.
29
-
30
- | Variable | Description |
31
- | --- | --- |
32
- | `<CHAIN>_RPC` | RPC URL(s) for the chain (comma-separated for multiple). |
33
- | `<CHAIN>_RPC_MULTICALL_V3` | Address of a Multicall3 contract for the chain. Setting it enables the Multicall3 code path for that chain (even if the chain is not in the built-in registry) and uses this address. Takes precedence over the built-in registry and the deployment-block gating. |
34
- | `<CHAIN>_RPC_MULTICALL` | Address of a legacy (v2) multicall contract, used only when Multicall3 is not available for the chain. |
35
- | `<CHAIN>_MULTICALL_CHUNK_SIZE` | Max number of calls per multicall batch for the chain. |
36
-
37
- ## Chain RPC PR
38
-
39
- Before putting up a PR for new chain, check if we already support it here: https://unpkg.com/@defillama/sdk@latest/build/providers.json
40
-
41
- Everytime we publish a new sdk version, we automically pull latest list from chainlist.org and include it.