@ledgerhq/coin-tezos 7.12.0 → 9.0.0
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.
- package/CHANGELOG.md +39 -0
- package/lib/api/index.d.ts +1 -2
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.js +45 -44
- package/lib/api/index.js.map +1 -1
- package/lib/api/types.d.ts +3 -2
- package/lib/api/types.d.ts.map +1 -1
- package/lib/config.d.ts +3 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js.map +1 -1
- package/lib/logic/broadcast.d.ts +2 -1
- package/lib/logic/broadcast.d.ts.map +1 -1
- package/lib/logic/broadcast.js +3 -2
- package/lib/logic/broadcast.js.map +1 -1
- package/lib/logic/combine.d.ts +1 -1
- package/lib/logic/combine.d.ts.map +1 -1
- package/lib/logic/combine.js +4 -1
- package/lib/logic/combine.js.map +1 -1
- package/lib/logic/craftRawOperations.d.ts +2 -1
- package/lib/logic/craftRawOperations.d.ts.map +1 -1
- package/lib/logic/craftRawOperations.js +5 -8
- package/lib/logic/craftRawOperations.js.map +1 -1
- package/lib/logic/craftTransaction.d.ts +3 -2
- package/lib/logic/craftTransaction.d.ts.map +1 -1
- package/lib/logic/craftTransaction.js +6 -9
- package/lib/logic/craftTransaction.js.map +1 -1
- package/lib/logic/estimateFees.d.ts +2 -1
- package/lib/logic/estimateFees.d.ts.map +1 -1
- package/lib/logic/estimateFees.js +24 -19
- package/lib/logic/estimateFees.js.map +1 -1
- package/lib/logic/getBalance.d.ts +2 -1
- package/lib/logic/getBalance.d.ts.map +1 -1
- package/lib/logic/getBalance.js +7 -8
- package/lib/logic/getBalance.js.map +1 -1
- package/lib/logic/getBlock.d.ts +2 -1
- package/lib/logic/getBlock.d.ts.map +1 -1
- package/lib/logic/getBlock.js +12 -10
- package/lib/logic/getBlock.js.map +1 -1
- package/lib/logic/getBlockInfo.d.ts +2 -1
- package/lib/logic/getBlockInfo.d.ts.map +1 -1
- package/lib/logic/getBlockInfo.js +5 -3
- package/lib/logic/getBlockInfo.js.map +1 -1
- package/lib/logic/getStakes.d.ts +3 -2
- package/lib/logic/getStakes.d.ts.map +1 -1
- package/lib/logic/getStakes.js +9 -9
- package/lib/logic/getStakes.js.map +1 -1
- package/lib/logic/lastBlock.d.ts +2 -1
- package/lib/logic/lastBlock.d.ts.map +1 -1
- package/lib/logic/lastBlock.js +4 -6
- package/lib/logic/lastBlock.js.map +1 -1
- package/lib/logic/listOperations.d.ts +2 -1
- package/lib/logic/listOperations.d.ts.map +1 -1
- package/lib/logic/listOperations.js +8 -6
- package/lib/logic/listOperations.js.map +1 -1
- package/lib/logic/tezosToolkit.d.ts +2 -1
- package/lib/logic/tezosToolkit.d.ts.map +1 -1
- package/lib/logic/tezosToolkit.js +2 -6
- package/lib/logic/tezosToolkit.js.map +1 -1
- package/lib/logic/validateIntent.d.ts +2 -1
- package/lib/logic/validateIntent.d.ts.map +1 -1
- package/lib/logic/validateIntent.js +12 -13
- package/lib/logic/validateIntent.js.map +1 -1
- package/lib/network/bakers.d.ts +5 -4
- package/lib/network/bakers.d.ts.map +1 -1
- package/lib/network/bakers.js +9 -10
- package/lib/network/bakers.js.map +1 -1
- package/lib/network/index.d.ts +1 -1
- package/lib/network/index.d.ts.map +1 -1
- package/lib/network/index.js +2 -5
- package/lib/network/index.js.map +1 -1
- package/lib/network/tzkt.d.ts +16 -9
- package/lib/network/tzkt.d.ts.map +1 -1
- package/lib/network/tzkt.js +341 -333
- package/lib/network/tzkt.js.map +1 -1
- package/lib/utils.d.ts +2 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +1 -6
- package/lib/utils.js.map +1 -1
- package/lib-es/api/index.d.ts +1 -2
- package/lib-es/api/index.d.ts.map +1 -1
- package/lib-es/api/index.js +40 -36
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/api/types.d.ts +3 -2
- package/lib-es/api/types.d.ts.map +1 -1
- package/lib-es/config.d.ts +3 -1
- package/lib-es/config.d.ts.map +1 -1
- package/lib-es/config.js.map +1 -1
- package/lib-es/logic/broadcast.d.ts +2 -1
- package/lib-es/logic/broadcast.d.ts.map +1 -1
- package/lib-es/logic/broadcast.js +3 -2
- package/lib-es/logic/broadcast.js.map +1 -1
- package/lib-es/logic/combine.d.ts +1 -1
- package/lib-es/logic/combine.d.ts.map +1 -1
- package/lib-es/logic/combine.js +4 -1
- package/lib-es/logic/combine.js.map +1 -1
- package/lib-es/logic/craftRawOperations.d.ts +2 -1
- package/lib-es/logic/craftRawOperations.d.ts.map +1 -1
- package/lib-es/logic/craftRawOperations.js +5 -5
- package/lib-es/logic/craftRawOperations.js.map +1 -1
- package/lib-es/logic/craftTransaction.d.ts +3 -2
- package/lib-es/logic/craftTransaction.d.ts.map +1 -1
- package/lib-es/logic/craftTransaction.js +6 -6
- package/lib-es/logic/craftTransaction.js.map +1 -1
- package/lib-es/logic/estimateFees.d.ts +2 -1
- package/lib-es/logic/estimateFees.d.ts.map +1 -1
- package/lib-es/logic/estimateFees.js +24 -16
- package/lib-es/logic/estimateFees.js.map +1 -1
- package/lib-es/logic/getBalance.d.ts +2 -1
- package/lib-es/logic/getBalance.d.ts.map +1 -1
- package/lib-es/logic/getBalance.js +5 -3
- package/lib-es/logic/getBalance.js.map +1 -1
- package/lib-es/logic/getBlock.d.ts +2 -1
- package/lib-es/logic/getBlock.d.ts.map +1 -1
- package/lib-es/logic/getBlock.js +10 -8
- package/lib-es/logic/getBlock.js.map +1 -1
- package/lib-es/logic/getBlockInfo.d.ts +2 -1
- package/lib-es/logic/getBlockInfo.d.ts.map +1 -1
- package/lib-es/logic/getBlockInfo.js +4 -2
- package/lib-es/logic/getBlockInfo.js.map +1 -1
- package/lib-es/logic/getStakes.d.ts +3 -2
- package/lib-es/logic/getStakes.d.ts.map +1 -1
- package/lib-es/logic/getStakes.js +9 -6
- package/lib-es/logic/getStakes.js.map +1 -1
- package/lib-es/logic/lastBlock.d.ts +2 -1
- package/lib-es/logic/lastBlock.d.ts.map +1 -1
- package/lib-es/logic/lastBlock.js +4 -3
- package/lib-es/logic/lastBlock.js.map +1 -1
- package/lib-es/logic/listOperations.d.ts +2 -1
- package/lib-es/logic/listOperations.d.ts.map +1 -1
- package/lib-es/logic/listOperations.js +7 -5
- package/lib-es/logic/listOperations.js.map +1 -1
- package/lib-es/logic/tezosToolkit.d.ts +2 -1
- package/lib-es/logic/tezosToolkit.d.ts.map +1 -1
- package/lib-es/logic/tezosToolkit.js +2 -3
- package/lib-es/logic/tezosToolkit.js.map +1 -1
- package/lib-es/logic/validateIntent.d.ts +2 -1
- package/lib-es/logic/validateIntent.d.ts.map +1 -1
- package/lib-es/logic/validateIntent.js +10 -8
- package/lib-es/logic/validateIntent.js.map +1 -1
- package/lib-es/network/bakers.d.ts +5 -4
- package/lib-es/network/bakers.d.ts.map +1 -1
- package/lib-es/network/bakers.js +9 -10
- package/lib-es/network/bakers.js.map +1 -1
- package/lib-es/network/index.d.ts +1 -1
- package/lib-es/network/index.d.ts.map +1 -1
- package/lib-es/network/index.js +1 -1
- package/lib-es/network/index.js.map +1 -1
- package/lib-es/network/tzkt.d.ts +16 -9
- package/lib-es/network/tzkt.d.ts.map +1 -1
- package/lib-es/network/tzkt.js +340 -333
- package/lib-es/network/tzkt.js.map +1 -1
- package/lib-es/utils.d.ts +2 -1
- package/lib-es/utils.d.ts.map +1 -1
- package/lib-es/utils.js +1 -3
- package/lib-es/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/api/index-mainnet.integ.test.ts +34 -30
- package/src/api/index.integ.test.ts +69 -53
- package/src/api/index.test.ts +99 -60
- package/src/api/index.ts +52 -36
- package/src/api/types.ts +3 -2
- package/src/config.ts +4 -1
- package/src/logic/broadcast.integ.test.ts +12 -13
- package/src/logic/broadcast.ts +4 -2
- package/src/logic/combine.test.ts +17 -0
- package/src/logic/combine.ts +5 -2
- package/src/logic/craftRawOperations.test.ts +47 -33
- package/src/logic/craftRawOperations.ts +6 -4
- package/src/logic/craftTransaction.integ.test.ts +12 -5
- package/src/logic/craftTransaction.test.ts +39 -31
- package/src/logic/craftTransaction.ts +10 -5
- package/src/logic/estimateFees.integ.test.ts +7 -7
- package/src/logic/estimateFees.test.ts +52 -49
- package/src/logic/estimateFees.ts +34 -22
- package/src/logic/getBalance.test.ts +19 -17
- package/src/logic/getBalance.ts +6 -3
- package/src/logic/getBlock.integ.test.ts +8 -30
- package/src/logic/getBlock.test.ts +91 -81
- package/src/logic/getBlock.ts +11 -8
- package/src/logic/getBlockInfo.integ.test.ts +9 -18
- package/src/logic/getBlockInfo.test.ts +19 -9
- package/src/logic/getBlockInfo.ts +5 -2
- package/src/logic/getStakes.test.ts +46 -49
- package/src/logic/getStakes.ts +14 -5
- package/src/logic/lastBlock.ts +5 -3
- package/src/logic/listOperations.integ.test.ts +40 -67
- package/src/logic/listOperations.test.ts +65 -59
- package/src/logic/listOperations.ts +8 -3
- package/src/logic/tezosToolkit.ts +3 -3
- package/src/logic/validateIntent.test.ts +78 -74
- package/src/logic/validateIntent.ts +17 -7
- package/src/network/bakers.integ.test.ts +2 -5
- package/src/network/bakers.test.ts +5 -6
- package/src/network/bakers.ts +13 -10
- package/src/network/index.ts +2 -1
- package/src/network/tzkt.integ.test.ts +3 -14
- package/src/network/tzkt.test.ts +128 -96
- package/src/network/tzkt.ts +426 -393
- package/src/utils.ts +2 -3
package/lib/network/tzkt.js
CHANGED
|
@@ -6,15 +6,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
6
6
|
};
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.fetchBlockReveals = exports.fetchBlockOriginations = exports.fetchBlockStaking = exports.fetchBlockDelegations = exports.fetchBlockTokenTransfers = exports.fetchBlockTransactions = exports.fetchAllTransactions = void 0;
|
|
9
|
+
exports.createTzktApi = createTzktApi;
|
|
9
10
|
const url_1 = __importDefault(require("url"));
|
|
10
11
|
const live_network_1 = __importDefault(require("@ledgerhq/live-network"));
|
|
11
12
|
const logs_1 = require("@ledgerhq/logs");
|
|
12
|
-
const config_1 = __importDefault(require("../config"));
|
|
13
13
|
/** TzKT hard-caps `limit` at 10 000; we use a safer page size to stay well under that. */
|
|
14
14
|
const BLOCK_PAGE_SIZE = 1000;
|
|
15
15
|
/** Maximum number of IDs per `id.in` request to keep URLs under the Cloudflare proxy limit (~16 KB). */
|
|
16
16
|
const ID_IN_CHUNK_SIZE = 100;
|
|
17
|
-
const getExplorerUrl = () => config_1.default.getCoinConfig().explorer.url;
|
|
18
17
|
/**
|
|
19
18
|
* Coalesces concurrent `getAccountByAddress` calls for the same explorer+address into a
|
|
20
19
|
* single request. During a sync both `getBalance` and the readiness hook hit this endpoint
|
|
@@ -35,349 +34,359 @@ function chunk(arr, size) {
|
|
|
35
34
|
return result;
|
|
36
35
|
}
|
|
37
36
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
37
|
+
* Builds the TzKT explorer client bound to the given coin config (ADR-019). The caller resolves the
|
|
38
|
+
* config from its {@link Context} and passes it in, rather than the client reading a module-level
|
|
39
|
+
* singleton.
|
|
40
40
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// Without an explicit sort the API default may be descending, which would cause the
|
|
44
|
-
// cursor to go backwards and produce duplicates or an infinite loop.
|
|
45
|
-
const params = {
|
|
46
|
-
'level.gte': level,
|
|
47
|
-
limit: BLOCK_PAGE_SIZE,
|
|
48
|
-
'sort.asc': 'id',
|
|
49
|
-
...clearUndefined(apiQueryParams),
|
|
50
|
-
};
|
|
51
|
-
if (cursor !== undefined)
|
|
52
|
-
params['offset.cr'] = cursor;
|
|
53
|
-
const { data } = await (0, live_network_1.default)({
|
|
54
|
-
url: `${getExplorerUrl()}/v1/operations/${type}`,
|
|
55
|
-
params,
|
|
56
|
-
});
|
|
57
|
-
return data;
|
|
58
|
-
}
|
|
59
|
-
const api = {
|
|
60
|
-
async getBlockCount() {
|
|
61
|
-
const { data } = await (0, live_network_1.default)({
|
|
62
|
-
url: `${getExplorerUrl()}/v1/blocks/count`,
|
|
63
|
-
});
|
|
64
|
-
return data;
|
|
65
|
-
},
|
|
66
|
-
async getLastBlock() {
|
|
67
|
-
const { data } = await (0, live_network_1.default)({
|
|
68
|
-
url: `${getExplorerUrl()}/v1/blocks`,
|
|
69
|
-
params: {
|
|
70
|
-
'sort.desc': 'level',
|
|
71
|
-
},
|
|
72
|
-
});
|
|
73
|
-
return {
|
|
74
|
-
hash: data[0].hash,
|
|
75
|
-
level: data[0].level,
|
|
76
|
-
date: new Date(data[0].timestamp),
|
|
77
|
-
};
|
|
78
|
-
},
|
|
79
|
-
async getAccountByAddress(address) {
|
|
80
|
-
const key = `${getExplorerUrl()}|${address}`;
|
|
81
|
-
const existing = accountByAddressInflight.get(key);
|
|
82
|
-
if (existing)
|
|
83
|
-
return existing;
|
|
84
|
-
const request = (0, live_network_1.default)({
|
|
85
|
-
url: `${getExplorerUrl()}/v1/accounts/${address}`,
|
|
86
|
-
})
|
|
87
|
-
.then(({ data }) => data)
|
|
88
|
-
.finally(() => accountByAddressInflight.delete(key));
|
|
89
|
-
accountByAddressInflight.set(key, request);
|
|
90
|
-
return request;
|
|
91
|
-
},
|
|
92
|
-
/**
|
|
93
|
-
* Returns the total `actualAmount` (mutez) summed over the account's `finalizable`
|
|
94
|
-
* unstake requests — the portion of `unstakedBalance` whose unlock cycle has been
|
|
95
|
-
* reached and that can be reclaimed via `finalize_unstake`. The complementary
|
|
96
|
-
* `unstakedBalance - finalizable` portion is still in the deactivation delay window.
|
|
97
|
-
*
|
|
98
|
-
* TzKT's account endpoint does not expose this split, so we sum from
|
|
99
|
-
* `/v1/staking/unstake_requests`. https://api.tzkt.io/#operation/Staking_GetUnstakeRequests
|
|
100
|
-
*
|
|
101
|
-
* `limit=1000` covers any realistic number of concurrent finalizable requests for
|
|
102
|
-
* a single staker — we do not paginate.
|
|
103
|
-
*/
|
|
104
|
-
async getUnstakeRequestsFinalizable(address) {
|
|
105
|
-
const { data } = await (0, live_network_1.default)({
|
|
106
|
-
url: `${getExplorerUrl()}/v1/staking/unstake_requests`,
|
|
107
|
-
params: {
|
|
108
|
-
'staker.eq': address,
|
|
109
|
-
status: 'finalizable',
|
|
110
|
-
'select.values': 'actualAmount',
|
|
111
|
-
limit: 1000,
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
return data.reduce((sum, n) => sum + BigInt(n), 0n);
|
|
115
|
-
},
|
|
116
|
-
/**
|
|
117
|
-
* Pending + finalizable unstake requests, by id ascending. Uses `status.ne=finalized` because
|
|
118
|
-
* TzKT ignores `status.in=pending,finalizable` on this endpoint and returns finalized requests.
|
|
119
|
-
* https://api.tzkt.io/#operation/Staking_GetUnstakeRequests
|
|
120
|
-
*/
|
|
121
|
-
async getUnstakeRequests(address) {
|
|
122
|
-
const { data } = await (0, live_network_1.default)({
|
|
123
|
-
url: `${getExplorerUrl()}/v1/staking/unstake_requests`,
|
|
124
|
-
params: {
|
|
125
|
-
'staker.eq': address,
|
|
126
|
-
'status.ne': 'finalized',
|
|
127
|
-
'sort.asc': 'id',
|
|
128
|
-
limit: 1000,
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
return data;
|
|
132
|
-
},
|
|
133
|
-
// https://api.tzkt.io/#operation/Accounts_GetOperations
|
|
134
|
-
async getAccountOperations(address, query) {
|
|
135
|
-
// Remove undefined from query
|
|
136
|
-
Object.entries(query).forEach(([key, value]) => value === undefined && delete query[key]);
|
|
137
|
-
const { data } = await (0, live_network_1.default)({
|
|
138
|
-
url: url_1.default.format({
|
|
139
|
-
pathname: `${getExplorerUrl()}/v1/accounts/${address}/operations`,
|
|
140
|
-
query,
|
|
141
|
-
}),
|
|
142
|
-
});
|
|
143
|
-
return data;
|
|
144
|
-
},
|
|
145
|
-
// https://api.tzkt.io/#operation/Blocks_GetByLevel
|
|
146
|
-
async getBlockByLevel(level) {
|
|
147
|
-
const { data } = await (0, live_network_1.default)({
|
|
148
|
-
url: `${getExplorerUrl()}/v1/blocks/${level}`,
|
|
149
|
-
});
|
|
150
|
-
return data;
|
|
151
|
-
},
|
|
152
|
-
/**
|
|
153
|
-
* Resolves block hashes for the given levels in a single request.
|
|
154
|
-
* Uses `/v1/blocks?level.in=...&select.values=level,hash`, which TzKT honours
|
|
155
|
-
* (unlike `/v1/blocks/{level}?select=...`, where `select` is ignored). Used
|
|
156
|
-
* for cheap backfill of `block.hash` on operations whose level is known but
|
|
157
|
-
* whose response omits the block field (e.g. `/accounts/{addr}/operations`
|
|
158
|
-
* for staking ops). Levels that don't resolve are absent from the result map.
|
|
159
|
-
*/
|
|
160
|
-
async getBlockHashesByLevels(levels) {
|
|
161
|
-
if (levels.length === 0)
|
|
162
|
-
return new Map();
|
|
163
|
-
const { data } = await (0, live_network_1.default)({
|
|
164
|
-
url: `${getExplorerUrl()}/v1/blocks`,
|
|
165
|
-
params: {
|
|
166
|
-
'level.in': levels.join(','),
|
|
167
|
-
'select.values': 'level,hash',
|
|
168
|
-
limit: levels.length,
|
|
169
|
-
},
|
|
170
|
-
});
|
|
171
|
-
return new Map(data);
|
|
172
|
-
},
|
|
41
|
+
function createTzktApi(config) {
|
|
42
|
+
const explorerUrl = config.explorer.url;
|
|
173
43
|
/**
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
* https://api.tzkt.io/#operation/Operations_GetTransactions
|
|
44
|
+
* Internal helper shared by `getOperationsTransactions` and `getOperationsOrigination`.
|
|
45
|
+
* Both endpoints accept the same query shape; only the URL path differs.
|
|
177
46
|
*/
|
|
178
|
-
async
|
|
47
|
+
async function getOperationsByType(type, level, cursor, apiQueryParams = {}) {
|
|
179
48
|
// "sort.asc": "id" guarantees forward progress for cursor-based paging (offset.cr).
|
|
180
49
|
// Without an explicit sort the API default may be descending, which would cause the
|
|
181
50
|
// cursor to go backwards and produce duplicates or an infinite loop.
|
|
182
|
-
const params = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' };
|
|
183
|
-
if (cursor !== undefined)
|
|
184
|
-
params['offset.cr'] = cursor;
|
|
185
|
-
const { data } = await (0, live_network_1.default)({
|
|
186
|
-
url: `${getExplorerUrl()}/v1/operations/transactions`,
|
|
187
|
-
params,
|
|
188
|
-
});
|
|
189
|
-
return data;
|
|
190
|
-
},
|
|
191
|
-
/**
|
|
192
|
-
* Fetches a list of `transaction` operations after the given level.
|
|
193
|
-
* https://api.tzkt.io/#operation/Operations_GetTransactions
|
|
194
|
-
*/
|
|
195
|
-
async getOperationsTransactions(level, cursor, apiQueryParams = {}) {
|
|
196
|
-
return getOperationsByType('transactions', level, cursor, apiQueryParams);
|
|
197
|
-
},
|
|
198
|
-
/**
|
|
199
|
-
* Fetches a list of `originations` operations after the given level.
|
|
200
|
-
* https://api.tzkt.io/#operation/Operations_GetOriginations
|
|
201
|
-
*/
|
|
202
|
-
async getOperationsOrigination(level, cursor, apiQueryParams = {}) {
|
|
203
|
-
return getOperationsByType('originations', level, cursor, apiQueryParams);
|
|
204
|
-
},
|
|
205
|
-
/**
|
|
206
|
-
* Fetches a single page of FA token transfers at the given block level.
|
|
207
|
-
* Internal — used by `fetchBlockTokenTransfers` which handles pagination.
|
|
208
|
-
* https://api.tzkt.io/#operation/Tokens_GetTokenTransfers
|
|
209
|
-
*/
|
|
210
|
-
async getBlockTokenTransfersPage(level, cursor) {
|
|
211
|
-
// Same rationale as getBlockTransactionsPage: explicit ascending sort keeps the
|
|
212
|
-
// offset.cr cursor advancing forward regardless of the API's default ordering.
|
|
213
51
|
const params = {
|
|
214
|
-
level,
|
|
52
|
+
'level.gte': level,
|
|
215
53
|
limit: BLOCK_PAGE_SIZE,
|
|
216
54
|
'sort.asc': 'id',
|
|
217
|
-
'token.standard': 'fa2',
|
|
218
|
-
};
|
|
219
|
-
if (cursor !== undefined)
|
|
220
|
-
params['offset.cr'] = cursor;
|
|
221
|
-
const { data } = await (0, live_network_1.default)({
|
|
222
|
-
url: `${getExplorerUrl()}/v1/tokens/transfers`,
|
|
223
|
-
params,
|
|
224
|
-
});
|
|
225
|
-
return data;
|
|
226
|
-
},
|
|
227
|
-
/**
|
|
228
|
-
* Fetches the latest FA token transfers since the given level.
|
|
229
|
-
* https://api.tzkt.io/#operation/Tokens_GetTokenTransfers
|
|
230
|
-
*/
|
|
231
|
-
async getTokenTransfers(apiQueryParams = {}) {
|
|
232
|
-
const params = {
|
|
233
55
|
...clearUndefined(apiQueryParams),
|
|
234
56
|
};
|
|
235
|
-
const { data } = await (0, live_network_1.default)({
|
|
236
|
-
url: `${getExplorerUrl()}/v1/tokens/transfers`,
|
|
237
|
-
params,
|
|
238
|
-
});
|
|
239
|
-
return data;
|
|
240
|
-
},
|
|
241
|
-
/**
|
|
242
|
-
* Fetches a single page of `origination` operations at the given block level.
|
|
243
|
-
* Internal — used by `fetchBlockOriginations` which handles pagination.
|
|
244
|
-
* https://api.tzkt.io/#operation/Operations_GetOriginations
|
|
245
|
-
*/
|
|
246
|
-
async getBlockOriginationsPage(level, cursor) {
|
|
247
|
-
const params = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' };
|
|
248
|
-
if (cursor !== undefined)
|
|
249
|
-
params['offset.cr'] = cursor;
|
|
250
|
-
const { data } = await (0, live_network_1.default)({
|
|
251
|
-
url: `${getExplorerUrl()}/v1/operations/originations`,
|
|
252
|
-
params,
|
|
253
|
-
});
|
|
254
|
-
return data;
|
|
255
|
-
},
|
|
256
|
-
/**
|
|
257
|
-
* Fetches a single page of `reveal` operations at the given block level.
|
|
258
|
-
* Internal — used by `fetchBlockReveals` which handles pagination.
|
|
259
|
-
* https://api.tzkt.io/#operation/Operations_GetReveals
|
|
260
|
-
*/
|
|
261
|
-
async getBlockRevealsPage(level, cursor) {
|
|
262
|
-
const params = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' };
|
|
263
|
-
if (cursor !== undefined)
|
|
264
|
-
params['offset.cr'] = cursor;
|
|
265
|
-
const { data } = await (0, live_network_1.default)({
|
|
266
|
-
url: `${getExplorerUrl()}/v1/operations/reveals`,
|
|
267
|
-
params,
|
|
268
|
-
});
|
|
269
|
-
return data;
|
|
270
|
-
},
|
|
271
|
-
/**
|
|
272
|
-
* Fetches a single page of `delegation` operations at the given block level.
|
|
273
|
-
* Internal — used by `fetchBlockDelegations` which handles pagination.
|
|
274
|
-
* https://api.tzkt.io/#operation/Operations_GetDelegations
|
|
275
|
-
*/
|
|
276
|
-
async getBlockDelegationsPage(level, cursor) {
|
|
277
|
-
const params = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' };
|
|
278
|
-
if (cursor !== undefined)
|
|
279
|
-
params['offset.cr'] = cursor;
|
|
280
|
-
const { data } = await (0, live_network_1.default)({
|
|
281
|
-
url: `${getExplorerUrl()}/v1/operations/delegations`,
|
|
282
|
-
params,
|
|
283
|
-
});
|
|
284
|
-
return data;
|
|
285
|
-
},
|
|
286
|
-
/**
|
|
287
|
-
* Fetches a single page of `staking` operations at the given block level.
|
|
288
|
-
* Internal — used by `fetchBlockStaking` which handles pagination.
|
|
289
|
-
* https://api.tzkt.io/#operation/Operations_GetStaking
|
|
290
|
-
*/
|
|
291
|
-
async getBlockStakingPage(level, cursor) {
|
|
292
|
-
const params = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' };
|
|
293
57
|
if (cursor !== undefined)
|
|
294
58
|
params['offset.cr'] = cursor;
|
|
295
59
|
const { data } = await (0, live_network_1.default)({
|
|
296
|
-
url: `${
|
|
60
|
+
url: `${explorerUrl}/v1/operations/${type}`,
|
|
297
61
|
params,
|
|
298
62
|
});
|
|
299
63
|
return data;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
'level.lt': query['level.lt'],
|
|
316
|
-
'level.gt': query['level.gt'],
|
|
317
|
-
'id.lt': query['id.lt'],
|
|
318
|
-
'id.gt': query['id.gt'],
|
|
319
|
-
};
|
|
320
|
-
const data = await api.getTokenTransfers(clearUndefined(params));
|
|
321
|
-
const transactionIds = data
|
|
322
|
-
.map((t) => t.transactionId)
|
|
323
|
-
.filter((id) => typeof id === 'number');
|
|
324
|
-
const originationIds = data
|
|
325
|
-
.map((t) => t.originationId)
|
|
326
|
-
.filter((id) => typeof id === 'number');
|
|
327
|
-
if (transactionIds.length === 0 && originationIds.length === 0) {
|
|
328
|
-
return [];
|
|
329
|
-
}
|
|
330
|
-
const transactions = transactionIds.length
|
|
331
|
-
? (await Promise.all(chunk(transactionIds, ID_IN_CHUNK_SIZE).map((ids) => api.getOperationsTransactions(query['level.ge'] || 0, undefined, {
|
|
332
|
-
'id.in': ids.join(','),
|
|
333
|
-
})))).flat()
|
|
334
|
-
: [];
|
|
335
|
-
const originations = originationIds.length
|
|
336
|
-
? (await Promise.all(chunk(originationIds, ID_IN_CHUNK_SIZE).map((ids) => api.getOperationsOrigination(query['level.ge'] || 0, undefined, {
|
|
337
|
-
'id.in': ids.join(','),
|
|
338
|
-
})))).flat()
|
|
339
|
-
: [];
|
|
340
|
-
// Build id -> operation maps once so per-transfer lookups are O(1) instead of O(n).
|
|
341
|
-
// Keys are widened to `number | undefined` so lookups with a missing id naturally
|
|
342
|
-
// return `undefined` (no entry is ever stored under the `undefined` key).
|
|
343
|
-
const transactionsById = new Map(transactions.map((t) => [t.id, t]));
|
|
344
|
-
const originationsById = new Map(originations.map((o) => [o.id, o]));
|
|
345
|
-
return data.map((token) => {
|
|
346
|
-
const transaction = transactionsById.get(token.transactionId);
|
|
347
|
-
const origination = originationsById.get(token.originationId);
|
|
64
|
+
}
|
|
65
|
+
const api = {
|
|
66
|
+
async getBlockCount() {
|
|
67
|
+
const { data } = await (0, live_network_1.default)({
|
|
68
|
+
url: `${explorerUrl}/v1/blocks/count`,
|
|
69
|
+
});
|
|
70
|
+
return data;
|
|
71
|
+
},
|
|
72
|
+
async getLastBlock() {
|
|
73
|
+
const { data } = await (0, live_network_1.default)({
|
|
74
|
+
url: `${explorerUrl}/v1/blocks`,
|
|
75
|
+
params: {
|
|
76
|
+
'sort.desc': 'level',
|
|
77
|
+
},
|
|
78
|
+
});
|
|
348
79
|
return {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
80
|
+
hash: data[0].hash,
|
|
81
|
+
level: data[0].level,
|
|
82
|
+
date: new Date(data[0].timestamp),
|
|
352
83
|
};
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
84
|
+
},
|
|
85
|
+
async getAccountByAddress(address) {
|
|
86
|
+
const key = `${explorerUrl}|${address}`;
|
|
87
|
+
const existing = accountByAddressInflight.get(key);
|
|
88
|
+
if (existing)
|
|
89
|
+
return existing;
|
|
90
|
+
const request = (0, live_network_1.default)({
|
|
91
|
+
url: `${explorerUrl}/v1/accounts/${address}`,
|
|
92
|
+
})
|
|
93
|
+
.then(({ data }) => data)
|
|
94
|
+
.finally(() => accountByAddressInflight.delete(key));
|
|
95
|
+
accountByAddressInflight.set(key, request);
|
|
96
|
+
return request;
|
|
97
|
+
},
|
|
98
|
+
/**
|
|
99
|
+
* Returns the total `actualAmount` (mutez) summed over the account's `finalizable`
|
|
100
|
+
* unstake requests — the portion of `unstakedBalance` whose unlock cycle has been
|
|
101
|
+
* reached and that can be reclaimed via `finalize_unstake`. The complementary
|
|
102
|
+
* `unstakedBalance - finalizable` portion is still in the deactivation delay window.
|
|
103
|
+
*
|
|
104
|
+
* TzKT's account endpoint does not expose this split, so we sum from
|
|
105
|
+
* `/v1/staking/unstake_requests`. https://api.tzkt.io/#operation/Staking_GetUnstakeRequests
|
|
106
|
+
*
|
|
107
|
+
* `limit=1000` covers any realistic number of concurrent finalizable requests for
|
|
108
|
+
* a single staker — we do not paginate.
|
|
109
|
+
*/
|
|
110
|
+
async getUnstakeRequestsFinalizable(address) {
|
|
111
|
+
const { data } = await (0, live_network_1.default)({
|
|
112
|
+
url: `${explorerUrl}/v1/staking/unstake_requests`,
|
|
113
|
+
params: {
|
|
114
|
+
'staker.eq': address,
|
|
115
|
+
status: 'finalizable',
|
|
116
|
+
'select.values': 'actualAmount',
|
|
117
|
+
limit: 1000,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
return data.reduce((sum, n) => sum + BigInt(n), 0n);
|
|
121
|
+
},
|
|
122
|
+
/**
|
|
123
|
+
* Pending + finalizable unstake requests, by id ascending. Uses `status.ne=finalized` because
|
|
124
|
+
* TzKT ignores `status.in=pending,finalizable` on this endpoint and returns finalized requests.
|
|
125
|
+
* https://api.tzkt.io/#operation/Staking_GetUnstakeRequests
|
|
126
|
+
*/
|
|
127
|
+
async getUnstakeRequests(address) {
|
|
128
|
+
const { data } = await (0, live_network_1.default)({
|
|
129
|
+
url: `${explorerUrl}/v1/staking/unstake_requests`,
|
|
130
|
+
params: {
|
|
131
|
+
'staker.eq': address,
|
|
132
|
+
'status.ne': 'finalized',
|
|
133
|
+
'sort.asc': 'id',
|
|
134
|
+
limit: 1000,
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
return data;
|
|
138
|
+
},
|
|
139
|
+
// https://api.tzkt.io/#operation/Accounts_GetOperations
|
|
140
|
+
async getAccountOperations(address, query) {
|
|
141
|
+
// Remove undefined from query
|
|
142
|
+
Object.entries(query).forEach(([key, value]) => value === undefined && delete query[key]);
|
|
143
|
+
const { data } = await (0, live_network_1.default)({
|
|
144
|
+
url: url_1.default.format({
|
|
145
|
+
pathname: `${explorerUrl}/v1/accounts/${address}/operations`,
|
|
146
|
+
query,
|
|
147
|
+
}),
|
|
148
|
+
});
|
|
149
|
+
return data;
|
|
150
|
+
},
|
|
151
|
+
// https://api.tzkt.io/#operation/Blocks_GetByLevel
|
|
152
|
+
async getBlockByLevel(level) {
|
|
153
|
+
const { data } = await (0, live_network_1.default)({
|
|
154
|
+
url: `${explorerUrl}/v1/blocks/${level}`,
|
|
155
|
+
});
|
|
156
|
+
return data;
|
|
157
|
+
},
|
|
158
|
+
/**
|
|
159
|
+
* Resolves block hashes for the given levels in a single request.
|
|
160
|
+
* Uses `/v1/blocks?level.in=...&select.values=level,hash`, which TzKT honours
|
|
161
|
+
* (unlike `/v1/blocks/{level}?select=...`, where `select` is ignored). Used
|
|
162
|
+
* for cheap backfill of `block.hash` on operations whose level is known but
|
|
163
|
+
* whose response omits the block field (e.g. `/accounts/{addr}/operations`
|
|
164
|
+
* for staking ops). Levels that don't resolve are absent from the result map.
|
|
165
|
+
*/
|
|
166
|
+
async getBlockHashesByLevels(levels) {
|
|
167
|
+
if (levels.length === 0)
|
|
168
|
+
return new Map();
|
|
169
|
+
const { data } = await (0, live_network_1.default)({
|
|
170
|
+
url: `${explorerUrl}/v1/blocks`,
|
|
171
|
+
params: {
|
|
172
|
+
'level.in': levels.join(','),
|
|
173
|
+
'select.values': 'level,hash',
|
|
174
|
+
limit: levels.length,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
return new Map(data);
|
|
178
|
+
},
|
|
179
|
+
/**
|
|
180
|
+
* Fetches a single page of `transaction` operations at the given block level.
|
|
181
|
+
* Internal — used by `fetchBlockTransactions` which handles pagination.
|
|
182
|
+
* https://api.tzkt.io/#operation/Operations_GetTransactions
|
|
183
|
+
*/
|
|
184
|
+
async getBlockTransactionsPage(level, cursor) {
|
|
185
|
+
// "sort.asc": "id" guarantees forward progress for cursor-based paging (offset.cr).
|
|
186
|
+
// Without an explicit sort the API default may be descending, which would cause the
|
|
187
|
+
// cursor to go backwards and produce duplicates or an infinite loop.
|
|
188
|
+
const params = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' };
|
|
189
|
+
if (cursor !== undefined)
|
|
190
|
+
params['offset.cr'] = cursor;
|
|
191
|
+
const { data } = await (0, live_network_1.default)({
|
|
192
|
+
url: `${explorerUrl}/v1/operations/transactions`,
|
|
193
|
+
params,
|
|
194
|
+
});
|
|
195
|
+
return data;
|
|
196
|
+
},
|
|
197
|
+
/**
|
|
198
|
+
* Fetches a list of `transaction` operations after the given level.
|
|
199
|
+
* https://api.tzkt.io/#operation/Operations_GetTransactions
|
|
200
|
+
*/
|
|
201
|
+
async getOperationsTransactions(level, cursor, apiQueryParams = {}) {
|
|
202
|
+
return getOperationsByType('transactions', level, cursor, apiQueryParams);
|
|
203
|
+
},
|
|
204
|
+
/**
|
|
205
|
+
* Fetches a list of `originations` operations after the given level.
|
|
206
|
+
* https://api.tzkt.io/#operation/Operations_GetOriginations
|
|
207
|
+
*/
|
|
208
|
+
async getOperationsOrigination(level, cursor, apiQueryParams = {}) {
|
|
209
|
+
return getOperationsByType('originations', level, cursor, apiQueryParams);
|
|
210
|
+
},
|
|
211
|
+
/**
|
|
212
|
+
* Fetches a single page of FA token transfers at the given block level.
|
|
213
|
+
* Internal — used by `fetchBlockTokenTransfers` which handles pagination.
|
|
214
|
+
* https://api.tzkt.io/#operation/Tokens_GetTokenTransfers
|
|
215
|
+
*/
|
|
216
|
+
async getBlockTokenTransfersPage(level, cursor) {
|
|
217
|
+
// Same rationale as getBlockTransactionsPage: explicit ascending sort keeps the
|
|
218
|
+
// offset.cr cursor advancing forward regardless of the API's default ordering.
|
|
219
|
+
const params = {
|
|
220
|
+
level,
|
|
221
|
+
limit: BLOCK_PAGE_SIZE,
|
|
222
|
+
'sort.asc': 'id',
|
|
223
|
+
'token.standard': 'fa2',
|
|
224
|
+
};
|
|
225
|
+
if (cursor !== undefined)
|
|
226
|
+
params['offset.cr'] = cursor;
|
|
227
|
+
const { data } = await (0, live_network_1.default)({
|
|
228
|
+
url: `${explorerUrl}/v1/tokens/transfers`,
|
|
229
|
+
params,
|
|
230
|
+
});
|
|
231
|
+
return data;
|
|
232
|
+
},
|
|
233
|
+
/**
|
|
234
|
+
* Fetches the latest FA token transfers since the given level.
|
|
235
|
+
* https://api.tzkt.io/#operation/Tokens_GetTokenTransfers
|
|
236
|
+
*/
|
|
237
|
+
async getTokenTransfers(apiQueryParams = {}) {
|
|
238
|
+
const params = {
|
|
239
|
+
...clearUndefined(apiQueryParams),
|
|
240
|
+
};
|
|
241
|
+
const { data } = await (0, live_network_1.default)({
|
|
242
|
+
url: `${explorerUrl}/v1/tokens/transfers`,
|
|
243
|
+
params,
|
|
244
|
+
});
|
|
245
|
+
return data;
|
|
246
|
+
},
|
|
247
|
+
/**
|
|
248
|
+
* Fetches a single page of `origination` operations at the given block level.
|
|
249
|
+
* Internal — used by `fetchBlockOriginations` which handles pagination.
|
|
250
|
+
* https://api.tzkt.io/#operation/Operations_GetOriginations
|
|
251
|
+
*/
|
|
252
|
+
async getBlockOriginationsPage(level, cursor) {
|
|
253
|
+
const params = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' };
|
|
254
|
+
if (cursor !== undefined)
|
|
255
|
+
params['offset.cr'] = cursor;
|
|
256
|
+
const { data } = await (0, live_network_1.default)({
|
|
257
|
+
url: `${explorerUrl}/v1/operations/originations`,
|
|
258
|
+
params,
|
|
259
|
+
});
|
|
260
|
+
return data;
|
|
261
|
+
},
|
|
262
|
+
/**
|
|
263
|
+
* Fetches a single page of `reveal` operations at the given block level.
|
|
264
|
+
* Internal — used by `fetchBlockReveals` which handles pagination.
|
|
265
|
+
* https://api.tzkt.io/#operation/Operations_GetReveals
|
|
266
|
+
*/
|
|
267
|
+
async getBlockRevealsPage(level, cursor) {
|
|
268
|
+
const params = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' };
|
|
269
|
+
if (cursor !== undefined)
|
|
270
|
+
params['offset.cr'] = cursor;
|
|
271
|
+
const { data } = await (0, live_network_1.default)({
|
|
272
|
+
url: `${explorerUrl}/v1/operations/reveals`,
|
|
273
|
+
params,
|
|
274
|
+
});
|
|
275
|
+
return data;
|
|
276
|
+
},
|
|
277
|
+
/**
|
|
278
|
+
* Fetches a single page of `delegation` operations at the given block level.
|
|
279
|
+
* Internal — used by `fetchBlockDelegations` which handles pagination.
|
|
280
|
+
* https://api.tzkt.io/#operation/Operations_GetDelegations
|
|
281
|
+
*/
|
|
282
|
+
async getBlockDelegationsPage(level, cursor) {
|
|
283
|
+
const params = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' };
|
|
284
|
+
if (cursor !== undefined)
|
|
285
|
+
params['offset.cr'] = cursor;
|
|
286
|
+
const { data } = await (0, live_network_1.default)({
|
|
287
|
+
url: `${explorerUrl}/v1/operations/delegations`,
|
|
288
|
+
params,
|
|
289
|
+
});
|
|
290
|
+
return data;
|
|
291
|
+
},
|
|
292
|
+
/**
|
|
293
|
+
* Fetches a single page of `staking` operations at the given block level.
|
|
294
|
+
* Internal — used by `fetchBlockStaking` which handles pagination.
|
|
295
|
+
* https://api.tzkt.io/#operation/Operations_GetStaking
|
|
296
|
+
*/
|
|
297
|
+
async getBlockStakingPage(level, cursor) {
|
|
298
|
+
const params = { level, limit: BLOCK_PAGE_SIZE, 'sort.asc': 'id' };
|
|
299
|
+
if (cursor !== undefined)
|
|
300
|
+
params['offset.cr'] = cursor;
|
|
301
|
+
const { data } = await (0, live_network_1.default)({
|
|
302
|
+
url: `${explorerUrl}/v1/operations/staking`,
|
|
303
|
+
params,
|
|
304
|
+
});
|
|
305
|
+
return data;
|
|
306
|
+
},
|
|
307
|
+
/**
|
|
308
|
+
* Fetches FA2 token transfers for a given account.
|
|
309
|
+
* Translates `query.sort` to TzKT's `sort.asc=id` / `sort.desc=id`.
|
|
310
|
+
* The lower-level `getTokenTransfers` helper is a generic pass-through and does not pin the sort.
|
|
311
|
+
* https://api.tzkt.io/#operation/Tokens_GetTokenTransfers
|
|
312
|
+
*/
|
|
313
|
+
async getAccountTokenTransfers(address, query) {
|
|
314
|
+
const sortKey = query.sort === 'Descending' ? 'sort.desc' : 'sort.asc';
|
|
315
|
+
const params = {
|
|
316
|
+
'anyof.from.to': address,
|
|
317
|
+
'token.standard': 'fa2',
|
|
318
|
+
[sortKey]: 'id',
|
|
319
|
+
limit: query.limit,
|
|
320
|
+
'level.ge': query['level.ge'],
|
|
321
|
+
'level.lt': query['level.lt'],
|
|
322
|
+
'level.gt': query['level.gt'],
|
|
323
|
+
'id.lt': query['id.lt'],
|
|
324
|
+
'id.gt': query['id.gt'],
|
|
325
|
+
};
|
|
326
|
+
const data = await api.getTokenTransfers(clearUndefined(params));
|
|
327
|
+
const transactionIds = data
|
|
328
|
+
.map((t) => t.transactionId)
|
|
329
|
+
.filter((id) => typeof id === 'number');
|
|
330
|
+
const originationIds = data
|
|
331
|
+
.map((t) => t.originationId)
|
|
332
|
+
.filter((id) => typeof id === 'number');
|
|
333
|
+
if (transactionIds.length === 0 && originationIds.length === 0) {
|
|
334
|
+
return [];
|
|
335
|
+
}
|
|
336
|
+
const transactions = transactionIds.length
|
|
337
|
+
? (await Promise.all(chunk(transactionIds, ID_IN_CHUNK_SIZE).map((ids) => api.getOperationsTransactions(query['level.ge'] || 0, undefined, {
|
|
338
|
+
'id.in': ids.join(','),
|
|
339
|
+
})))).flat()
|
|
340
|
+
: [];
|
|
341
|
+
const originations = originationIds.length
|
|
342
|
+
? (await Promise.all(chunk(originationIds, ID_IN_CHUNK_SIZE).map((ids) => api.getOperationsOrigination(query['level.ge'] || 0, undefined, {
|
|
343
|
+
'id.in': ids.join(','),
|
|
344
|
+
})))).flat()
|
|
345
|
+
: [];
|
|
346
|
+
// Build id -> operation maps once so per-transfer lookups are O(1) instead of O(n).
|
|
347
|
+
// Keys are widened to `number | undefined` so lookups with a missing id naturally
|
|
348
|
+
// return `undefined` (no entry is ever stored under the `undefined` key).
|
|
349
|
+
const transactionsById = new Map(transactions.map((t) => [t.id, t]));
|
|
350
|
+
const originationsById = new Map(originations.map((o) => [o.id, o]));
|
|
351
|
+
return data.map((token) => {
|
|
352
|
+
const transaction = transactionsById.get(token.transactionId);
|
|
353
|
+
const origination = originationsById.get(token.originationId);
|
|
354
|
+
return {
|
|
355
|
+
...token,
|
|
356
|
+
hash: transaction?.hash ?? origination?.hash ?? '',
|
|
357
|
+
block: transaction?.block ?? origination?.block ?? '',
|
|
358
|
+
};
|
|
359
|
+
});
|
|
360
|
+
},
|
|
361
|
+
/**
|
|
362
|
+
* Fetches FA2 token balances for a given account.
|
|
363
|
+
* When `tokenFilter` is omitted, all FA2 token balances are returned.
|
|
364
|
+
* Pass `tokenFilter` to query a specific FA2 contract + token id (e.g. send-max for FA2).
|
|
365
|
+
* https://api.tzkt.io/#operation/Tokens_GetTokenBalances
|
|
366
|
+
*/
|
|
367
|
+
async getTokensBalances(address, tokenFilter) {
|
|
368
|
+
const params = {
|
|
369
|
+
account: address,
|
|
370
|
+
'token.standard': 'fa2',
|
|
371
|
+
};
|
|
372
|
+
if (tokenFilter) {
|
|
373
|
+
params['token.contract'] = tokenFilter.contractAddress;
|
|
374
|
+
params['token.tokenId'] = String(tokenFilter.tokenId);
|
|
375
|
+
}
|
|
376
|
+
const { data } = await (0, live_network_1.default)({
|
|
377
|
+
url: `${explorerUrl}/v1/tokens/balances`,
|
|
378
|
+
params,
|
|
379
|
+
});
|
|
380
|
+
return data;
|
|
381
|
+
},
|
|
382
|
+
};
|
|
383
|
+
return api;
|
|
384
|
+
}
|
|
377
385
|
// TODO this has same purpose as api/listOperations
|
|
378
|
-
const fetchAllTransactions = async (address, lastId) => {
|
|
386
|
+
const fetchAllTransactions = async (config, address, lastId) => {
|
|
387
|
+
const api = createTzktApi(config);
|
|
379
388
|
let ops = [];
|
|
380
|
-
let maxIteration =
|
|
389
|
+
let maxIteration = config.explorer.maxTxQuery;
|
|
381
390
|
do {
|
|
382
391
|
const newOps = await api.getAccountOperations(address, {
|
|
383
392
|
lastId,
|
|
@@ -406,10 +415,10 @@ exports.fetchAllTransactions = fetchAllTransactions;
|
|
|
406
415
|
* requests when needed and is therefore safe for dense blocks.
|
|
407
416
|
* A safety cap (`maxTxQuery`) prevents infinite loops on pathological responses.
|
|
408
417
|
*/
|
|
409
|
-
async function fetchBlockPaginated(pageFn, level, label) {
|
|
418
|
+
async function fetchBlockPaginated(config, pageFn, level, label) {
|
|
410
419
|
const items = [];
|
|
411
420
|
let cursor;
|
|
412
|
-
let maxIteration =
|
|
421
|
+
let maxIteration = config.explorer.maxTxQuery;
|
|
413
422
|
do {
|
|
414
423
|
const page = await pageFn(level, cursor);
|
|
415
424
|
if (page.length === 0)
|
|
@@ -424,17 +433,16 @@ async function fetchBlockPaginated(pageFn, level, label) {
|
|
|
424
433
|
}
|
|
425
434
|
return items;
|
|
426
435
|
}
|
|
427
|
-
const fetchBlockTransactions = (level) => fetchBlockPaginated(
|
|
436
|
+
const fetchBlockTransactions = (config, level) => fetchBlockPaginated(config, createTzktApi(config).getBlockTransactionsPage, level, 'fetchBlockTransactions');
|
|
428
437
|
exports.fetchBlockTransactions = fetchBlockTransactions;
|
|
429
|
-
const fetchBlockTokenTransfers = (level) => fetchBlockPaginated(
|
|
438
|
+
const fetchBlockTokenTransfers = (config, level) => fetchBlockPaginated(config, createTzktApi(config).getBlockTokenTransfersPage, level, 'fetchBlockTokenTransfers');
|
|
430
439
|
exports.fetchBlockTokenTransfers = fetchBlockTokenTransfers;
|
|
431
|
-
const fetchBlockDelegations = (level) => fetchBlockPaginated(
|
|
440
|
+
const fetchBlockDelegations = (config, level) => fetchBlockPaginated(config, createTzktApi(config).getBlockDelegationsPage, level, 'fetchBlockDelegations');
|
|
432
441
|
exports.fetchBlockDelegations = fetchBlockDelegations;
|
|
433
|
-
const fetchBlockStaking = (level) => fetchBlockPaginated(
|
|
442
|
+
const fetchBlockStaking = (config, level) => fetchBlockPaginated(config, createTzktApi(config).getBlockStakingPage, level, 'fetchBlockStaking');
|
|
434
443
|
exports.fetchBlockStaking = fetchBlockStaking;
|
|
435
|
-
const fetchBlockOriginations = (level) => fetchBlockPaginated(
|
|
444
|
+
const fetchBlockOriginations = (config, level) => fetchBlockPaginated(config, createTzktApi(config).getBlockOriginationsPage, level, 'fetchBlockOriginations');
|
|
436
445
|
exports.fetchBlockOriginations = fetchBlockOriginations;
|
|
437
|
-
const fetchBlockReveals = (level) => fetchBlockPaginated(
|
|
446
|
+
const fetchBlockReveals = (config, level) => fetchBlockPaginated(config, createTzktApi(config).getBlockRevealsPage, level, 'fetchBlockReveals');
|
|
438
447
|
exports.fetchBlockReveals = fetchBlockReveals;
|
|
439
|
-
exports.default = api;
|
|
440
448
|
//# sourceMappingURL=tzkt.js.map
|