@ocap/indexdb-sqlite 1.29.5

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 (42) hide show
  1. package/README.md +84 -0
  2. package/esm/_virtual/rolldown_runtime.mjs +21 -0
  3. package/esm/db/base.d.mts +76 -0
  4. package/esm/db/base.mjs +666 -0
  5. package/esm/db/index.d.mts +80 -0
  6. package/esm/db/index.mjs +551 -0
  7. package/esm/index.d.mts +3 -0
  8. package/esm/index.mjs +8 -0
  9. package/esm/interfaces.d.mts +328 -0
  10. package/esm/interfaces.mjs +1 -0
  11. package/esm/kysely.d.mts +43 -0
  12. package/esm/kysely.mjs +62 -0
  13. package/esm/migrations/001-genesis.d.mts +14 -0
  14. package/esm/migrations/001-genesis.mjs +107 -0
  15. package/esm/migrations/index.d.mts +16 -0
  16. package/esm/migrations/index.mjs +44 -0
  17. package/esm/package.mjs +70 -0
  18. package/esm/table/base.d.mts +107 -0
  19. package/esm/table/base.mjs +262 -0
  20. package/esm/table/transaction.d.mts +18 -0
  21. package/esm/table/transaction.mjs +22 -0
  22. package/lib/_virtual/rolldown_runtime.cjs +43 -0
  23. package/lib/db/base.cjs +670 -0
  24. package/lib/db/base.d.cts +76 -0
  25. package/lib/db/index.cjs +552 -0
  26. package/lib/db/index.d.cts +80 -0
  27. package/lib/index.cjs +10 -0
  28. package/lib/index.d.cts +3 -0
  29. package/lib/interfaces.cjs +0 -0
  30. package/lib/interfaces.d.cts +328 -0
  31. package/lib/kysely.cjs +63 -0
  32. package/lib/kysely.d.cts +43 -0
  33. package/lib/migrations/001-genesis.cjs +114 -0
  34. package/lib/migrations/001-genesis.d.cts +14 -0
  35. package/lib/migrations/index.cjs +46 -0
  36. package/lib/migrations/index.d.cts +16 -0
  37. package/lib/package.cjs +76 -0
  38. package/lib/table/base.cjs +265 -0
  39. package/lib/table/base.d.cts +107 -0
  40. package/lib/table/transaction.cjs +24 -0
  41. package/lib/table/transaction.d.cts +18 -0
  42. package/package.json +75 -0
