@ocap/indexdb 1.28.8 → 1.29.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/esm/util.mjs ADDED
@@ -0,0 +1,556 @@
1
+ import { BN } from "@ocap/util";
2
+ import { createSortedList } from "@ocap/util/lib/create-sorted-list";
3
+ import get from "lodash/get.js";
4
+ import pick from "lodash/pick.js";
5
+ import uniq from "lodash/uniq.js";
6
+ import uniqBy from "lodash/uniqBy.js";
7
+
8
+ //#region src/util.ts
9
+ /**
10
+ * Format token with metadata from token states
11
+ * @param token - Token with address
12
+ * @param tokenStates - Array of token states for metadata lookup
13
+ * @param rest - Additional args for debug logging
14
+ */
15
+ const formatTokenMeta = (token, tokenStates, ...rest) => {
16
+ if (!tokenStates) return token;
17
+ const tokenState = tokenStates.filter(Boolean).find((x) => x.address === token.address);
18
+ if (tokenState) {
19
+ token.decimal = tokenState.decimal;
20
+ token.unit = tokenState.unit;
21
+ token.symbol = tokenState.symbol;
22
+ token.icon = tokenState.icon;
23
+ } else console.warn("Invalid token state on formatting", token, tokenStates, ...rest);
24
+ return token;
25
+ };
26
+ /**
27
+ * Create indexed account from account state
28
+ */
29
+ const createIndexedAccount = async (x, getTokenFn) => {
30
+ const tasks = Object.keys(x.tokens || {}).map((address) => getTokenFn(address));
31
+ const tokenStates = await Promise.all(tasks);
32
+ return {
33
+ address: x.address,
34
+ balance: x.balance || "0",
35
+ moniker: x.moniker || "",
36
+ nonce: x.nonce ?? 0,
37
+ numAssets: x.numAssets ?? 0,
38
+ numTxs: x.numTxs ?? 0,
39
+ recentNumTxs: [],
40
+ renaissanceTime: x.context.renaissanceTime,
41
+ tokens: Object.keys(x.tokens || {}).map((address) => formatTokenMeta({
42
+ address,
43
+ balance: x.tokens[address]
44
+ }, tokenStates)),
45
+ genesisTime: x.context.genesisTime,
46
+ migratedTo: x.migratedTo?.[0] || "",
47
+ migratedFrom: x.migratedFrom?.[0] || ""
48
+ };
49
+ };
50
+ /**
51
+ * Create indexed asset from asset state
52
+ * Note: display/endpoint/data types from IAssetState may differ from TIndexedAssetState,
53
+ * they are passed through without transformation
54
+ */
55
+ const createIndexedAsset = (x) => ({
56
+ address: x.address,
57
+ issuer: x.issuer,
58
+ moniker: x.moniker,
59
+ owner: x.owner,
60
+ parent: x.parent,
61
+ readonly: x.readonly,
62
+ transferrable: x.transferrable,
63
+ ttl: String(x.ttl || 0),
64
+ consumedTime: x.consumedTime || "",
65
+ genesisTime: x.context.genesisTime,
66
+ renaissanceTime: x.context.renaissanceTime,
67
+ data: x.data,
68
+ display: x.display,
69
+ endpoint: x.endpoint,
70
+ tags: x.tags || []
71
+ });
72
+ /**
73
+ * Create indexed delegation from delegation state
74
+ */
75
+ const createIndexedDelegation = (x, ctx) => {
76
+ const result = {
77
+ address: x.address,
78
+ data: x.data,
79
+ genesisTime: x.context.genesisTime,
80
+ renaissanceTime: x.context.renaissanceTime,
81
+ ops: [x.ops]
82
+ };
83
+ if (x.from) result.from = x.from;
84
+ else if (ctx.senderState) result.from = get(ctx, "senderState.address", "");
85
+ else result.from = get(ctx, "tx.from", "");
86
+ if (x.to) result.to = x.to;
87
+ else if (ctx.receiverState) result.to = get(ctx, "receiverState.address", "");
88
+ else result.to = get(ctx, "itx.to", "");
89
+ return result;
90
+ };
91
+ /**
92
+ * Create indexed token from token state
93
+ * Note: foreignToken/metadata/data types from ITokenState may differ from TIndexedTokenState,
94
+ * they are passed through without transformation
95
+ */
96
+ const createIndexedToken = (x) => ({
97
+ address: x.address,
98
+ issuer: x.issuer || "",
99
+ name: x.name,
100
+ description: x.description,
101
+ symbol: x.symbol,
102
+ unit: x.unit,
103
+ decimal: x.decimal,
104
+ icon: x.icon || "",
105
+ website: x.website || "",
106
+ totalSupply: x.totalSupply,
107
+ initialSupply: x.initialSupply,
108
+ maxTotalSupply: x.maxTotalSupply || "",
109
+ foreignToken: x.foreignToken,
110
+ tokenFactoryAddress: x.tokenFactoryAddress || "",
111
+ metadata: x.metadata,
112
+ spenders: x.spenders || [],
113
+ minters: x.minters || [],
114
+ type: x.type || "",
115
+ data: x.data,
116
+ genesisTime: x.context.genesisTime,
117
+ renaissanceTime: x.context.renaissanceTime
118
+ });
119
+ /**
120
+ * Create indexed token factory from token factory state
121
+ * Note: token/reserveToken may not have all TIndexedTokenInput fields filled,
122
+ * they are populated with available metadata from context
123
+ */
124
+ const createIndexedTokenFactory = (tokenFactory, context) => {
125
+ return {
126
+ ...pick(tokenFactory, [
127
+ "address",
128
+ "owner",
129
+ "tokenAddress",
130
+ "reserveAddress",
131
+ "curve",
132
+ "feeRate",
133
+ "currentSupply",
134
+ "reserveBalance",
135
+ "status",
136
+ "data"
137
+ ]),
138
+ token: formatTokenMeta({ address: tokenFactory.tokenAddress }, context.itx?.token ? [context.itx.token] : []),
139
+ reserveToken: formatTokenMeta({ address: tokenFactory.reserveAddress }, context.config?.token ? [context.config.token] : []),
140
+ genesisTime: tokenFactory.context.genesisTime,
141
+ renaissanceTime: tokenFactory.context.renaissanceTime
142
+ };
143
+ };
144
+ /**
145
+ * Create indexed factory from asset factory state
146
+ * Note: tokens array may not have all TTokenMeta fields filled,
147
+ * they are populated with available metadata from context
148
+ */
149
+ const createIndexedFactory = (factory, context) => {
150
+ if (context.factoryTokens && context.factoryTokens.length > 0 && factory.input?.tokens) factory.input.tokens = factory.input.tokens.map((token) => formatTokenMeta(token, context.tokenStates));
151
+ return {
152
+ ...pick(factory, [
153
+ "address",
154
+ "owner",
155
+ "name",
156
+ "description",
157
+ "settlement",
158
+ "limit",
159
+ "trustedIssuers",
160
+ "input",
161
+ "output",
162
+ "hooks",
163
+ "data",
164
+ "numMinted",
165
+ "lastSettlement",
166
+ "balance",
167
+ "display"
168
+ ]),
169
+ tokens: Object.keys(factory.tokens || {}).map((address) => formatTokenMeta({
170
+ address,
171
+ balance: factory.tokens[address]
172
+ }, context.tokenStates)),
173
+ genesisTime: factory.context.genesisTime,
174
+ renaissanceTime: factory.context.renaissanceTime
175
+ };
176
+ };
177
+ /**
178
+ * Create indexed transaction from transaction context
179
+ * These fields are used internally to filter transactions by some entity
180
+ */
181
+ const createIndexedTransaction = async (tx, ctx, indexdb) => {
182
+ tx.accounts = [
183
+ tx.tx.from,
184
+ tx.sender,
185
+ tx.receiver
186
+ ].filter(Boolean);
187
+ tx.assets = [];
188
+ tx.tokens = [];
189
+ tx.factories = [];
190
+ tx.stakes = [];
191
+ tx.rollups = [];
192
+ tx.delegations = [];
193
+ tx.tokenFactories = [];
194
+ tx.valid = tx.code === "OK";
195
+ if (ctx.senderState) tx.accounts.push(ctx.senderState.address);
196
+ if (ctx.receiverState) tx.accounts.push(ctx.receiverState.address);
197
+ if (ctx.feeVaultState && ctx.feeVaultChange) tx.accounts.push(ctx.feeVaultState.address);
198
+ if (ctx.gasVaultState && ctx.gasVaultChange) tx.accounts.push(ctx.gasVaultState.address);
199
+ if (ctx.updatedAccounts && Array.isArray(ctx.updatedAccounts)) tx.accounts.push(...ctx.updatedAccounts.map((x) => x.address));
200
+ if (ctx.delegatorState) tx.accounts.push(ctx.delegatorState.address);
201
+ if (ctx.delegationState) tx.delegations.push(ctx.delegationState.address);
202
+ if (ctx.delegationState && ctx.txType === "fg:t:revoke_delegate") {
203
+ const indexed = await indexdb.delegation?.get(ctx.delegationState.address);
204
+ if (indexed) tx.accounts.push(indexed.to);
205
+ }
206
+ if (Array.isArray(ctx.delegatorStates)) tx.accounts.push(...ctx.delegatorStates.map((x) => x.address));
207
+ if (Array.isArray(ctx.signerStates)) tx.accounts.push(...ctx.signerStates.map((x) => x.address));
208
+ if (Array.isArray(ctx.receiverStates)) tx.accounts.push(...ctx.receiverStates.map((x) => x.address));
209
+ if (ctx.assetState) {
210
+ tx.assets.push(ctx.assetState.address);
211
+ if (ctx.txType === "fg:t:update_asset") tx.accounts.push(ctx.assetState.owner);
212
+ if (ctx.txType === "fg:t:mint_asset") tx.accounts.push(ctx.ownerAddress);
213
+ }
214
+ if (ctx.assetStates && Array.isArray(ctx.assetStates)) tx.assets.push(...ctx.assetStates.map((x) => x.address));
215
+ if (ctx.tokenState) tx.tokens.push(ctx.tokenState.address);
216
+ if (ctx.tokenStates && Array.isArray(ctx.tokenStates)) tx.tokens.push(...ctx.tokenStates.map((x) => x.address));
217
+ if (ctx.factoryState) tx.factories.push(ctx.factoryState.address);
218
+ if (ctx.stakeState) {
219
+ tx.stakes.push(ctx.stakeState.address);
220
+ if (ctx.txType === "fg:t:slash_stake") tx.accounts.push(ctx.stakeState.sender);
221
+ if (ctx.txType === "fg:t:return_stake") tx.accounts.push(ctx.stakeState.sender);
222
+ }
223
+ if (Array.isArray(ctx.stakeStates)) tx.stakes.push(...ctx.stakeStates.map((x) => x.address));
224
+ if (ctx.rollupState) tx.rollups.push(ctx.rollupState.address);
225
+ if (ctx.tokenFactoryState) tx.tokenFactories.push(ctx.tokenFactoryState.address);
226
+ const pickedFields = [
227
+ "address",
228
+ "symbol",
229
+ "decimal",
230
+ "unit"
231
+ ];
232
+ if (Array.isArray(ctx.tokenStates)) tx.tokenSymbols = ctx.tokenStates.map((t) => pick(t, pickedFields));
233
+ else if (ctx.tokenState) tx.tokenSymbols = [pick(ctx.tokenState, pickedFields)];
234
+ else tx.tokenSymbols = [];
235
+ tx.accounts = [...tx.accounts, ...tx.stakes];
236
+ return tx;
237
+ };
238
+ /**
239
+ * Create indexed stake from stake state
240
+ * Note: tokens/revokedTokens arrays may not have all TTokenMeta fields filled,
241
+ * they are populated with available metadata from context
242
+ */
243
+ const createIndexedStake = async (x, ctx, indexdb) => {
244
+ const tokens = uniq(Object.keys(x.tokens || {}).concat(Object.keys(x.revokedTokens || {})));
245
+ const existTokenStates = ctx.tokenStates || [];
246
+ const missingTokenStates = await Promise.all(tokens.filter((a) => !existTokenStates.find((t) => t.address === a)).map((t) => indexdb.token?.get(t)));
247
+ const tokenStates = [...existTokenStates, ...missingTokenStates.filter(Boolean)];
248
+ return {
249
+ ...pick(x, [
250
+ "address",
251
+ "sender",
252
+ "receiver",
253
+ "assets",
254
+ "slashers",
255
+ "revocable",
256
+ "data",
257
+ "nonce",
258
+ "message",
259
+ "revokeWaitingPeriod",
260
+ "revokedAssets"
261
+ ]),
262
+ tokens: Object.keys(x.tokens || {}).map((address) => formatTokenMeta({
263
+ address,
264
+ balance: x.tokens[address]
265
+ }, tokenStates, x)),
266
+ revokedTokens: Object.keys(x.revokedTokens || {}).map((address) => formatTokenMeta({
267
+ address,
268
+ balance: x.revokedTokens[address]
269
+ }, tokenStates)),
270
+ genesisTime: x.context.genesisTime,
271
+ renaissanceTime: x.context.renaissanceTime
272
+ };
273
+ };
274
+ /**
275
+ * Create indexed rollup from rollup state
276
+ * Note: foreignToken from TokenStateInfo is passed through without transformation
277
+ */
278
+ const createIndexedRollup = (x, ctx) => {
279
+ const rollup = {
280
+ ...pick(x, [
281
+ "address",
282
+ "paused",
283
+ "closed",
284
+ "tokenAddress",
285
+ "vaultAddress",
286
+ "contractAddress",
287
+ "seedValidators",
288
+ "validators",
289
+ "minStakeAmount",
290
+ "maxStakeAmount",
291
+ "minSignerCount",
292
+ "maxSignerCount",
293
+ "minBlockSize",
294
+ "maxBlockSize",
295
+ "minBlockInterval",
296
+ "minBlockConfirmation",
297
+ "minDepositAmount",
298
+ "maxDepositAmount",
299
+ "minWithdrawAmount",
300
+ "maxWithdrawAmount",
301
+ "depositFeeRate",
302
+ "withdrawFeeRate",
303
+ "proposerFeeShare",
304
+ "publisherFeeShare",
305
+ "minDepositFee",
306
+ "maxDepositFee",
307
+ "minWithdrawFee",
308
+ "maxWithdrawFee",
309
+ "issuer",
310
+ "blockHeight",
311
+ "blockHash",
312
+ "leaveWaitingPeriod",
313
+ "publishWaitingPeriod",
314
+ "publishSlashRate",
315
+ "migrateHistory",
316
+ "vaultHistory",
317
+ "data"
318
+ ]),
319
+ genesisTime: x.context.genesisTime,
320
+ renaissanceTime: x.context.renaissanceTime
321
+ };
322
+ if (ctx.tokenStates) {
323
+ const tokenState = ctx.tokenStates.find((t) => t.address === x.tokenAddress);
324
+ rollup.tokenInfo = formatTokenMeta({
325
+ address: x.tokenAddress,
326
+ value: "0"
327
+ }, ctx.tokenStates);
328
+ if (tokenState) rollup.foreignToken = tokenState.foreignToken;
329
+ }
330
+ return rollup;
331
+ };
332
+ /**
333
+ * Create indexed rollup block from rollup block state
334
+ * Note: tokenInfo may not have all TIndexedTokenInput fields filled,
335
+ * they are populated with available metadata from context
336
+ */
337
+ const createIndexedRollupBlock = (x, ctx) => {
338
+ const signatures = x.signaturesList || x.signatures || [];
339
+ return {
340
+ ...pick(x, [
341
+ "hash",
342
+ "height",
343
+ "merkleRoot",
344
+ "previousHash",
345
+ "txsHash",
346
+ "txs",
347
+ "proposer",
348
+ "signatures",
349
+ "rollup",
350
+ "mintedAmount",
351
+ "burnedAmount",
352
+ "rewardAmount",
353
+ "minReward",
354
+ "governance",
355
+ "data"
356
+ ]),
357
+ genesisTime: x.context.genesisTime,
358
+ renaissanceTime: x.context.renaissanceTime,
359
+ tokenInfo: ctx.rollupState ? formatTokenMeta({
360
+ address: ctx.rollupState.tokenAddress,
361
+ value: "0"
362
+ }, ctx.tokenStates) : void 0,
363
+ validators: signatures.map((v) => v.signer)
364
+ };
365
+ };
366
+ /**
367
+ * Create indexed token distribution
368
+ */
369
+ const createIndexedTokenDistribution = (x) => {
370
+ return {
371
+ tokenAddress: x.tokenAddress,
372
+ txTime: x.txTime,
373
+ account: x.account.toString(),
374
+ gas: x.gas.toString(),
375
+ fee: x.fee.toString(),
376
+ slashedVault: x.slashedVault.toString(),
377
+ stake: x.stake.toString(),
378
+ revokedStake: x.revokedStake.toString(),
379
+ gasStake: x.gasStake.toString()
380
+ };
381
+ };
382
+ /**
383
+ * Format transaction before inserting to index
384
+ */
385
+ const formatTxBeforeInsert = (row) => {
386
+ const tx = { ...row };
387
+ tx.sender = tx.sender || "";
388
+ tx.receiver = tx.receiver || "";
389
+ if (!tx.tx || !tx.tx.itxJson) return tx;
390
+ const itx = tx.tx.itxJson;
391
+ tx.assets = tx.assets || [];
392
+ if (["transfer", "transfer_v2"].includes(tx.type || "") && itx.assets) tx.assets.push(...itx.assets);
393
+ else if (["transfer_v3", "stake"].includes(tx.type || "") && itx.inputs) tx.assets.push(...createSortedList(itx.inputs.map((x) => x.assets || [])));
394
+ else if ([
395
+ "revoke_stake",
396
+ "slash_stake",
397
+ "return_stake"
398
+ ].includes(tx.type || "") && itx.outputs) tx.assets.push(...createSortedList(itx.outputs.map((x) => x.assets || [])));
399
+ else if (["exchange", "exchange_v2"].includes(tx.type || "")) tx.assets.push(...itx.sender?.assets || [], ...itx.receiver?.assets || []);
400
+ else if ([
401
+ "create_asset",
402
+ "update_asset",
403
+ "acquire_asset_v2",
404
+ "mint_asset"
405
+ ].includes(tx.type || "") && itx.address) tx.assets.push(itx.address);
406
+ tx.factories = tx.factories || [];
407
+ if ([
408
+ "acquire_asset_v2",
409
+ "acquire_asset_v3",
410
+ "mint_asset",
411
+ "create_factory"
412
+ ].includes(tx.type || "") && itx.factory) tx.factories.push(itx.factory);
413
+ tx.tokens = tx.tokens || [];
414
+ if (tx.type === "transfer_v2" && itx.tokens) tx.tokens.push(...itx.tokens.map((x) => x.address));
415
+ else if (["transfer_v3", "stake"].includes(tx.type || "") && itx.inputs) tx.tokens.push(...createSortedList(itx.inputs.map((x) => (x.tokens || []).map((t) => t.address))));
416
+ else if ([
417
+ "revoke_stake",
418
+ "slash_stake",
419
+ "return_stake"
420
+ ].includes(tx.type || "") && itx.outputs) tx.tokens.push(...createSortedList(itx.outputs.map((x) => (x.tokens || []).map((t) => t.address))));
421
+ else if (tx.type === "exchange_v2") tx.tokens.push(...(itx.sender?.tokens || []).map((x) => x.address), ...(itx.receiver?.tokens || []).map((x) => x.address));
422
+ tx.accounts = tx.accounts || [];
423
+ tx.stakes = tx.stakes || [];
424
+ tx.assets = uniq(tx.assets).filter(Boolean);
425
+ tx.factories = uniq(tx.factories).filter(Boolean);
426
+ tx.tokens = uniq(tx.tokens).filter(Boolean);
427
+ tx.accounts = uniq(tx.accounts).filter(Boolean);
428
+ tx.stakes = uniq(tx.stakes).filter(Boolean);
429
+ tx.rollups = uniq(tx.rollups || []).filter(Boolean);
430
+ tx.tokenSymbols = uniqBy(tx.tokenSymbols || [], "address");
431
+ return tx;
432
+ };
433
+ /**
434
+ * Format transaction after reading from index (remove internal indexing fields)
435
+ */
436
+ const formatTxAfterRead = (tx) => {
437
+ delete tx.assets;
438
+ delete tx.factories;
439
+ delete tx.tokens;
440
+ delete tx.accounts;
441
+ delete tx.stakes;
442
+ delete tx.rollups;
443
+ delete tx.delegations;
444
+ return tx;
445
+ };
446
+ /**
447
+ * Format delegation after reading from index
448
+ */
449
+ const formatDelegationAfterRead = (delegation) => {
450
+ const opsRecord = Array.isArray(delegation.ops) ? delegation.ops[0] : delegation.ops;
451
+ return {
452
+ ...delegation,
453
+ ops: Object.keys(opsRecord).map((x) => ({
454
+ key: x,
455
+ value: opsRecord[x]
456
+ }))
457
+ };
458
+ };
459
+ /**
460
+ * Parse date time string to ISO format
461
+ */
462
+ const parseDateTime = (str) => {
463
+ if (!str) return "";
464
+ const parsed = Date.parse(str);
465
+ if (Number.isNaN(parsed)) return "";
466
+ return new Date(parsed).toISOString();
467
+ };
468
+ const PAGE_SIZE_DEFAULT = 20;
469
+ const PAGE_SIZE_MAX = 100;
470
+ /**
471
+ * Format pagination parameters with defaults
472
+ */
473
+ const formatPagination = ({ paging, defaultSortField, supportedSortFields = [] }) => {
474
+ if (!defaultSortField) throw new Error("argument defaultSortField is required");
475
+ const pagination = {
476
+ size: paging?.size ?? PAGE_SIZE_DEFAULT,
477
+ cursor: typeof paging?.cursor === "number" ? paging.cursor : Number(paging?.cursor) || 0,
478
+ order: {
479
+ field: defaultSortField,
480
+ type: "desc"
481
+ }
482
+ };
483
+ let inputOrder = paging?.order;
484
+ if (Array.isArray(inputOrder)) inputOrder = inputOrder[0];
485
+ if (inputOrder?.field) pagination.order.field = inputOrder.field;
486
+ if (supportedSortFields.length > 0 && !supportedSortFields.includes(pagination.order.field)) pagination.order.field = defaultSortField;
487
+ if (inputOrder?.type) pagination.order.type = inputOrder.type;
488
+ pagination.size = Math.min(pagination.size, PAGE_SIZE_MAX);
489
+ return pagination;
490
+ };
491
+ /**
492
+ * Format next pagination info for response
493
+ */
494
+ const formatNextPagination = (total, pagination) => {
495
+ const nextCursor = pagination.cursor + pagination.size;
496
+ if (total > nextCursor) return {
497
+ cursor: String(nextCursor),
498
+ next: true,
499
+ total
500
+ };
501
+ return {
502
+ cursor: "0",
503
+ next: false,
504
+ total
505
+ };
506
+ };
507
+ /**
508
+ * Check if a transaction changes the default token balance
509
+ */
510
+ const isDefaultTokenChanged = (tx, token) => {
511
+ const itx = tx.tx.itxJson;
512
+ if ([
513
+ "fg:t:transfer",
514
+ "fg:t:transfer_v2",
515
+ "fg:t:transfer_v3",
516
+ "fg:t:acquire_asset_v2",
517
+ "fg:t:acquire_asset_v3",
518
+ "fg:t:exchange",
519
+ "fg:t:exchange_v2",
520
+ "fg:t:deposit_token",
521
+ "fg:t:withdraw_token",
522
+ "fg:t:faucet",
523
+ "fg:t:poke",
524
+ "fg:t:setup_swap",
525
+ "fg:t:retrieve_swap",
526
+ "fg:t:stake",
527
+ "fg:t:revoke_stake"
528
+ ].includes(itx.type_url || "") === false) return false;
529
+ const ZERO = new BN(0);
530
+ const isDefaultToken = (id) => [token.address, ""].includes(id);
531
+ const isPositive = (v) => new BN(v || 0).gt(ZERO);
532
+ const isChangedByInput = (input) => isPositive(input.value) || (input.tokens?.some((x) => isDefaultToken(x.address) && isPositive(x.value)) ?? false);
533
+ switch (itx.type_url) {
534
+ case "fg:t:transfer": return isPositive(itx.value);
535
+ case "fg:t:transfer_v2": return isChangedByInput(itx);
536
+ case "fg:t:transfer_v3":
537
+ case "fg:t:acquire_asset_v3": return (itx.inputs || []).some((input) => isChangedByInput(input));
538
+ case "fg:t:acquire_asset_v2": return (tx.receipts || []).some((r) => r.changes.some((c) => isDefaultToken(c.target) && isPositive(c.value)));
539
+ case "fg:t:exchange": return isPositive(itx.sender?.value) || isPositive(itx.receiver?.value);
540
+ case "fg:t:exchange_v2": return isChangedByInput(itx.sender || {}) || isChangedByInput(itx.receiver || {});
541
+ case "fg:t:deposit_token":
542
+ case "fg:t:withdraw_token": return isPositive(itx.value);
543
+ case "fg:t:setup_swap":
544
+ case "fg:t:retrieve_swap": return isPositive(itx.value);
545
+ case "fg:t:poke": return true;
546
+ case "fg:t:faucet": return !itx.token;
547
+ case "fg:t:stake": return (itx.inputs || []).some((input) => isChangedByInput(input));
548
+ case "fg:t:revoke_stake":
549
+ case "fg:t:slash_stake":
550
+ case "fg:t:return_stake": return (itx.outputs || []).some((output) => isChangedByInput(output));
551
+ default: return false;
552
+ }
553
+ };
554
+
555
+ //#endregion
556
+ export { createIndexedAccount, createIndexedAsset, createIndexedDelegation, createIndexedFactory, createIndexedRollup, createIndexedRollupBlock, createIndexedStake, createIndexedToken, createIndexedTokenDistribution, createIndexedTokenFactory, createIndexedTransaction, formatDelegationAfterRead, formatNextPagination, formatPagination, formatTokenMeta, formatTxAfterRead, formatTxBeforeInsert, isDefaultTokenChanged, parseDateTime };
@@ -0,0 +1,29 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) {
13
+ __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ }
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+
27
+ //#endregion
28
+
29
+ exports.__toESM = __toESM;
package/lib/db.cjs ADDED
@@ -0,0 +1,64 @@
1
+ Object.defineProperty(exports, '__esModule', { value: true });
2
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
3
+ let _ocap_state = require("@ocap/state");
4
+ let _ocap_util_lib_ready = require("@ocap/util/lib/ready");
5
+
6
+ //#region src/db.ts
7
+ var BaseIndexDB = class extends _ocap_util_lib_ready.Ready {
8
+ constructor() {
9
+ super();
10
+ this.readyMarks = Object.fromEntries(_ocap_state.indexes.map((x) => [x, false]));
11
+ this.readyListenersAttached = false;
12
+ }
13
+ attachReadyListeners() {
14
+ if (this.readyListenersAttached) return;
15
+ for (const index of _ocap_state.indexes) {
16
+ if (typeof this[index] === "undefined") throw new Error(`Missing index ${index} in indexdb adapter: ${this.name}`);
17
+ this[index].onReady(() => this.markReady(index));
18
+ }
19
+ this.readyListenersAttached = true;
20
+ }
21
+ listTransactions(_params) {
22
+ throw new Error("listTransactions should be implemented in adapter");
23
+ }
24
+ listAssets(_params) {
25
+ throw new Error("listAssets should be implemented in adapter");
26
+ }
27
+ listTopAccounts(_params) {
28
+ throw new Error("listTopAccounts should be implemented in adapter");
29
+ }
30
+ listTokens(_params) {
31
+ throw new Error("listTokens should be implemented in adapter");
32
+ }
33
+ listFactories(_params) {
34
+ throw new Error("listFactories should be implemented in adapter");
35
+ }
36
+ listStakes(_params) {
37
+ throw new Error("listStakes should be implemented in adapter");
38
+ }
39
+ listDelegations(_params) {
40
+ throw new Error("listDelegations should be implemented in adapter");
41
+ }
42
+ listRollups(_params) {
43
+ throw new Error("listRollups should be implemented in adapter");
44
+ }
45
+ listRollupBlocks(_params) {
46
+ throw new Error("listRollupBlocks should be implemented in adapter");
47
+ }
48
+ listRollupValidators(_params) {
49
+ throw new Error("listRollupValidators should be implemented in adapter");
50
+ }
51
+ listTokenFactories(_params) {
52
+ throw new Error("listTokenFactories should be implemented in adapter");
53
+ }
54
+ getRelatedAddresses(_address) {
55
+ return [];
56
+ }
57
+ listBlocks() {
58
+ return [];
59
+ }
60
+ };
61
+ var db_default = BaseIndexDB;
62
+
63
+ //#endregion
64
+ exports.default = db_default;
package/lib/db.d.cts ADDED
@@ -0,0 +1,40 @@
1
+ import { IIndexDB, IIndexTable, IListAccountsResult, IListAssetsResult, IListDelegationsResult, IListFactoriesResult, IListRollupBlocksResult, IListRollupValidatorsResult, IListRollupsResult, IListStakesResult, IListTokenFactoriesResult, IListTokensResult, IListTransactionsResult, IndexTableTypeMap, Promisable, TRequestListAssets, TRequestListDelegations, TRequestListFactories, TRequestListRollupBlocks, TRequestListRollupValidators, TRequestListRollups, TRequestListStakes, TRequestListTokenFactories, TRequestListTokens, TRequestListTopAccounts, TRequestListTransactions } from "@ocap/types";
2
+ import { Ready } from "@ocap/util/lib/ready";
3
+
4
+ //#region src/db.d.ts
5
+ declare class BaseIndexDB extends Ready implements IIndexDB {
6
+ readyMarks: Record<string, boolean>;
7
+ readyListenersAttached: boolean;
8
+ name: string;
9
+ version: string;
10
+ tx: IIndexTable<IndexTableTypeMap['tx']>;
11
+ account: IIndexTable<IndexTableTypeMap['account']>;
12
+ asset: IIndexTable<IndexTableTypeMap['asset']>;
13
+ token: IIndexTable<IndexTableTypeMap['token']>;
14
+ factory: IIndexTable<IndexTableTypeMap['factory']>;
15
+ stake: IIndexTable<IndexTableTypeMap['stake']>;
16
+ delegation: IIndexTable<IndexTableTypeMap['delegation']>;
17
+ rollup: IIndexTable<IndexTableTypeMap['rollup']>;
18
+ rollupBlock: IIndexTable<IndexTableTypeMap['rollupBlock']>;
19
+ rollupValidator: IIndexTable<IndexTableTypeMap['rollupValidator']>;
20
+ tokenDistribution: IIndexTable<IndexTableTypeMap['tokenDistribution']>;
21
+ tokenFactory: IIndexTable<IndexTableTypeMap['tokenFactory']>;
22
+ [key: string]: unknown;
23
+ constructor();
24
+ attachReadyListeners(): void;
25
+ listTransactions(_params?: Partial<TRequestListTransactions>): Promisable<IListTransactionsResult>;
26
+ listAssets(_params?: Partial<TRequestListAssets>): Promisable<IListAssetsResult>;
27
+ listTopAccounts(_params?: Partial<TRequestListTopAccounts>): Promisable<IListAccountsResult>;
28
+ listTokens(_params?: Partial<TRequestListTokens>): Promisable<IListTokensResult>;
29
+ listFactories(_params?: Partial<TRequestListFactories>): Promisable<IListFactoriesResult>;
30
+ listStakes(_params?: Partial<TRequestListStakes>): Promisable<IListStakesResult>;
31
+ listDelegations(_params?: Partial<TRequestListDelegations>): Promisable<IListDelegationsResult>;
32
+ listRollups(_params?: Partial<TRequestListRollups>): Promisable<IListRollupsResult>;
33
+ listRollupBlocks(_params?: Partial<TRequestListRollupBlocks>): Promisable<IListRollupBlocksResult>;
34
+ listRollupValidators(_params?: Partial<TRequestListRollupValidators>): Promisable<IListRollupValidatorsResult>;
35
+ listTokenFactories(_params?: Partial<TRequestListTokenFactories>): Promisable<IListTokenFactoriesResult>;
36
+ getRelatedAddresses(_address: string): Promisable<string[]>;
37
+ listBlocks(): unknown[];
38
+ }
39
+ //#endregion
40
+ export { BaseIndexDB as default };