@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
@@ -0,0 +1,225 @@
1
+ /** TzKT indexer base url, overridable with `TEZOS_TZKT` (also `SDK_` / `LLAMA_SDK_` prefixed). */
2
+ export declare const DEFAULT_TZKT = "https://api.tzkt.io";
3
+ /** Tezos node RPC endpoints, overridable with `TEZOS_RPC` (comma separated). */
4
+ export declare const DEFAULT_RPC_ENDPOINTS: string[];
5
+ export declare const MUTEZ_PER_TEZ = 1000000;
6
+ export declare const MAINNET_CHAIN_ID = "NetXdQprcVkpaWU";
7
+ /** All configured TzKT base urls (env `TEZOS_TZKT` wins, then `DEFAULT_TZKT`). */
8
+ export declare function getTzktEndpoints(): string[];
9
+ /** First configured TzKT base url. */
10
+ export declare function getTzktEndpoint(): string;
11
+ /** Node RPC endpoints (env `TEZOS_RPC` wins, then `DEFAULT_RPC_ENDPOINTS`). */
12
+ export declare function getRpcEndpoints(): string[];
13
+ export type NumLike = string | number | bigint;
14
+ export interface TzktOptions {
15
+ /** path under the TzKT base url, e.g. `/v1/head` */
16
+ path: string;
17
+ /** query string parameters (TzKT filter syntax, e.g. `{ 'balance.gt': 0 }`) */
18
+ params?: Record<string, any>;
19
+ timeout?: number;
20
+ retries?: number;
21
+ }
22
+ export interface TzktAllOptions extends TzktOptions {
23
+ /** page size, default 1000 (TzKT max 10000) */
24
+ limit?: number;
25
+ /** starting offset, default 0 */
26
+ offset?: number;
27
+ /** stop after this many pages (safety valve), default unlimited */
28
+ maxPages?: number;
29
+ }
30
+ export interface TokenBalance {
31
+ /** token contract address (`'tezos'` for the native balance when `includeTezos` is set) */
32
+ contract: string;
33
+ /** token id within the contract as a decimal string (`'0'` for FA1.2) */
34
+ tokenId: string;
35
+ /** raw balance in token base units */
36
+ balance: string;
37
+ /** parsed from `token.metadata.decimals`; undefined when metadata is missing */
38
+ decimals?: number;
39
+ symbol?: string;
40
+ name?: string;
41
+ /** `fa1.2` | `fa2` | `native` */
42
+ standard: string;
43
+ }
44
+ export interface TokenInfo {
45
+ contract: string;
46
+ tokenId: string;
47
+ /** raw total supply in token base units */
48
+ totalSupply: string;
49
+ decimals?: number;
50
+ symbol?: string;
51
+ name?: string;
52
+ standard: string;
53
+ /** TzKT internal token id */
54
+ id?: number;
55
+ metadata?: Record<string, any>;
56
+ }
57
+ export interface BlockInfo {
58
+ /** block level */
59
+ number: number;
60
+ /** unix timestamp in seconds */
61
+ timestamp: number;
62
+ hash: string;
63
+ }
64
+ /** tz1 / tz2 / tz3 / tz4 implicit accounts and KT1 originated contracts (36 chars, base58). */
65
+ export declare function isTezosAddress(str: any): boolean;
66
+ /** KT1 originated contract address. */
67
+ export declare function isContractAddress(str: any): boolean;
68
+ /**
69
+ * Coerce a decimal / hex / scientific-notation string, number or bigint to BigInt.
70
+ * Fractional parts are truncated. Empty / null values become 0.
71
+ */
72
+ export declare function toBigInt(value: NumLike | null | undefined): bigint;
73
+ /** mutez (1e-6 tez) -> tez as a JS number. */
74
+ export declare function mutezToTez(mutez: NumLike): number;
75
+ /**
76
+ * Parse `metadata.decimals` (string or number). Unlike the pegged-assets helper,
77
+ * `0` is a valid result and is not replaced by the fallback.
78
+ */
79
+ export declare function parseDecimals(value: any): number | undefined;
80
+ /**
81
+ * Turn a TzKT big map key list into a `{ key: value }` object. Object keys
82
+ * (pairs) are indexed by their `hash`, mirroring the adapters' getBigMapById.
83
+ */
84
+ export declare function bigMapKeysToObject(keys: any[]): Record<string, any>;
85
+ /** Raw TzKT GET (rate limited, rotates configured base urls, retried). */
86
+ export declare function tzkt({ path, params, timeout, retries }: TzktOptions): Promise<any>;
87
+ /**
88
+ * Fetch every page of a TzKT list endpoint using `offset` / `limit` paging.
89
+ * Stops when a page comes back shorter than `limit` or `maxPages` is reached.
90
+ */
91
+ export declare function tzktAll({ path, params, limit, offset, maxPages, timeout, retries }: TzktAllOptions): Promise<any[]>;
92
+ /** `/v1/accounts/{address}` */
93
+ export declare function getAccount({ address }: {
94
+ address: string;
95
+ }): Promise<any>;
96
+ /** Native tez balance in mutez as a decimal string. */
97
+ export declare function getBalance({ address }: {
98
+ address: string;
99
+ }): Promise<string>;
100
+ export interface GetTokenBalancesOptions {
101
+ address: string;
102
+ /** also append the native tez balance as `{ contract: 'tezos', standard: 'native' }`, default false */
103
+ includeTezos?: boolean;
104
+ /** keep entries with a zero balance, default false */
105
+ includeZero?: boolean;
106
+ /** extra TzKT filters, e.g. `{ 'token.standard': 'fa2' }` */
107
+ filters?: Record<string, any>;
108
+ limit?: number;
109
+ maxPages?: number;
110
+ }
111
+ /**
112
+ * All FA1.2 / FA2 token balances held by `address` (every page), with
113
+ * `decimals` / `symbol` parsed from the token metadata when available.
114
+ */
115
+ export declare function getTokenBalances({ address, includeTezos, includeZero, filters, limit, maxPages }: GetTokenBalancesOptions): Promise<TokenBalance[]>;
116
+ /** Raw balance of one token (`contract` + `tokenId`) held by `address`; `'0'` when not found. */
117
+ export declare function getTokenBalance({ address, contract, tokenId }: {
118
+ address: string;
119
+ contract: string;
120
+ tokenId?: NumLike;
121
+ }): Promise<string>;
122
+ /** Token info from `/v1/tokens?contract=&tokenId=`; throws when TzKT does not know the token. */
123
+ export declare function getToken({ contract, tokenId }: {
124
+ contract: string;
125
+ tokenId?: NumLike;
126
+ }): Promise<TokenInfo>;
127
+ /** Raw total supply of a token in base units. */
128
+ export declare function getTokenTotalSupply({ contract, tokenId }: {
129
+ contract: string;
130
+ tokenId?: NumLike;
131
+ }): Promise<string>;
132
+ /** Decoded contract storage (`/v1/contracts/{contract}/storage`), optionally at a past `level`. */
133
+ export declare function getContractStorage({ contract, level }: {
134
+ contract: string;
135
+ level?: number;
136
+ }): Promise<any>;
137
+ /** Big map descriptor by pointer (`/v1/bigmaps/{id}`). */
138
+ export declare function getBigMap({ id }: {
139
+ id: NumLike;
140
+ }): Promise<any>;
141
+ export interface GetBigMapKeysOptions {
142
+ id: NumLike;
143
+ limit?: number;
144
+ offset?: number;
145
+ maxPages?: number;
146
+ /** only active (non-removed) keys, default true */
147
+ active?: boolean;
148
+ /** TzKT `select` clause, e.g. `'key,value'` */
149
+ select?: string;
150
+ /** extra filters, e.g. `{ 'key.address': 'tz1...' }` or `{ value: '0' }` */
151
+ filters?: Record<string, any>;
152
+ }
153
+ /** All keys of a big map (every page). Use `bigMapKeysToObject` for a `{ key: value }` view. */
154
+ export declare function getBigMapKeys({ id, limit, offset, maxPages, active, select, filters }: GetBigMapKeysOptions): Promise<any[]>;
155
+ /** One big map entry by key (`/v1/bigmaps/{id}/keys/{key}`); undefined when missing. */
156
+ export declare function getBigMapKey({ id, key }: {
157
+ id: NumLike;
158
+ key: string;
159
+ }): Promise<any>;
160
+ /** Big map descriptor (including `ptr`) by storage path (`/v1/contracts/{contract}/bigmaps/{path}`). */
161
+ export declare function getBigMapByPath({ contract, path }: {
162
+ contract: string;
163
+ path: string;
164
+ }): Promise<any>;
165
+ /** Current head: `{ number: level, timestamp (unix seconds), hash }`. */
166
+ export declare function getHead(): Promise<BlockInfo>;
167
+ /** Block by level. */
168
+ export declare function getBlock({ level }: {
169
+ level: number | string;
170
+ }): Promise<BlockInfo>;
171
+ /** Latest block at or before `timestamp` (unix seconds, ms, ISO string or Date). */
172
+ export declare function getBlockAtTimestamp({ timestamp }: {
173
+ timestamp: number | string | Date;
174
+ }): Promise<BlockInfo>;
175
+ export interface GetOperationsOptions {
176
+ address: string;
177
+ /** comma separated TzKT operation types, e.g. `'transaction'` or `'transaction,origination'` */
178
+ type?: string;
179
+ /** inclusive lower bound (unix seconds, ms, ISO or Date) */
180
+ from?: number | string | Date;
181
+ /** inclusive upper bound (unix seconds, ms, ISO or Date) */
182
+ to?: number | string | Date;
183
+ /** `'asc'` (default) or `'desc'` */
184
+ sort?: 'asc' | 'desc';
185
+ /** page size, default 1000 */
186
+ limit?: number;
187
+ maxPages?: number;
188
+ /** extra filters, e.g. `{ entrypoint: 'transfer', status: 'applied' }` */
189
+ filters?: Record<string, any>;
190
+ }
191
+ /**
192
+ * Operations involving `address` (`/v1/accounts/{address}/operations`), every page.
193
+ * This endpoint pages with the `lastId` cursor rather than `offset`.
194
+ */
195
+ export declare function getOperations({ address, type, from, to, sort, limit, maxPages, filters }: GetOperationsOptions): Promise<any[]>;
196
+ /** Raw GET against the Tezos node RPC (rotates `TEZOS_RPC` endpoints, retried). */
197
+ export declare function rpcGet({ path, params, timeout, retries }: TzktOptions): Promise<any>;
198
+ /** Raw POST against the Tezos node RPC. */
199
+ export declare function rpcPost({ path, body, timeout, retries }: {
200
+ path: string;
201
+ body: any;
202
+ timeout?: number;
203
+ retries?: number;
204
+ }): Promise<any>;
205
+ /** Spendable balance in mutez straight from the node (`.../context/contracts/{address}/balance`). */
206
+ export declare function getContractBalanceRpc({ address, block }: {
207
+ address: string;
208
+ block?: string | number;
209
+ }): Promise<string>;
210
+ /** Chain id of the configured node (`/chains/main/chain_id`), cached. */
211
+ export declare function getChainId(): Promise<string>;
212
+ export interface RunViewOptions {
213
+ contract: string;
214
+ /** on-chain (TZIP-16 / Michelson) view name */
215
+ view: string;
216
+ /** Micheline JSON input, e.g. `{ string: 'tz1...' }` or `{ int: '0' }` */
217
+ input: any;
218
+ block?: string | number;
219
+ chainId?: string;
220
+ }
221
+ /**
222
+ * Execute an on-chain Michelson view via `run_script_view`. Returns the Micheline
223
+ * JSON result (`data`).
224
+ */
225
+ export declare function runView({ contract, view, input, block, chainId }: RunViewOptions): Promise<any>;
@@ -0,0 +1,412 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAINNET_CHAIN_ID = exports.MUTEZ_PER_TEZ = exports.DEFAULT_RPC_ENDPOINTS = exports.DEFAULT_TZKT = void 0;
4
+ exports.getTzktEndpoints = getTzktEndpoints;
5
+ exports.getTzktEndpoint = getTzktEndpoint;
6
+ exports.getRpcEndpoints = getRpcEndpoints;
7
+ exports.isTezosAddress = isTezosAddress;
8
+ exports.isContractAddress = isContractAddress;
9
+ exports.toBigInt = toBigInt;
10
+ exports.mutezToTez = mutezToTez;
11
+ exports.parseDecimals = parseDecimals;
12
+ exports.bigMapKeysToObject = bigMapKeysToObject;
13
+ exports.tzkt = tzkt;
14
+ exports.tzktAll = tzktAll;
15
+ exports.getAccount = getAccount;
16
+ exports.getBalance = getBalance;
17
+ exports.getTokenBalances = getTokenBalances;
18
+ exports.getTokenBalance = getTokenBalance;
19
+ exports.getToken = getToken;
20
+ exports.getTokenTotalSupply = getTokenTotalSupply;
21
+ exports.getContractStorage = getContractStorage;
22
+ exports.getBigMap = getBigMap;
23
+ exports.getBigMapKeys = getBigMapKeys;
24
+ exports.getBigMapKey = getBigMapKey;
25
+ exports.getBigMapByPath = getBigMapByPath;
26
+ exports.getHead = getHead;
27
+ exports.getBlock = getBlock;
28
+ exports.getBlockAtTimestamp = getBlockAtTimestamp;
29
+ exports.getOperations = getOperations;
30
+ exports.rpcGet = rpcGet;
31
+ exports.rpcPost = rpcPost;
32
+ exports.getContractBalanceRpc = getContractBalanceRpc;
33
+ exports.getChainId = getChainId;
34
+ exports.runView = runView;
35
+ /**
36
+ * Tezos client over the TzKT indexer API (`TEZOS_TZKT`, default https://api.tzkt.io)
37
+ * plus a few Tezos node RPC calls (`TEZOS_RPC`).
38
+ *
39
+ * Replaces the chain access parts of:
40
+ * - DefiLlama-Adapters projects/helper/chain/tezos.js (getTokenBalances,
41
+ * getTezosBalance, getStorage, getBigMapById)
42
+ * - peggedassets-server src/adapters/peggedAssets/helper/tezos.ts (getTotalSupply,
43
+ * getBalance)
44
+ *
45
+ * TVL coupling (tokenBlacklist, transformAddress, sumTokens, addDexPosition,
46
+ * resolveLPPosition) is intentionally left out; every function returns raw chain
47
+ * values (mutez / raw token units as decimal strings).
48
+ *
49
+ * Usage: `sdk.chains.tezos.getToken({ contract: 'KT1...', tokenId: 0 })`
50
+ */
51
+ const debugLog_1 = require("../util/debugLog");
52
+ const rpc_1 = require("./rpc");
53
+ // ---------------------------------------------------------------------------
54
+ // config
55
+ // ---------------------------------------------------------------------------
56
+ /** TzKT indexer base url, overridable with `TEZOS_TZKT` (also `SDK_` / `LLAMA_SDK_` prefixed). */
57
+ exports.DEFAULT_TZKT = 'https://api.tzkt.io';
58
+ /** Tezos node RPC endpoints, overridable with `TEZOS_RPC` (comma separated). */
59
+ exports.DEFAULT_RPC_ENDPOINTS = [
60
+ 'https://mainnet.api.tez.ie',
61
+ 'https://rpc.tzkt.io/mainnet',
62
+ ];
63
+ exports.MUTEZ_PER_TEZ = 1000000;
64
+ exports.MAINNET_CHAIN_ID = 'NetXdQprcVkpaWU';
65
+ const CHAIN = 'tezos';
66
+ const DEFAULT_CONCURRENCY = 10;
67
+ /** TzKT hard limit per request */
68
+ const TZKT_MAX_LIMIT = 10000;
69
+ /** All configured TzKT base urls (env `TEZOS_TZKT` wins, then `DEFAULT_TZKT`). */
70
+ function getTzktEndpoints() {
71
+ return (0, rpc_1.getEndpoints)(CHAIN, exports.DEFAULT_TZKT, { envKey: 'TEZOS_TZKT' });
72
+ }
73
+ /** First configured TzKT base url. */
74
+ function getTzktEndpoint() {
75
+ return getTzktEndpoints()[0];
76
+ }
77
+ /** Node RPC endpoints (env `TEZOS_RPC` wins, then `DEFAULT_RPC_ENDPOINTS`). */
78
+ function getRpcEndpoints() {
79
+ return (0, rpc_1.getEndpoints)(CHAIN, exports.DEFAULT_RPC_ENDPOINTS);
80
+ }
81
+ function limiter() {
82
+ return (0, rpc_1.getLimiter)(CHAIN.toUpperCase(), DEFAULT_CONCURRENCY);
83
+ }
84
+ // ---------------------------------------------------------------------------
85
+ // pure helpers
86
+ // ---------------------------------------------------------------------------
87
+ const ADDRESS_RE = /^(tz1|tz2|tz3|tz4|KT1)[1-9A-HJ-NP-Za-km-z]{33}$/;
88
+ const CONTRACT_RE = /^KT1[1-9A-HJ-NP-Za-km-z]{33}$/;
89
+ /** tz1 / tz2 / tz3 / tz4 implicit accounts and KT1 originated contracts (36 chars, base58). */
90
+ function isTezosAddress(str) {
91
+ return typeof str === 'string' && str.length === 36 && ADDRESS_RE.test(str);
92
+ }
93
+ /** KT1 originated contract address. */
94
+ function isContractAddress(str) {
95
+ return typeof str === 'string' && str.length === 36 && CONTRACT_RE.test(str);
96
+ }
97
+ /**
98
+ * Coerce a decimal / hex / scientific-notation string, number or bigint to BigInt.
99
+ * Fractional parts are truncated. Empty / null values become 0.
100
+ */
101
+ function toBigInt(value) {
102
+ if (value === null || value === undefined || value === '')
103
+ return BigInt(0);
104
+ if (typeof value === 'bigint')
105
+ return value;
106
+ if (typeof value === 'number') {
107
+ if (!Number.isFinite(value))
108
+ throw new Error(`toBigInt: not a finite number: ${value}`);
109
+ // BigInt accepts any integer-valued double, including those above MAX_SAFE_INTEGER
110
+ return BigInt(Math.trunc(value));
111
+ }
112
+ const s = String(value).trim();
113
+ if (/^-?\d+$/.test(s))
114
+ return BigInt(s);
115
+ if (/^-?0x[0-9a-f]+$/i.test(s))
116
+ return s.startsWith('-') ? -BigInt(s.slice(1)) : BigInt(s);
117
+ if (/^-?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i.test(s)) {
118
+ const n = Number(s);
119
+ if (!Number.isFinite(n))
120
+ throw new Error(`toBigInt: cannot parse ${s}`);
121
+ return toBigInt(n);
122
+ }
123
+ throw new Error(`toBigInt: cannot parse ${s}`);
124
+ }
125
+ /** mutez (1e-6 tez) -> tez as a JS number. */
126
+ function mutezToTez(mutez) {
127
+ return Number(toBigInt(mutez)) / exports.MUTEZ_PER_TEZ;
128
+ }
129
+ /**
130
+ * Parse `metadata.decimals` (string or number). Unlike the pegged-assets helper,
131
+ * `0` is a valid result and is not replaced by the fallback.
132
+ */
133
+ function parseDecimals(value) {
134
+ if (value === undefined || value === null || value === '')
135
+ return undefined;
136
+ const n = Number(value);
137
+ return Number.isFinite(n) ? n : undefined;
138
+ }
139
+ /**
140
+ * Turn a TzKT big map key list into a `{ key: value }` object. Object keys
141
+ * (pairs) are indexed by their `hash`, mirroring the adapters' getBigMapById.
142
+ */
143
+ function bigMapKeysToObject(keys) {
144
+ const res = {};
145
+ for (const entry of keys) {
146
+ const key = (typeof entry.key === 'object' && entry.hash) ? entry.hash : entry.key;
147
+ res[key] = entry.value;
148
+ }
149
+ return res;
150
+ }
151
+ function toIsoTimestamp(ts) {
152
+ if (ts instanceof Date)
153
+ return ts.toISOString();
154
+ if (typeof ts === 'string') {
155
+ if (/^\d+$/.test(ts))
156
+ return toIsoTimestamp(+ts);
157
+ return new Date(ts).toISOString();
158
+ }
159
+ // accept seconds or milliseconds
160
+ const ms = ts > 1e12 ? ts : ts * 1000;
161
+ return new Date(ms).toISOString();
162
+ }
163
+ function toBlockInfo(block) {
164
+ return {
165
+ number: block.level,
166
+ timestamp: Math.floor(new Date(block.timestamp).getTime() / 1000),
167
+ hash: block.hash,
168
+ };
169
+ }
170
+ function pickFirst(res) {
171
+ if (Array.isArray(res))
172
+ return res[0];
173
+ return res;
174
+ }
175
+ // ---------------------------------------------------------------------------
176
+ // TzKT transport
177
+ // ---------------------------------------------------------------------------
178
+ /** Raw TzKT GET (rate limited, rotates configured base urls, retried). */
179
+ async function tzkt({ path, params, timeout, retries }) {
180
+ return limiter()(() => (0, rpc_1.httpGet)(getTzktEndpoints(), { path, params, timeout, retries }));
181
+ }
182
+ /**
183
+ * Fetch every page of a TzKT list endpoint using `offset` / `limit` paging.
184
+ * Stops when a page comes back shorter than `limit` or `maxPages` is reached.
185
+ */
186
+ async function tzktAll({ path, params = {}, limit = 1000, offset = 0, maxPages, timeout, retries }) {
187
+ limit = Math.min(Math.max(1, limit), TZKT_MAX_LIMIT);
188
+ const res = [];
189
+ let page = 0;
190
+ while (true) {
191
+ const data = await tzkt({ path, params: { ...params, limit, offset }, timeout, retries });
192
+ if (!Array.isArray(data))
193
+ throw new Error(`tzktAll: expected an array from ${path}`);
194
+ res.push(...data);
195
+ page++;
196
+ if (data.length < limit)
197
+ break;
198
+ if (maxPages !== undefined && page >= maxPages) {
199
+ (0, debugLog_1.debugLog)(`[chains.tezos] tzktAll ${path}: stopped after ${maxPages} pages`);
200
+ break;
201
+ }
202
+ offset += limit;
203
+ }
204
+ return res;
205
+ }
206
+ // ---------------------------------------------------------------------------
207
+ // accounts & balances
208
+ // ---------------------------------------------------------------------------
209
+ /** `/v1/accounts/{address}` */
210
+ async function getAccount({ address }) {
211
+ return tzkt({ path: `/v1/accounts/${address}` });
212
+ }
213
+ /** Native tez balance in mutez as a decimal string. */
214
+ async function getBalance({ address }) {
215
+ const balance = await tzkt({ path: `/v1/accounts/${address}/balance` });
216
+ return toBigInt(balance).toString();
217
+ }
218
+ /**
219
+ * All FA1.2 / FA2 token balances held by `address` (every page), with
220
+ * `decimals` / `symbol` parsed from the token metadata when available.
221
+ */
222
+ async function getTokenBalances({ address, includeTezos = false, includeZero = false, filters = {}, limit, maxPages }) {
223
+ const params = { account: address, ...filters };
224
+ if (!includeZero)
225
+ params['balance.ne'] = '0';
226
+ const rows = await tzktAll({ path: '/v1/tokens/balances', params, limit, maxPages });
227
+ const res = rows.map((row) => {
228
+ var _a, _b, _c, _d, _e, _f;
229
+ const token = (_a = row.token) !== null && _a !== void 0 ? _a : {};
230
+ const metadata = (_b = token.metadata) !== null && _b !== void 0 ? _b : {};
231
+ return {
232
+ contract: (_d = (_c = token.contract) === null || _c === void 0 ? void 0 : _c.address) !== null && _d !== void 0 ? _d : token.contract,
233
+ tokenId: String((_e = token.tokenId) !== null && _e !== void 0 ? _e : '0'),
234
+ balance: String((_f = row.balance) !== null && _f !== void 0 ? _f : '0'),
235
+ decimals: parseDecimals(metadata.decimals),
236
+ symbol: metadata.symbol,
237
+ name: metadata.name,
238
+ standard: token.standard,
239
+ };
240
+ });
241
+ if (includeTezos) {
242
+ const balance = await getBalance({ address });
243
+ res.push({ contract: 'tezos', tokenId: '0', balance, decimals: 6, symbol: 'XTZ', name: 'Tezos', standard: 'native' });
244
+ }
245
+ return res;
246
+ }
247
+ /** Raw balance of one token (`contract` + `tokenId`) held by `address`; `'0'` when not found. */
248
+ async function getTokenBalance({ address, contract, tokenId = 0 }) {
249
+ var _a;
250
+ const rows = await tzkt({
251
+ path: '/v1/tokens/balances',
252
+ params: { account: address, 'token.contract': contract, 'token.tokenId': String(tokenId), select: 'balance', limit: 1 },
253
+ });
254
+ const first = pickFirst(rows);
255
+ if (first === undefined || first === null)
256
+ return '0';
257
+ return String(typeof first === 'object' ? (_a = first.balance) !== null && _a !== void 0 ? _a : '0' : first);
258
+ }
259
+ // ---------------------------------------------------------------------------
260
+ // tokens
261
+ // ---------------------------------------------------------------------------
262
+ /** Token info from `/v1/tokens?contract=&tokenId=`; throws when TzKT does not know the token. */
263
+ async function getToken({ contract, tokenId = 0 }) {
264
+ var _a, _b, _c, _d, _e;
265
+ const rows = await tzkt({ path: '/v1/tokens', params: { contract, tokenId: String(tokenId), limit: 1 } });
266
+ const token = pickFirst(rows);
267
+ if (!token)
268
+ throw new Error(`tezos: token ${contract}:${tokenId} not found on TzKT`);
269
+ const metadata = (_a = token.metadata) !== null && _a !== void 0 ? _a : {};
270
+ return {
271
+ contract: (_c = (_b = token.contract) === null || _b === void 0 ? void 0 : _b.address) !== null && _c !== void 0 ? _c : contract,
272
+ tokenId: String((_d = token.tokenId) !== null && _d !== void 0 ? _d : tokenId),
273
+ totalSupply: String((_e = token.totalSupply) !== null && _e !== void 0 ? _e : '0'),
274
+ decimals: parseDecimals(metadata.decimals),
275
+ symbol: metadata.symbol,
276
+ name: metadata.name,
277
+ standard: token.standard,
278
+ id: token.id,
279
+ metadata,
280
+ };
281
+ }
282
+ /** Raw total supply of a token in base units. */
283
+ async function getTokenTotalSupply({ contract, tokenId = 0 }) {
284
+ const token = await getToken({ contract, tokenId });
285
+ return token.totalSupply;
286
+ }
287
+ // ---------------------------------------------------------------------------
288
+ // contracts & big maps
289
+ // ---------------------------------------------------------------------------
290
+ /** Decoded contract storage (`/v1/contracts/{contract}/storage`), optionally at a past `level`. */
291
+ async function getContractStorage({ contract, level }) {
292
+ const params = {};
293
+ if (level !== undefined)
294
+ params.level = level;
295
+ return tzkt({ path: `/v1/contracts/${contract}/storage`, params });
296
+ }
297
+ /** Big map descriptor by pointer (`/v1/bigmaps/{id}`). */
298
+ async function getBigMap({ id }) {
299
+ return tzkt({ path: `/v1/bigmaps/${id}` });
300
+ }
301
+ /** All keys of a big map (every page). Use `bigMapKeysToObject` for a `{ key: value }` view. */
302
+ async function getBigMapKeys({ id, limit, offset, maxPages, active = true, select, filters = {} }) {
303
+ const params = { ...filters };
304
+ if (active)
305
+ params.active = true;
306
+ if (select)
307
+ params.select = select;
308
+ return tzktAll({ path: `/v1/bigmaps/${id}/keys`, params, limit, offset, maxPages });
309
+ }
310
+ /** One big map entry by key (`/v1/bigmaps/{id}/keys/{key}`); undefined when missing. */
311
+ async function getBigMapKey({ id, key }) {
312
+ const res = await tzkt({ path: `/v1/bigmaps/${id}/keys/${encodeURIComponent(key)}` });
313
+ if (res === '' || res === null)
314
+ return undefined;
315
+ return res;
316
+ }
317
+ /** Big map descriptor (including `ptr`) by storage path (`/v1/contracts/{contract}/bigmaps/{path}`). */
318
+ async function getBigMapByPath({ contract, path }) {
319
+ return tzkt({ path: `/v1/contracts/${contract}/bigmaps/${path}` });
320
+ }
321
+ // ---------------------------------------------------------------------------
322
+ // blocks
323
+ // ---------------------------------------------------------------------------
324
+ /** Current head: `{ number: level, timestamp (unix seconds), hash }`. */
325
+ async function getHead() {
326
+ const head = await tzkt({ path: '/v1/head' });
327
+ return toBlockInfo(head);
328
+ }
329
+ /** Block by level. */
330
+ async function getBlock({ level }) {
331
+ const block = await tzkt({ path: `/v1/blocks/${level}` });
332
+ return toBlockInfo(block);
333
+ }
334
+ /** Latest block at or before `timestamp` (unix seconds, ms, ISO string or Date). */
335
+ async function getBlockAtTimestamp({ timestamp }) {
336
+ const rows = await tzkt({
337
+ path: '/v1/blocks',
338
+ params: { 'timestamp.le': toIsoTimestamp(timestamp), 'sort.desc': 'level', limit: 1 },
339
+ });
340
+ const block = pickFirst(rows);
341
+ if (!block)
342
+ throw new Error(`tezos: no block at or before ${toIsoTimestamp(timestamp)}`);
343
+ return toBlockInfo(block);
344
+ }
345
+ /**
346
+ * Operations involving `address` (`/v1/accounts/{address}/operations`), every page.
347
+ * This endpoint pages with the `lastId` cursor rather than `offset`.
348
+ */
349
+ async function getOperations({ address, type, from, to, sort = 'asc', limit = 1000, maxPages, filters = {} }) {
350
+ limit = Math.min(Math.max(1, limit), 1000);
351
+ const params = { ...filters, limit, sort };
352
+ if (type)
353
+ params.type = type;
354
+ if (from !== undefined)
355
+ params['timestamp.ge'] = toIsoTimestamp(from);
356
+ if (to !== undefined)
357
+ params['timestamp.le'] = toIsoTimestamp(to);
358
+ const res = [];
359
+ let lastId;
360
+ let page = 0;
361
+ while (true) {
362
+ const data = await tzkt({ path: `/v1/accounts/${address}/operations`, params: lastId === undefined ? params : { ...params, lastId } });
363
+ if (!Array.isArray(data))
364
+ throw new Error('getOperations: expected an array');
365
+ res.push(...data);
366
+ page++;
367
+ if (data.length < limit)
368
+ break;
369
+ if (maxPages !== undefined && page >= maxPages) {
370
+ (0, debugLog_1.debugLog)(`[chains.tezos] getOperations ${address}: stopped after ${maxPages} pages`);
371
+ break;
372
+ }
373
+ lastId = data[data.length - 1].id;
374
+ }
375
+ return res;
376
+ }
377
+ // ---------------------------------------------------------------------------
378
+ // node RPC
379
+ // ---------------------------------------------------------------------------
380
+ /** Raw GET against the Tezos node RPC (rotates `TEZOS_RPC` endpoints, retried). */
381
+ async function rpcGet({ path, params, timeout, retries }) {
382
+ return limiter()(() => (0, rpc_1.httpGet)(getRpcEndpoints(), { path, params, timeout, retries }));
383
+ }
384
+ /** Raw POST against the Tezos node RPC. */
385
+ async function rpcPost({ path, body, timeout, retries }) {
386
+ return limiter()(() => (0, rpc_1.httpPost)(getRpcEndpoints(), body, { path, timeout, retries }));
387
+ }
388
+ /** Spendable balance in mutez straight from the node (`.../context/contracts/{address}/balance`). */
389
+ async function getContractBalanceRpc({ address, block = 'head' }) {
390
+ const balance = await rpcGet({ path: `/chains/main/blocks/${block}/context/contracts/${address}/balance` });
391
+ return toBigInt(balance).toString();
392
+ }
393
+ let cachedChainId;
394
+ /** Chain id of the configured node (`/chains/main/chain_id`), cached. */
395
+ async function getChainId() {
396
+ if (!cachedChainId)
397
+ cachedChainId = await rpcGet({ path: '/chains/main/chain_id' });
398
+ return cachedChainId;
399
+ }
400
+ /**
401
+ * Execute an on-chain Michelson view via `run_script_view`. Returns the Micheline
402
+ * JSON result (`data`).
403
+ */
404
+ async function runView({ contract, view, input, block = 'head', chainId }) {
405
+ var _a;
406
+ const chain_id = chainId !== null && chainId !== void 0 ? chainId : await getChainId();
407
+ const res = await rpcPost({
408
+ path: `/chains/main/blocks/${block}/helpers/scripts/run_script_view`,
409
+ body: { contract, view, input, chain_id, unlimited_gas: true },
410
+ });
411
+ return (_a = res === null || res === void 0 ? void 0 : res.data) !== null && _a !== void 0 ? _a : res;
412
+ }