@@ -0,0 +1,666 @@
1
+ import { BaseIndexDB, formatDelegationAfterRead, formatNextPagination, formatPagination, parseDateTime } from "@ocap/indexdb";
2
+ import { toChecksumAddress } from "@arcblock/did/lib/type";
3
+ import { BN } from "@ocap/util";
4
+ import { DEFAULT_TOKEN_DECIMAL } from "@ocap/util/lib/constant";
5
+ import debugFactory from "debug";
6
+ import omit from "lodash/omit.js";
7
+
8
+ //#region src/db/base.ts
9
+ const debug = debugFactory("@ocap/indexdb-sqlite");
10
+ const MAX_REQUEST_FACTORY_ADDRESS_SIZE = 100;
11
+ function buildPagingResult(total, pagination, itemCount) {
12
+ return {
13
+ cursor: String(pagination.cursor + itemCount),
14
+ next: itemCount >= pagination.size,
15
+ total
16
+ };
17
+ }
18
+ /**
19
+ * Base SQLite IndexDB implementation
20
+ * Contains all the list methods with SQL-based filtering
21
+ */
22
+ var SqliteBaseIndexDB = class extends BaseIndexDB {
23
+ /**
24
+ * List transactions with filtering and pagination
25
+ */
26
+ async listTransactions(params = {}) {
27
+ const { addressFilter = {}, paging = {}, timeFilter = {}, typeFilter = {}, assetFilter = {}, factoryFilter = {}, tokenFilter = {}, accountFilter = {}, validityFilter = {}, txFilter = {}, rollupFilter = {}, stakeFilter = {}, delegationFilter = {}, tokenFactoryFilter = {}, includeItxData = false } = params;
28
+ const { sender, receiver, direction = "UNION" } = addressFilter;
29
+ const { types = [] } = typeFilter;
30
+ const { factories = [] } = factoryFilter;
31
+ const { assets = [] } = assetFilter;
32
+ const { tokens = [] } = tokenFilter;
33
+ const { accounts = [] } = accountFilter;
34
+ const { txs = [] } = txFilter;
35
+ const { rollups = [] } = rollupFilter;
36
+ const { stakes = [] } = stakeFilter;
37
+ const { delegations = [] } = delegationFilter;
38
+ const { tokenFactories = [] } = tokenFactoryFilter;
39
+ const pagination = formatPagination({
40
+ paging,
41
+ defaultSortField: "time"
42
+ });
43
+ debug("listTransactions", {
44
+ sender,
45
+ receiver,
46
+ pagination,
47
+ types,
48
+ factories,
49
+ assets,
50
+ tokens,
51
+ accounts,
52
+ rollups,
53
+ stakes,
54
+ delegations,
55
+ includeItxData
56
+ });
57
+ let qb = this.db.selectFrom("tx").selectAll();
58
+ if (sender && receiver) if (direction === "MUTUAL") qb = qb.where((eb) => eb.or([eb.and([eb("sender", "=", sender), eb("receiver", "=", receiver)]), eb.and([eb("sender", "=", receiver), eb("receiver", "=", sender)])]));
59
+ else if (direction === "ONE_WAY") qb = qb.where("sender", "=", sender).where("receiver", "=", receiver);
60
+ else qb = qb.where((eb) => eb.or([eb("sender", "=", sender), eb("receiver", "=", receiver)]));
61
+ else if (sender) qb = qb.where("sender", "=", sender);
62
+ else if (receiver) qb = qb.where("receiver", "=", receiver);
63
+ if (types.length) qb = qb.where("type", "in", types);
64
+ if (txs.length) qb = qb.where("hash", "in", txs);
65
+ const { startDateTime, endDateTime } = timeFilter;
66
+ const parsedStart = parseDateTime(startDateTime);
67
+ const parsedEnd = parseDateTime(endDateTime);
68
+ if (parsedStart && parsedEnd) qb = qb.where("time", ">", parsedStart).where("time", "<=", parsedEnd);
69
+ else if (parsedStart) qb = qb.where("time", ">", parsedStart);
70
+ else if (parsedEnd) qb = qb.where("time", "<=", parsedEnd);
71
+ const { validity } = validityFilter;
72
+ if (validity === "VALID") qb = qb.where("valid", "=", 1);
73
+ else if (validity === "INVALID") qb = qb.where("valid", "=", 0);
74
+ if (factories.length) qb = qb.where((eb) => eb.exists(eb.selectFrom(eb.fn("json_each", [eb.ref("factories")]).as("je")).select("je.value").where("je.value", "in", factories)));
75
+ if (assets.length) qb = qb.where((eb) => eb.exists(eb.selectFrom(eb.fn("json_each", [eb.ref("assets")]).as("je")).select("je.value").where("je.value", "in", assets)));
76
+ if (tokens.length) qb = qb.where((eb) => eb.exists(eb.selectFrom(eb.fn("json_each", [eb.ref("tokens")]).as("je")).select("je.value").where("je.value", "in", tokens)));
77
+ if (accounts.length) qb = qb.where((eb) => eb.exists(eb.selectFrom(eb.fn("json_each", [eb.ref("accounts")]).as("je")).select("je.value").where("je.value", "in", accounts)));
78
+ if (rollups.length) qb = qb.where((eb) => eb.exists(eb.selectFrom(eb.fn("json_each", [eb.ref("rollups")]).as("je")).select("je.value").where("je.value", "in", rollups)));
79
+ if (stakes.length) qb = qb.where((eb) => eb.exists(eb.selectFrom(eb.fn("json_each", [eb.ref("stakes")]).as("je")).select("je.value").where("je.value", "in", stakes)));
80
+ if (delegations.length) qb = qb.where((eb) => eb.exists(eb.selectFrom(eb.fn("json_each", [eb.ref("delegations")]).as("je")).select("je.value").where("je.value", "in", delegations)));
81
+ if (tokenFactories.length) qb = qb.where((eb) => eb.exists(eb.selectFrom(eb.fn("json_each", [eb.ref("tokenFactories")]).as("je")).select("je.value").where("je.value", "in", tokenFactories)));
82
+ const total = (await qb.clearSelect().select(this.db.fn.countAll().as("count")).executeTakeFirst())?.count ?? 0;
83
+ const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
84
+ qb = qb.orderBy(pagination.order.field, orderDir).offset(pagination.cursor).limit(pagination.size);
85
+ let transactions = (await qb.execute()).map((row) => {
86
+ const tx = { ...row };
87
+ [
88
+ "receipts",
89
+ "tx",
90
+ "accounts",
91
+ "assets",
92
+ "tokens",
93
+ "tokenSymbols",
94
+ "factories",
95
+ "rollups",
96
+ "stakes",
97
+ "delegations",
98
+ "tokenFactories",
99
+ "data"
100
+ ].forEach((field) => {
101
+ if (typeof tx[field] === "string") try {
102
+ tx[field] = JSON.parse(tx[field]);
103
+ } catch {}
104
+ });
105
+ return tx;
106
+ });
107
+ if (!includeItxData) transactions = transactions.map((tx) => {
108
+ const row = tx;
109
+ if (row.tx && row.tx?.itxJson) return {
110
+ ...tx,
111
+ tx: {
112
+ ...row.tx,
113
+ itxJson: omit(row.tx.itxJson, ["data"])
114
+ }
115
+ };
116
+ return tx;
117
+ });
118
+ return {
119
+ transactions,
120
+ paging: buildPagingResult(total, pagination, transactions.length)
121
+ };
122
+ }
123
+ /**
124
+ * Get related addresses for account migration tracking
125
+ */
126
+ async getRelatedAddresses(address) {
127
+ let account = await this.account.get(address);
128
+ if (!account) return [];
129
+ const related = [address];
130
+ while (account?.migratedFrom && related.length <= 8) {
131
+ const migratedFrom = account.migratedFrom;
132
+ related.push(migratedFrom);
133
+ account = await this.account.get(migratedFrom);
134
+ }
135
+ return related.filter(Boolean);
136
+ }
137
+ /**
138
+ * List assets with filtering and pagination
139
+ */
140
+ async listAssets(params = {}) {
141
+ const { ownerAddress, factoryAddress, paging, timeFilter = {} } = params;
142
+ if (!ownerAddress && !factoryAddress) return {
143
+ assets: [],
144
+ account: null,
145
+ paging: {
146
+ cursor: "0",
147
+ next: false,
148
+ total: 0
149
+ }
150
+ };
151
+ const pagination = formatPagination({
152
+ paging,
153
+ defaultSortField: "renaissanceTime"
154
+ });
155
+ let qb = this.db.selectFrom("asset").selectAll();
156
+ if (ownerAddress) {
157
+ const possibleOwners = await this.getRelatedAddresses(ownerAddress);
158
+ if (possibleOwners.length) qb = qb.where("owner", "in", possibleOwners);
159
+ else return {
160
+ assets: [],
161
+ account: null,
162
+ paging: {
163
+ cursor: "0",
164
+ next: false,
165
+ total: 0
166
+ }
167
+ };
168
+ }
169
+ if (factoryAddress) qb = qb.where("parent", "=", factoryAddress);
170
+ const { startDateTime, endDateTime, field: rawField = "renaissanceTime" } = timeFilter;
171
+ const parsedStart = parseDateTime(startDateTime);
172
+ const parsedEnd = parseDateTime(endDateTime);
173
+ const timeField = [
174
+ "genesisTime",
175
+ "renaissanceTime",
176
+ "consumedTime"
177
+ ].includes(rawField) ? rawField : "renaissanceTime";
178
+ if (parsedStart && parsedEnd) qb = qb.where(timeField, ">", parsedStart).where(timeField, "<=", parsedEnd);
179
+ else if (parsedStart) qb = qb.where(timeField, ">", parsedStart);
180
+ else if (parsedEnd) qb = qb.where(timeField, "<=", parsedEnd);
181
+ debug("listAssets", {
182
+ ownerAddress,
183
+ factoryAddress,
184
+ timeFilter,
185
+ paging,
186
+ pagination
187
+ });
188
+ const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
189
+ qb = qb.orderBy(pagination.order.field, orderDir).offset(pagination.cursor).limit(pagination.size);
190
+ const assets = (await qb.execute()).map((row) => {
191
+ const asset = { ...row };
192
+ [
193
+ "display",
194
+ "tags",
195
+ "stake",
196
+ "data"
197
+ ].forEach((field) => {
198
+ if (typeof asset[field] === "string") try {
199
+ asset[field] = JSON.parse(asset[field]);
200
+ } catch {}
201
+ });
202
+ return asset;
203
+ });
204
+ const countConditions = {};
205
+ if (ownerAddress) countConditions.owner = { $in: await this.getRelatedAddresses(ownerAddress) };
206
+ if (factoryAddress) countConditions.parent = factoryAddress;
207
+ const total = await this.asset.count(Object.keys(countConditions).length ? countConditions : void 0);
208
+ return {
209
+ assets,
210
+ account: ownerAddress ? await this.account.get(ownerAddress) : null,
211
+ paging: formatNextPagination(total, pagination)
212
+ };
213
+ }
214
+ /**
215
+ * List top accounts by token balance
216
+ */
217
+ async listTopAccounts(params = {}) {
218
+ const { paging, tokenAddress } = params;
219
+ const pagination = formatPagination({
220
+ paging,
221
+ defaultSortField: "balance",
222
+ supportedSortFields: [
223
+ "genesisTime",
224
+ "renaissanceTime",
225
+ "balance"
226
+ ]
227
+ });
228
+ debug("listTopAccounts", {
229
+ tokenAddress,
230
+ paging,
231
+ pagination
232
+ });
233
+ let qb = this.db.selectFrom("account").selectAll();
234
+ if (pagination.order.field !== "balance") {
235
+ const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
236
+ qb = qb.orderBy(pagination.order.field, orderDir);
237
+ }
238
+ let accounts = (await qb.execute()).map((row) => {
239
+ const account = { ...row };
240
+ [
241
+ "stake",
242
+ "tokens",
243
+ "data"
244
+ ].forEach((field) => {
245
+ if (typeof account[field] === "string") try {
246
+ account[field] = JSON.parse(account[field]);
247
+ } catch {}
248
+ });
249
+ if (Array.isArray(account.tokens)) account.tokens = account.tokens?.map((token) => {
250
+ token.decimal = typeof token.decimal === "undefined" ? DEFAULT_TOKEN_DECIMAL : token.decimal;
251
+ return token;
252
+ });
253
+ return account;
254
+ });
255
+ if (tokenAddress) accounts = accounts.filter((acc) => {
256
+ const tokens = acc.tokens;
257
+ if (!Array.isArray(tokens)) return false;
258
+ const owned = tokens.find((t) => t.address === tokenAddress);
259
+ return owned ? owned.balance > "0" : false;
260
+ });
261
+ if (pagination.order.field === "balance" && tokenAddress) {
262
+ const descending = pagination.order.type === "desc";
263
+ accounts.sort((a, b) => {
264
+ const tokensA = a.tokens;
265
+ const tokensB = b.tokens;
266
+ const tokenA = tokensA?.find((t) => t.address === tokenAddress);
267
+ const tokenB = tokensB?.find((t) => t.address === tokenAddress);
268
+ const balanceA = new BN(tokenA ? tokenA.balance : "0");
269
+ const balanceB = new BN(tokenB ? tokenB.balance : "0");
270
+ if (balanceB.gt(balanceA)) return descending ? 1 : -1;
271
+ if (balanceB.eq(balanceA)) return 0;
272
+ return descending ? -1 : 1;
273
+ });
274
+ }
275
+ const total = accounts.length;
276
+ accounts = accounts.slice(pagination.cursor, pagination.cursor + pagination.size);
277
+ return {
278
+ accounts,
279
+ paging: formatNextPagination(total, pagination)
280
+ };
281
+ }
282
+ /**
283
+ * List tokens with filtering and pagination
284
+ */
285
+ async listTokens(params = {}) {
286
+ const { issuerAddress, paging } = params;
287
+ const pagination = formatPagination({
288
+ paging,
289
+ defaultSortField: "renaissanceTime",
290
+ supportedSortFields: [
291
+ "genesisTime",
292
+ "renaissanceTime",
293
+ "issuer",
294
+ "symbol",
295
+ "totalSupply"
296
+ ]
297
+ });
298
+ debug("listTokens", {
299
+ issuerAddress,
300
+ paging,
301
+ pagination
302
+ });
303
+ let qb = this.db.selectFrom("token").selectAll();
304
+ if (issuerAddress) qb = qb.where("issuer", "=", issuerAddress);
305
+ const orderField = pagination.order.field === "totalSupply" ? "totalSupplyNum" : pagination.order.field;
306
+ const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
307
+ qb = qb.orderBy(orderField, orderDir).offset(pagination.cursor).limit(pagination.size);
308
+ return {
309
+ tokens: (await qb.execute()).map((row) => {
310
+ const token = { ...row };
311
+ [
312
+ "foreignToken",
313
+ "metadata",
314
+ "spenders",
315
+ "minters",
316
+ "data"
317
+ ].forEach((field) => {
318
+ if (typeof token[field] === "string") try {
319
+ token[field] = JSON.parse(token[field]);
320
+ } catch {}
321
+ });
322
+ const t = token;
323
+ t.decimal = typeof t.decimal === "undefined" ? DEFAULT_TOKEN_DECIMAL : t.decimal;
324
+ return t;
325
+ }),
326
+ paging: formatNextPagination(await this.token.count(issuerAddress ? { issuer: issuerAddress } : void 0), pagination)
327
+ };
328
+ }
329
+ /**
330
+ * List token factories (bonding curve)
331
+ */
332
+ async listTokenFactories(params = {}) {
333
+ const { owner, reserveAddress, tokenAddress, paging } = params;
334
+ const pagination = formatPagination({
335
+ paging,
336
+ defaultSortField: "renaissanceTime",
337
+ supportedSortFields: [
338
+ "genesisTime",
339
+ "renaissanceTime",
340
+ "reserveBalance",
341
+ "currentSupply"
342
+ ]
343
+ });
344
+ debug("listTokenFactories", {
345
+ owner,
346
+ reserveAddress,
347
+ tokenAddress,
348
+ paging,
349
+ pagination
350
+ });
351
+ let qb = this.db.selectFrom("tokenFactory").selectAll();
352
+ if (owner) qb = qb.where("owner", "=", owner);
353
+ if (reserveAddress) qb = qb.where("reserveAddress", "=", reserveAddress);
354
+ if (tokenAddress) qb = qb.where("tokenAddress", "=", tokenAddress);
355
+ const orderField = pagination.order.field === "reserveBalance" ? "reserveBalanceNum" : pagination.order.field === "currentSupply" ? "currentSupplyNum" : pagination.order.field;
356
+ const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
357
+ qb = qb.orderBy(orderField, orderDir).offset(pagination.cursor).limit(pagination.size);
358
+ const tokenFactories = (await qb.execute()).map((row) => {
359
+ const tf = { ...row };
360
+ [
361
+ "curve",
362
+ "token",
363
+ "reserveToken",
364
+ "input",
365
+ "output",
366
+ "data"
367
+ ].forEach((field) => {
368
+ if (typeof tf[field] === "string") try {
369
+ tf[field] = JSON.parse(tf[field]);
370
+ } catch {}
371
+ });
372
+ return tf;
373
+ });
374
+ const conditions = {};
375
+ if (owner) conditions.owner = owner;
376
+ if (reserveAddress) conditions.reserveAddress = reserveAddress;
377
+ if (tokenAddress) conditions.tokenAddress = tokenAddress;
378
+ return {
379
+ tokenFactories,
380
+ paging: formatNextPagination(await this.tokenFactory.count(Object.keys(conditions).length ? conditions : void 0), pagination)
381
+ };
382
+ }
383
+ /**
384
+ * List asset factories
385
+ */
386
+ async listFactories(params = {}) {
387
+ const { ownerAddress, addressList, paging } = params;
388
+ const pagination = formatPagination({
389
+ paging,
390
+ defaultSortField: "renaissanceTime",
391
+ supportedSortFields: [
392
+ "genesisTime",
393
+ "renaissanceTime",
394
+ "owner",
395
+ "numMinted",
396
+ "limit",
397
+ "name"
398
+ ]
399
+ });
400
+ debug("listFactories", {
401
+ ownerAddress,
402
+ paging,
403
+ pagination
404
+ });
405
+ let qb = this.db.selectFrom("factory").selectAll();
406
+ if (ownerAddress) qb = qb.where("owner", "=", ownerAddress);
407
+ if (Array.isArray(addressList) && addressList.length > 0) {
408
+ if (addressList.length > MAX_REQUEST_FACTORY_ADDRESS_SIZE) throw new Error(`The length of 'addressList' cannot exceed the length of ${MAX_REQUEST_FACTORY_ADDRESS_SIZE}`);
409
+ qb = qb.where("address", "in", addressList);
410
+ }
411
+ const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
412
+ qb = qb.orderBy(pagination.order.field, orderDir).offset(pagination.cursor).limit(pagination.size);
413
+ const factories = (await qb.execute()).map((row) => {
414
+ const factory = { ...row };
415
+ [
416
+ "trustedIssuers",
417
+ "tokens",
418
+ "input",
419
+ "output",
420
+ "display",
421
+ "hooks",
422
+ "data"
423
+ ].forEach((field) => {
424
+ if (typeof factory[field] === "string") try {
425
+ factory[field] = JSON.parse(factory[field]);
426
+ } catch {}
427
+ });
428
+ return factory;
429
+ });
430
+ const conditions = {};
431
+ if (ownerAddress) conditions.owner = ownerAddress;
432
+ if (Array.isArray(addressList) && addressList.length) conditions.address = { $in: addressList };
433
+ return {
434
+ factories,
435
+ paging: formatNextPagination(await this.factory.count(Object.keys(conditions).length ? conditions : void 0), pagination)
436
+ };
437
+ }
438
+ /**
439
+ * List stakes
440
+ */
441
+ async listStakes(params = {}) {
442
+ const { addressFilter = {}, paging = {}, timeFilter = {}, assetFilter = {} } = params;
443
+ const { sender, receiver } = addressFilter;
444
+ const { assets = [] } = assetFilter;
445
+ const pagination = formatPagination({
446
+ paging,
447
+ defaultSortField: "renaissanceTime",
448
+ supportedSortFields: ["genesisTime", "renaissanceTime"]
449
+ });
450
+ let qb = this.db.selectFrom("stake").selectAll();
451
+ if (sender && receiver) qb = qb.where("sender", "=", sender).where("receiver", "=", receiver);
452
+ else if (sender) qb = qb.where("sender", "=", sender);
453
+ else if (receiver) qb = qb.where("receiver", "=", receiver);
454
+ const { startDateTime, endDateTime } = timeFilter;
455
+ const parsedStart = parseDateTime(startDateTime);
456
+ const parsedEnd = parseDateTime(endDateTime);
457
+ if (parsedStart && parsedEnd) qb = qb.where("renaissanceTime", ">", parsedStart).where("renaissanceTime", "<=", parsedEnd);
458
+ else if (parsedStart) qb = qb.where("renaissanceTime", ">", parsedStart);
459
+ else if (parsedEnd) qb = qb.where("renaissanceTime", "<=", parsedEnd);
460
+ if (assets.length) qb = qb.where((eb) => eb.exists(eb.selectFrom(eb.fn("json_each", [eb.ref("assets")]).as("je")).select("je.value").where("je.value", "in", assets)));
461
+ const total = (await qb.clearSelect().select(this.db.fn.countAll().as("count")).executeTakeFirst())?.count ?? 0;
462
+ const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
463
+ qb = qb.orderBy(pagination.order.field, orderDir).offset(pagination.cursor).limit(pagination.size);
464
+ const stakes = (await qb.execute()).map((row) => {
465
+ const stake = { ...row };
466
+ [
467
+ "tokens",
468
+ "revokedTokens",
469
+ "assets",
470
+ "revokedAssets",
471
+ "slashers",
472
+ "data"
473
+ ].forEach((field) => {
474
+ if (typeof stake[field] === "string") try {
475
+ stake[field] = JSON.parse(stake[field]);
476
+ } catch {}
477
+ });
478
+ return stake;
479
+ });
480
+ return {
481
+ stakes,
482
+ paging: buildPagingResult(total, pagination, stakes.length)
483
+ };
484
+ }
485
+ /**
486
+ * List rollups
487
+ */
488
+ async listRollups(params = {}) {
489
+ const { paging, tokenAddress = "", erc20TokenAddress = "", foreignTokenAddress = "" } = params;
490
+ const pagination = formatPagination({
491
+ paging,
492
+ defaultSortField: "renaissanceTime",
493
+ supportedSortFields: ["genesisTime", "renaissanceTime"]
494
+ });
495
+ let qb = this.db.selectFrom("rollup").selectAll();
496
+ if (tokenAddress) qb = qb.where("tokenAddress", "=", tokenAddress);
497
+ const foreignTokenAddr = foreignTokenAddress || erc20TokenAddress;
498
+ if (foreignTokenAddr) {
499
+ const checksumAddr = toChecksumAddress(foreignTokenAddr);
500
+ const lowerAddr = foreignTokenAddr.toLowerCase();
501
+ qb = qb.where((eb) => eb.or([eb(eb.fn("json_extract", [eb.ref("foreignToken"), eb.val("$.contractAddress")]), "=", checksumAddr), eb(eb.fn("json_extract", [eb.ref("foreignToken"), eb.val("$.contractAddress")]), "=", lowerAddr)]));
502
+ }
503
+ debug("listRollups", {
504
+ paging,
505
+ pagination
506
+ });
507
+ const total = (await qb.clearSelect().select(this.db.fn.countAll().as("count")).executeTakeFirst())?.count ?? 0;
508
+ const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
509
+ qb = qb.orderBy(pagination.order.field, orderDir).offset(pagination.cursor).limit(pagination.size);
510
+ return {
511
+ rollups: (await qb.execute()).map((row) => {
512
+ const rollup = { ...row };
513
+ [
514
+ "seedValidators",
515
+ "validators",
516
+ "foreignToken",
517
+ "tokenInfo",
518
+ "migrateHistory",
519
+ "vaultHistory",
520
+ "data"
521
+ ].forEach((field) => {
522
+ if (typeof rollup[field] === "string") try {
523
+ rollup[field] = JSON.parse(rollup[field]);
524
+ } catch {}
525
+ });
526
+ return rollup;
527
+ }),
528
+ paging: formatNextPagination(total, pagination)
529
+ };
530
+ }
531
+ /**
532
+ * List rollup blocks
533
+ */
534
+ async listRollupBlocks(params = {}) {
535
+ const { paging = {}, rollupAddress = "", tokenAddress = "", proposer = "", height = "", timeFilter = {}, txFilter = {}, validatorFilter = {} } = params;
536
+ const { txs = [] } = txFilter;
537
+ const { validators = [] } = validatorFilter;
538
+ const pagination = formatPagination({
539
+ paging,
540
+ defaultSortField: "genesisTime",
541
+ supportedSortFields: ["genesisTime", "renaissanceTime"]
542
+ });
543
+ let qb = this.db.selectFrom("rollupBlock").selectAll();
544
+ if (rollupAddress) qb = qb.where("rollup", "=", rollupAddress);
545
+ if (Number(height) > 0) qb = qb.where("height", "=", Number(height));
546
+ if (proposer) qb = qb.where("proposer", "=", proposer);
547
+ const { startDateTime, endDateTime } = timeFilter;
548
+ const parsedStart = parseDateTime(startDateTime);
549
+ const parsedEnd = parseDateTime(endDateTime);
550
+ if (parsedStart && parsedEnd) qb = qb.where("genesisTime", ">", parsedStart).where("genesisTime", "<=", parsedEnd);
551
+ else if (parsedStart) qb = qb.where("genesisTime", ">", parsedStart);
552
+ else if (parsedEnd) qb = qb.where("genesisTime", "<=", parsedEnd);
553
+ if (txs.length) qb = qb.where((eb) => eb.exists(eb.selectFrom(eb.fn("json_each", [eb.ref("txs")]).as("je")).select("je.value").where("je.value", "in", txs)));
554
+ if (validators.length) qb = qb.where((eb) => eb.exists(eb.selectFrom(eb.fn("json_each", [eb.ref("validators")]).as("je")).select("je.value").where("je.value", "in", validators)));
555
+ if (tokenAddress) qb = qb.where((eb) => eb(eb.fn("json_extract", [eb.ref("tokenInfo"), eb.val("$.address")]), "=", tokenAddress));
556
+ const total = (await qb.clearSelect().select(this.db.fn.countAll().as("count")).executeTakeFirst())?.count ?? 0;
557
+ const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
558
+ qb = qb.orderBy(pagination.order.field, orderDir).offset(pagination.cursor).limit(pagination.size);
559
+ const blocks = (await qb.execute()).map((row) => {
560
+ const block = { ...row };
561
+ [
562
+ "signatures",
563
+ "txs",
564
+ "validators",
565
+ "tokenInfo",
566
+ "data"
567
+ ].forEach((field) => {
568
+ if (typeof block[field] === "string") try {
569
+ block[field] = JSON.parse(block[field]);
570
+ } catch {}
571
+ });
572
+ return block;
573
+ });
574
+ return {
575
+ blocks,
576
+ paging: buildPagingResult(total, pagination, blocks.length)
577
+ };
578
+ }
579
+ /**
580
+ * List rollup validators
581
+ */
582
+ async listRollupValidators(params = {}) {
583
+ const { paging = {}, rollupAddress = "" } = params;
584
+ const pagination = formatPagination({
585
+ paging,
586
+ defaultSortField: "genesisTime",
587
+ supportedSortFields: [
588
+ "joinTime",
589
+ "leaveTime",
590
+ "genesisTime",
591
+ "renaissanceTime"
592
+ ]
593
+ });
594
+ let qb = this.db.selectFrom("rollupValidator").selectAll();
595
+ let countQb = this.db.selectFrom("rollupValidator").select((eb) => eb.fn.countAll().as("count"));
596
+ if (rollupAddress) {
597
+ qb = qb.where("rollup", "=", rollupAddress);
598
+ countQb = countQb.where("rollup", "=", rollupAddress);
599
+ }
600
+ const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
601
+ qb = qb.orderBy(pagination.order.field, orderDir).offset(pagination.cursor).limit(pagination.size);
602
+ const [rawResults, countResult] = await Promise.all([qb.execute(), countQb.executeTakeFirst()]);
603
+ const validators = rawResults.map((row) => row);
604
+ return {
605
+ validators,
606
+ paging: buildPagingResult(Number(countResult?.count || 0), pagination, validators.length)
607
+ };
608
+ }
609
+ /**
610
+ * List delegations
611
+ */
612
+ async listDelegations(params = {}) {
613
+ const { from, to, paging = {}, timeFilter = {} } = params;
614
+ if (!from && !to) return {
615
+ delegations: [],
616
+ paging: {
617
+ cursor: "0",
618
+ next: false,
619
+ total: 0
620
+ }
621
+ };
622
+ const pagination = formatPagination({
623
+ paging,
624
+ defaultSortField: "renaissanceTime",
625
+ supportedSortFields: ["genesisTime", "renaissanceTime"]
626
+ });
627
+ let qb = this.db.selectFrom("delegation").selectAll();
628
+ if (from && to) qb = qb.where("from_", "=", from).where("to_", "=", to);
629
+ else if (from) qb = qb.where("from_", "=", from);
630
+ else if (to) qb = qb.where("to_", "=", to);
631
+ const { startDateTime, endDateTime } = timeFilter;
632
+ const parsedStart = parseDateTime(startDateTime);
633
+ const parsedEnd = parseDateTime(endDateTime);
634
+ if (parsedStart && parsedEnd) qb = qb.where("renaissanceTime", ">", parsedStart).where("renaissanceTime", "<=", parsedEnd);
635
+ else if (parsedStart) qb = qb.where("renaissanceTime", ">", parsedStart);
636
+ else if (parsedEnd) qb = qb.where("renaissanceTime", "<=", parsedEnd);
637
+ const total = (await qb.clearSelect().select(this.db.fn.countAll().as("count")).executeTakeFirst())?.count ?? 0;
638
+ const orderDir = pagination.order.type === "desc" ? "desc" : "asc";
639
+ qb = qb.orderBy(pagination.order.field, orderDir).offset(pagination.cursor).limit(pagination.size);
640
+ const delegations = (await qb.execute()).map((row) => {
641
+ const delegation = { ...row };
642
+ delegation.from = delegation.from_;
643
+ delegation.to = delegation.to_;
644
+ delete delegation.from_;
645
+ delete delegation.to_;
646
+ [
647
+ "ops",
648
+ "context",
649
+ "data"
650
+ ].forEach((field) => {
651
+ if (typeof delegation[field] === "string") try {
652
+ delegation[field] = JSON.parse(delegation[field]);
653
+ } catch {}
654
+ });
655
+ return formatDelegationAfterRead(delegation);
656
+ });
657
+ return {
658
+ delegations,
659
+ paging: buildPagingResult(total, pagination, delegations.length)
660
+ };
661
+ }
662
+ };
663
+ var base_default = SqliteBaseIndexDB;
664
+
665
+ //#endregion
666
+ export { base_default as default };