@ocap/resolver 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/api.d.mts +24 -0
- package/esm/api.mjs +53 -0
- package/esm/hooks.d.mts +153 -0
- package/esm/hooks.mjs +267 -0
- package/esm/index.d.mts +201 -0
- package/esm/index.mjs +1327 -0
- package/esm/migration-chain.d.mts +52 -0
- package/esm/migration-chain.mjs +97 -0
- package/esm/package.mjs +5 -0
- package/esm/token-cache.d.mts +20 -0
- package/esm/token-cache.mjs +26 -0
- package/esm/token-distribution.d.mts +166 -0
- package/esm/token-distribution.mjs +241 -0
- package/esm/token-flow.d.mts +139 -0
- package/esm/token-flow.mjs +330 -0
- package/esm/types.d.mts +115 -0
- package/esm/types.mjs +1 -0
- package/lib/_virtual/rolldown_runtime.cjs +29 -0
- package/lib/api.cjs +54 -0
- package/lib/api.d.cts +24 -0
- package/lib/hooks.cjs +274 -0
- package/lib/hooks.d.cts +153 -0
- package/lib/index.cjs +1343 -0
- package/lib/index.d.cts +201 -0
- package/lib/migration-chain.cjs +99 -0
- package/lib/migration-chain.d.cts +52 -0
- package/lib/package.cjs +11 -0
- package/lib/token-cache.cjs +27 -0
- package/lib/token-cache.d.cts +20 -0
- package/lib/token-distribution.cjs +243 -0
- package/lib/token-distribution.d.cts +166 -0
- package/lib/token-flow.cjs +336 -0
- package/lib/token-flow.d.cts +139 -0
- package/lib/types.cjs +0 -0
- package/lib/types.d.cts +115 -0
- package/package.json +49 -21
- package/lib/api.js +0 -71
- package/lib/hooks.js +0 -339
- package/lib/index.js +0 -1486
- package/lib/migration-chain.js +0 -144
- package/lib/token-cache.js +0 -40
- package/lib/token-distribution.js +0 -358
- package/lib/token-flow.js +0 -445
package/lib/types.d.cts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { Address, BN, DirectionMap, Hash, IAccountState, IAddressArgs, IAny, IAssetFactoryState, IAssetState, IBalanceTable, IChainConfig, IChainConfig as IChainConfig$1, IChainState, IDelegateState, IEvidenceState, IExecutedContext, IForeignToken, IGetAccountStateArgs, IGetAccountTokensArgs, IIndexDB, IIndexDB as IIndexDB$1, IIndexTable, IIndexTable as IIndexTable$1, IListAccountsResult, IListAssetsResult, IListDelegationsResult, IListFactoriesResult, IListRollupBlocksResult, IListRollupValidatorsResult, IListRollupsResult, IListStakesResult, IListTokenFactoriesResult, IListTokensResult, IListTransactionsResult, IOperationContext, IPipelineLogger, IPipelineLogger as IPipelineLogger$1, IResolver, IResolverAccountState, IResolverChainInfo, IResolverContext, IResolverContext as IResolverContext$1, IResolverFactoryState, IResolverForgeStats, IResolverListAccountsResult, IResolverListAssetsResult, IResolverListDelegationsResult, IResolverListFactoriesResult, IResolverListRollupBlocksResult, IResolverListRollupValidatorsResult, IResolverListRollupsResult, IResolverListStakesResult, IResolverListTokenFactoriesResult, IResolverListTokensResult, IResolverListTransactionsResult, IResolverNetInfo, IResolverNodeInfo, IResolverPaging, IResolverPaging as IResolverPaging$1, IResolverRollupState, IResolverStakeState, IResolverTransaction, IResolverTxItxJson, IResolverValidatorsInfo, IRollupBlock, IRollupState, IRollupValidator, IStakeState, IStateContext, IStateDB, IStateDB as IStateDB$1, IStateTable, IStateTable as IStateTable$1, ITokenConfig, ITokenFactoryState, ITokenFlowsResult, ITokenInfo, ITokenInfo as ITokenInfo$1, ITokenMetadata, ITokenState, ITransactionConfig, ITxGasConfig, ITxStakeConfig, ITxState, IVaultsConfig, IndexTableTypeMap, Promisable, TAccountFilter, TAccountToken, TAddressFilter, TAssetFilter, TDelegationFilter, TFactoryFilter, TIndexedAccountState, TIndexedAssetState, TIndexedDelegationState, TIndexedFactoryState, TIndexedRollupBlock, TIndexedRollupState, TIndexedRollupValidator, TIndexedStakeState, TIndexedTokenFactoryState, TIndexedTokenState, TIndexedTokenState as TIndexedTokenState$1, TIndexedTransaction, TPage, TPageInfo, TPageOrder, TRangeFilter, TReceiptChange, TRequestEstimateGas, TRequestGetEvidenceState, TRequestGetRollupBlock, TRequestGetTokenDistribution, TRequestGetTx, TRequestListAssetTransactions, TRequestListAssets, TRequestListDelegations, TRequestListFactories, TRequestListRollupBlocks, TRequestListRollupValidators, TRequestListRollups, TRequestListStakes, TRequestListTokenFactories, TRequestListTokenFlows, TRequestListTokens, TRequestListTopAccounts, TRequestListTransactions, TRequestSearch, TRequestVerifyAccountRisk, TRollupFilter, TSearchResult, TStakeFilter, TTimeFilter, TTokenDistribution, TTokenFactoryFilter, TTokenFilter, TTokenMeta, TTransactionReceipt, TTxFilter, TTypeFilter, TValidatorFilter, TValidityFilter, TVerifyAccountRiskResult, TokenBalanceMap, ValidityMap } from "@ocap/types";
|
|
2
|
+
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Flexible StateDB type that supports dynamic table access
|
|
7
|
+
*/
|
|
8
|
+
type FlexibleStateDB = IStateDB$1 & {
|
|
9
|
+
[key: string]: IStateTable$1<unknown>;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Flexible IndexDB type that supports dynamic table access
|
|
13
|
+
*/
|
|
14
|
+
type FlexibleIndexDB = IIndexDB$1 & {
|
|
15
|
+
[key: string]: IIndexTable$1<unknown> | ((...args: unknown[]) => Promise<unknown>);
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Data object for encoded data fields (typeUrl + value)
|
|
19
|
+
*/
|
|
20
|
+
interface IDataObject {
|
|
21
|
+
type_url?: string;
|
|
22
|
+
typeUrl?: string;
|
|
23
|
+
value?: string;
|
|
24
|
+
type?: string;
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Delegation operation
|
|
29
|
+
*/
|
|
30
|
+
interface IDelegationOp {
|
|
31
|
+
key: string;
|
|
32
|
+
value: {
|
|
33
|
+
limit?: {
|
|
34
|
+
tokens?: ITokenInfo$1[];
|
|
35
|
+
};
|
|
36
|
+
[key: string]: unknown;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Chunk iterator for paginated data fetching
|
|
41
|
+
*/
|
|
42
|
+
interface IChunkIterator<T> {
|
|
43
|
+
next: () => Promise<T[]>;
|
|
44
|
+
done: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Parameters for list chunks operation
|
|
48
|
+
*/
|
|
49
|
+
interface IListChunksParams {
|
|
50
|
+
total: number;
|
|
51
|
+
concurrency?: number;
|
|
52
|
+
chunkSize?: number;
|
|
53
|
+
pageSize?: number;
|
|
54
|
+
timeKey: string;
|
|
55
|
+
dataKey: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Generic paginated result
|
|
59
|
+
*/
|
|
60
|
+
interface IPaginatedResult<T> {
|
|
61
|
+
paging?: IResolverPaging$1;
|
|
62
|
+
[key: string]: T[] | IResolverPaging$1 | unknown;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Filter interface for risk verification
|
|
66
|
+
*/
|
|
67
|
+
interface IFilter {
|
|
68
|
+
getTrustedAccountConfig?: (address: string) => Promise<ITrustedAccountConfig | null>;
|
|
69
|
+
[key: string]: any;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Trusted account configuration
|
|
73
|
+
*/
|
|
74
|
+
interface ITrustedAccountConfig {
|
|
75
|
+
tolerance?: string | number;
|
|
76
|
+
[key: string]: unknown;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Resolver constructor parameters
|
|
80
|
+
*/
|
|
81
|
+
interface IResolverParams {
|
|
82
|
+
statedb: IStateDB$1;
|
|
83
|
+
indexdb: IIndexDB$1;
|
|
84
|
+
config: IChainConfig$1;
|
|
85
|
+
filter?: IFilter;
|
|
86
|
+
validateTokenConfig?: boolean;
|
|
87
|
+
logger?: IPipelineLogger$1;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get state parameters
|
|
91
|
+
*/
|
|
92
|
+
interface IGetStateParams {
|
|
93
|
+
table: string;
|
|
94
|
+
id: string;
|
|
95
|
+
dataKey?: string | string[] | null;
|
|
96
|
+
extraParams?: Record<string, unknown>;
|
|
97
|
+
onRead?: (state: any) => any;
|
|
98
|
+
expandContext?: boolean;
|
|
99
|
+
ctx?: IResolverContext$1;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Token cache interface
|
|
103
|
+
*/
|
|
104
|
+
interface ITokenCache {
|
|
105
|
+
get: (address: string) => Promise<TIndexedTokenState$1 | null>;
|
|
106
|
+
set: (address: string, token: TIndexedTokenState$1) => void;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Migration chain interface
|
|
110
|
+
*/
|
|
111
|
+
interface IMigrationChain {
|
|
112
|
+
findAddressAtTime: (address: string, time: Date) => string;
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
export { type Address, type BN, type DirectionMap, FlexibleIndexDB, FlexibleStateDB, type Hash, type IAccountState, type IAddressArgs, type IAny, type IAssetFactoryState, type IAssetState, type IBalanceTable, type IChainConfig, type IChainState, IChunkIterator, IDataObject, type IDelegateState, IDelegationOp, type IEvidenceState, type IExecutedContext, IFilter, type IForeignToken, type IGetAccountStateArgs, type IGetAccountTokensArgs, IGetStateParams, type IIndexDB, type IIndexTable, type IListAccountsResult, type IListAssetsResult, IListChunksParams, type IListDelegationsResult, type IListFactoriesResult, type IListRollupBlocksResult, type IListRollupValidatorsResult, type IListRollupsResult, type IListStakesResult, type IListTokenFactoriesResult, type IListTokensResult, type IListTransactionsResult, IMigrationChain, type IOperationContext, IPaginatedResult, type IPipelineLogger, type IResolver, type IResolverAccountState, type IResolverChainInfo, type IResolverContext, type IResolverFactoryState, type IResolverForgeStats, type IResolverListAccountsResult, type IResolverListAssetsResult, type IResolverListDelegationsResult, type IResolverListFactoriesResult, type IResolverListRollupBlocksResult, type IResolverListRollupValidatorsResult, type IResolverListRollupsResult, type IResolverListStakesResult, type IResolverListTokenFactoriesResult, type IResolverListTokensResult, type IResolverListTransactionsResult, type IResolverNetInfo, type IResolverNodeInfo, type IResolverPaging, IResolverParams, type IResolverRollupState, type IResolverStakeState, type IResolverTransaction, type IResolverTxItxJson, type IResolverValidatorsInfo, type IRollupBlock, type IRollupState, type IRollupValidator, type IStakeState, type IStateContext, type IStateDB, type IStateTable, ITokenCache, type ITokenConfig, type ITokenFactoryState, type ITokenFlowsResult, type ITokenInfo, type ITokenMetadata, type ITokenState, type ITransactionConfig, ITrustedAccountConfig, type ITxGasConfig, type ITxStakeConfig, type ITxState, type IVaultsConfig, type IndexTableTypeMap, type Promisable, type TAccountFilter, type TAccountToken, type TAddressFilter, type TAssetFilter, type TDelegationFilter, type TFactoryFilter, type TIndexedAccountState, type TIndexedAssetState, type TIndexedDelegationState, type TIndexedFactoryState, type TIndexedRollupBlock, type TIndexedRollupState, type TIndexedRollupValidator, type TIndexedStakeState, type TIndexedTokenFactoryState, type TIndexedTokenState, type TIndexedTransaction, type TPage, type TPageInfo, type TPageOrder, type TRangeFilter, type TReceiptChange, type TRequestEstimateGas, type TRequestGetEvidenceState, type TRequestGetRollupBlock, type TRequestGetTokenDistribution, type TRequestGetTx, type TRequestListAssetTransactions, type TRequestListAssets, type TRequestListDelegations, type TRequestListFactories, type TRequestListRollupBlocks, type TRequestListRollupValidators, type TRequestListRollups, type TRequestListStakes, type TRequestListTokenFactories, type TRequestListTokenFlows, type TRequestListTokens, type TRequestListTopAccounts, type TRequestListTransactions, type TRequestSearch, type TRequestVerifyAccountRisk, type TRollupFilter, type TSearchResult, type TStakeFilter, type TTimeFilter, type TTokenDistribution, type TTokenFactoryFilter, type TTokenFilter, type TTokenMeta, type TTransactionReceipt, type TTxFilter, type TTypeFilter, type TValidatorFilter, type TValidityFilter, type TVerifyAccountRiskResult, type TokenBalanceMap, type ValidityMap };
|
package/package.json
CHANGED
|
@@ -3,13 +3,36 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.29.0",
|
|
7
7
|
"description": "GraphQL resolver built upon ocap statedb and GQL layer",
|
|
8
|
-
"
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "./lib/index.cjs",
|
|
10
|
+
"module": "./esm/index.mjs",
|
|
11
|
+
"types": "./esm/index.d.mts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./esm/index.d.mts",
|
|
15
|
+
"import": "./esm/index.mjs",
|
|
16
|
+
"default": "./lib/index.cjs"
|
|
17
|
+
},
|
|
18
|
+
"./lib/*.js": {
|
|
19
|
+
"types": "./esm/*.d.mts",
|
|
20
|
+
"import": "./esm/*.mjs",
|
|
21
|
+
"default": "./lib/*.cjs"
|
|
22
|
+
},
|
|
23
|
+
"./lib/*": {
|
|
24
|
+
"types": "./esm/*.d.mts",
|
|
25
|
+
"import": "./esm/*.mjs",
|
|
26
|
+
"default": "./lib/*.cjs"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
9
29
|
"files": [
|
|
10
|
-
"lib"
|
|
30
|
+
"lib",
|
|
31
|
+
"esm"
|
|
11
32
|
],
|
|
12
33
|
"scripts": {
|
|
34
|
+
"build": "tsdown",
|
|
35
|
+
"prebuild": "rm -rf lib esm",
|
|
13
36
|
"lint": "biome check",
|
|
14
37
|
"lint:fix": "biome check --write",
|
|
15
38
|
"test": "bun test",
|
|
@@ -19,27 +42,32 @@
|
|
|
19
42
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
43
|
"license": "MIT",
|
|
21
44
|
"devDependencies": {
|
|
22
|
-
"@arcblock/jwt": "1.
|
|
23
|
-
"@ocap/indexdb-memory": "1.
|
|
24
|
-
"@ocap/statedb-memory": "1.
|
|
45
|
+
"@arcblock/jwt": "1.29.0",
|
|
46
|
+
"@ocap/indexdb-memory": "1.29.0",
|
|
47
|
+
"@ocap/statedb-memory": "1.29.0",
|
|
48
|
+
"@types/express": "^4.17.23",
|
|
49
|
+
"@types/lodash": "^4.17.16",
|
|
50
|
+
"@types/node": "^20.10.0",
|
|
51
|
+
"tsdown": "^0.18.4"
|
|
25
52
|
},
|
|
26
53
|
"dependencies": {
|
|
27
|
-
"@arcblock/did": "1.
|
|
28
|
-
"@arcblock/did-ext": "1.
|
|
29
|
-
"@arcblock/did-util": "1.
|
|
54
|
+
"@arcblock/did": "1.29.0",
|
|
55
|
+
"@arcblock/did-ext": "1.29.0",
|
|
56
|
+
"@arcblock/did-util": "1.29.0",
|
|
30
57
|
"@arcblock/nft-display": "^3.2.3",
|
|
31
|
-
"@arcblock/validator": "1.
|
|
32
|
-
"@ocap/config": "1.
|
|
33
|
-
"@ocap/indexdb": "1.
|
|
34
|
-
"@ocap/mcrypto": "1.
|
|
35
|
-
"@ocap/message": "1.
|
|
36
|
-
"@ocap/state": "1.
|
|
37
|
-
"@ocap/tx-protocols": "1.
|
|
38
|
-
"@ocap/
|
|
39
|
-
"@ocap/
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
58
|
+
"@arcblock/validator": "1.29.0",
|
|
59
|
+
"@ocap/config": "1.29.0",
|
|
60
|
+
"@ocap/indexdb": "1.29.0",
|
|
61
|
+
"@ocap/mcrypto": "1.29.0",
|
|
62
|
+
"@ocap/message": "1.29.0",
|
|
63
|
+
"@ocap/state": "1.29.0",
|
|
64
|
+
"@ocap/tx-protocols": "1.29.0",
|
|
65
|
+
"@ocap/types": "1.29.0",
|
|
66
|
+
"@ocap/util": "1.29.0",
|
|
67
|
+
"@ocap/wallet": "1.29.0",
|
|
68
|
+
"debug": "^4.4.3",
|
|
69
|
+
"express": "^4.22.1",
|
|
70
|
+
"lodash": "^4.17.23",
|
|
43
71
|
"queue": "^6"
|
|
44
72
|
}
|
|
45
73
|
}
|
package/lib/api.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
const { Router } = require('express');
|
|
2
|
-
const { getNftBGColorFromDid, getSvg } = require('@arcblock/nft-display');
|
|
3
|
-
|
|
4
|
-
function createAPIHandler({ resolver }) {
|
|
5
|
-
const router = Router();
|
|
6
|
-
|
|
7
|
-
router.get('/token/display', async (req, res) => {
|
|
8
|
-
const { address } = req.query;
|
|
9
|
-
if (!address) {
|
|
10
|
-
return res.status(400).json({ error: 'address is required' });
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const token = await resolver.getTokenState({ address });
|
|
14
|
-
|
|
15
|
-
if (!token) {
|
|
16
|
-
return res.status(400).json({ error: 'token not found' });
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
let iconUri = '';
|
|
20
|
-
|
|
21
|
-
if (token.icon) {
|
|
22
|
-
let iconWidth = 40;
|
|
23
|
-
let iconHeight = 40;
|
|
24
|
-
|
|
25
|
-
// Extract viewBox dimensions to ensure the icon displays properly in nft-display
|
|
26
|
-
const viewBoxMatch = token.icon.match(/viewBox\s*=\s*["']([^"']+)["']/i);
|
|
27
|
-
if (viewBoxMatch) {
|
|
28
|
-
const viewBoxValues = viewBoxMatch[1].split(/\s+/);
|
|
29
|
-
if (viewBoxValues.length >= 4) {
|
|
30
|
-
iconWidth = +viewBoxValues[2] || iconWidth;
|
|
31
|
-
iconHeight = +viewBoxValues[3] || iconHeight;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const fixedSvg = token.icon.replace(/<svg([^>]*)>/, `<svg$1 width="${iconWidth}" height="${iconHeight}">`);
|
|
36
|
-
|
|
37
|
-
iconUri = `data:image/svg+xml;base64,${Buffer.from(fixedSvg).toString('base64')}`;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const svg = getSvg({
|
|
41
|
-
color: getNftBGColorFromDid(address),
|
|
42
|
-
|
|
43
|
-
did: address,
|
|
44
|
-
variant: 'app-passport',
|
|
45
|
-
verifiable: true,
|
|
46
|
-
chain: 'arcblock',
|
|
47
|
-
|
|
48
|
-
header: {
|
|
49
|
-
icon: iconUri,
|
|
50
|
-
name: token.symbol,
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
issuer: {
|
|
54
|
-
name: token.symbol,
|
|
55
|
-
icon: iconUri,
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
extra: {
|
|
59
|
-
key: 'Name',
|
|
60
|
-
value: token.name,
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
res.setHeader('Content-Type', 'image/svg+xml');
|
|
65
|
-
res.send(svg);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
return router;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
module.exports = { createAPIHandler };
|
package/lib/hooks.js
DELETED
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
// Purpose of these hooks: update indexdb to speed up subsequent queries
|
|
2
|
-
// RULE: do not try to update statedb in these hooks
|
|
3
|
-
|
|
4
|
-
const merge = require('lodash/merge');
|
|
5
|
-
const pick = require('lodash/pick');
|
|
6
|
-
const { BN } = require('@ocap/util');
|
|
7
|
-
const { toStakeAddress } = require('@arcblock/did-util');
|
|
8
|
-
|
|
9
|
-
const debug = require('debug')(require('../package.json').name);
|
|
10
|
-
|
|
11
|
-
const onCreateRollup = (rollup, _ctx, indexdb) => {
|
|
12
|
-
rollup.seedValidators.forEach(async (x) => {
|
|
13
|
-
const { pk, address, endpoint } = x;
|
|
14
|
-
try {
|
|
15
|
-
const account = await indexdb.account.get(address);
|
|
16
|
-
|
|
17
|
-
await indexdb.rollupValidator.insert({
|
|
18
|
-
rollup: rollup.address,
|
|
19
|
-
|
|
20
|
-
pk,
|
|
21
|
-
address,
|
|
22
|
-
endpoint,
|
|
23
|
-
moniker: account.moniker,
|
|
24
|
-
|
|
25
|
-
joinTime: rollup.genesisTime,
|
|
26
|
-
leaveTime: '',
|
|
27
|
-
genesisTime: account.genesisTime,
|
|
28
|
-
renaissanceTime: account.renaissanceTime,
|
|
29
|
-
|
|
30
|
-
totalStake: '0',
|
|
31
|
-
revokedStake: '0',
|
|
32
|
-
availableStake: '0',
|
|
33
|
-
|
|
34
|
-
totalGain: '0',
|
|
35
|
-
|
|
36
|
-
proposedBlockCount: 0,
|
|
37
|
-
verifiedBlockCount: 0,
|
|
38
|
-
|
|
39
|
-
latestBlockHeight: 0,
|
|
40
|
-
latestBlockHash: '',
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
debug('create rollup validator', address);
|
|
44
|
-
} catch (err) {
|
|
45
|
-
console.error('create rollup validator error', err);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const ensureRollupValidator = async (address, rollupAddress, ctx, indexdb, upsert = true) => {
|
|
51
|
-
const doc = await indexdb.rollupValidator.get(address);
|
|
52
|
-
if (doc) {
|
|
53
|
-
doc.rollup = rollupAddress;
|
|
54
|
-
|
|
55
|
-
if (!doc.pk || !doc.endpoint) {
|
|
56
|
-
const rollup = await indexdb.rollup.get(rollupAddress);
|
|
57
|
-
const validator = rollup.validators.find((v) => v.address === address);
|
|
58
|
-
doc.pk = validator.pk;
|
|
59
|
-
doc.endpoint = validator.endpoint;
|
|
60
|
-
return indexdb.rollupValidator.update(address, doc);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return doc;
|
|
64
|
-
}
|
|
65
|
-
if (upsert === false) {
|
|
66
|
-
throw new Error('Rollup validator not found and upsert is disabled');
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const stakeAddress = toStakeAddress(address, rollupAddress);
|
|
70
|
-
const [rollup, stake, account] = await Promise.all([
|
|
71
|
-
indexdb.rollup.get(rollupAddress),
|
|
72
|
-
indexdb.stake.get(stakeAddress),
|
|
73
|
-
indexdb.account.get(address),
|
|
74
|
-
]);
|
|
75
|
-
|
|
76
|
-
const token = stake.tokens.find((t) => t.address === rollup.tokenAddress);
|
|
77
|
-
const validator = rollup.validators.find((v) => v.address === address);
|
|
78
|
-
|
|
79
|
-
debug('ensure rollup validator', { txType: ctx.txType, address, rollupAddress, validator, token });
|
|
80
|
-
|
|
81
|
-
return indexdb.rollupValidator.insert({
|
|
82
|
-
rollup: rollup.address,
|
|
83
|
-
|
|
84
|
-
address,
|
|
85
|
-
pk: validator ? validator.pk : '',
|
|
86
|
-
endpoint: validator ? validator.endpoint : '',
|
|
87
|
-
moniker: account.moniker,
|
|
88
|
-
|
|
89
|
-
joinTime: '',
|
|
90
|
-
leaveTime: '',
|
|
91
|
-
genesisTime: ctx.txState.time,
|
|
92
|
-
renaissanceTime: ctx.txState.time,
|
|
93
|
-
|
|
94
|
-
totalStake: token.balance,
|
|
95
|
-
revokedStake: '0',
|
|
96
|
-
availableStake: '0',
|
|
97
|
-
|
|
98
|
-
totalGain: '0',
|
|
99
|
-
|
|
100
|
-
proposedBlockCount: 0,
|
|
101
|
-
verifiedBlockCount: 0,
|
|
102
|
-
|
|
103
|
-
latestBlockHeight: 0,
|
|
104
|
-
latestBlockHash: '',
|
|
105
|
-
});
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const onCreateRollupBlock = (block, ctx, indexdb) => {
|
|
109
|
-
const { validators, proposer } = block;
|
|
110
|
-
const { rollupState, txStates } = ctx;
|
|
111
|
-
|
|
112
|
-
validators.forEach(async (address) => {
|
|
113
|
-
try {
|
|
114
|
-
const doc = await ensureRollupValidator(address, rollupState.address, ctx, indexdb);
|
|
115
|
-
|
|
116
|
-
doc.rollup = rollupState.address;
|
|
117
|
-
doc.renaissanceTime = block.genesisTime;
|
|
118
|
-
doc.verifiedBlockCount += 1;
|
|
119
|
-
if (address === proposer) {
|
|
120
|
-
doc.latestBlockHeight = block.height;
|
|
121
|
-
doc.latestBlockHash = block.hash;
|
|
122
|
-
doc.proposedBlockCount += 1;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
await indexdb.rollupValidator.update(address, doc);
|
|
126
|
-
debug('update rollup validator on new block', address);
|
|
127
|
-
} catch (err) {
|
|
128
|
-
console.error('update rollup validator error', err);
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
// Withdraw tx.actualFee needs to be reindexed
|
|
133
|
-
if (Array.isArray(txStates)) {
|
|
134
|
-
txStates
|
|
135
|
-
.filter((x) => x.type === 'withdraw_token_v2')
|
|
136
|
-
.forEach(async (x) => {
|
|
137
|
-
try {
|
|
138
|
-
const doc = await indexdb.tx.get(x.hash);
|
|
139
|
-
const updates = merge(doc, pick(x, ['tx.itxJson.actualFee']));
|
|
140
|
-
await indexdb.tx.update(x.hash, updates);
|
|
141
|
-
debug('update tx on new block', x.hash);
|
|
142
|
-
} catch (err) {
|
|
143
|
-
console.error('update tx on new block error', err);
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
const updateRollupStats = async (address, value, key, indexdb) => {
|
|
150
|
-
try {
|
|
151
|
-
const doc = await indexdb.rollup.get(address);
|
|
152
|
-
doc[key] = new BN(doc[key] || '0').add(new BN(value)).toString(10);
|
|
153
|
-
await indexdb.rollup.update(address, doc);
|
|
154
|
-
debug('update rollup', address);
|
|
155
|
-
} catch (err) {
|
|
156
|
-
console.error('update rollup error', err);
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const onDepositTokenV2 = async (tx, ctx, indexdb) => {
|
|
161
|
-
const { signatures } = tx.tx;
|
|
162
|
-
const { rollupState } = ctx;
|
|
163
|
-
signatures.forEach(async ({ signer: address }) => {
|
|
164
|
-
try {
|
|
165
|
-
const doc = await ensureRollupValidator(address, rollupState.address, ctx, indexdb);
|
|
166
|
-
doc.renaissanceTime = tx.time;
|
|
167
|
-
|
|
168
|
-
await indexdb.rollupValidator.update(address, doc);
|
|
169
|
-
debug('update rollup validator on deposit', address);
|
|
170
|
-
} catch (err) {
|
|
171
|
-
console.error('update rollup validator error', err);
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
// totalDepositAmount should include txFee
|
|
176
|
-
const amount = new BN(tx.tx.itxJson.token.value).add(new BN(tx.tx.itxJson.actualFee));
|
|
177
|
-
await updateRollupStats(ctx.rollupState.address, amount.toString(), 'totalDepositAmount', indexdb);
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
const onClaimBlockReward = (tx, ctx, indexdb) => {
|
|
181
|
-
const { rollupState, blockState } = ctx;
|
|
182
|
-
const { signatures } = blockState;
|
|
183
|
-
// TODO: delegation is not supported here
|
|
184
|
-
return Promise.all(
|
|
185
|
-
signatures.map(async ({ signer }) => {
|
|
186
|
-
try {
|
|
187
|
-
const doc = await ensureRollupValidator(signer, rollupState.address, ctx, indexdb);
|
|
188
|
-
|
|
189
|
-
const receipt = tx.receipts.find((x) => x.address === signer);
|
|
190
|
-
if (receipt) {
|
|
191
|
-
const change = receipt.changes.find(
|
|
192
|
-
(x) => x.target === rollupState.tokenAddress && new BN(x.value).isNeg() === false
|
|
193
|
-
);
|
|
194
|
-
doc.totalGain = new BN(doc.totalGain).add(new BN(change.value).abs()).toString(10);
|
|
195
|
-
await indexdb.rollupValidator.update(signer, doc);
|
|
196
|
-
debug('update rollup validator on claim reward', signer);
|
|
197
|
-
}
|
|
198
|
-
} catch (err) {
|
|
199
|
-
console.error('update rollup validator on claim reward error', err);
|
|
200
|
-
}
|
|
201
|
-
})
|
|
202
|
-
);
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
const onJoinRollup = async (tx, ctx, indexdb) => {
|
|
206
|
-
try {
|
|
207
|
-
const address = tx.tx.from;
|
|
208
|
-
const doc = await ensureRollupValidator(address, tx.tx.itxJson.rollup, ctx, indexdb);
|
|
209
|
-
|
|
210
|
-
doc.endpoint = tx.tx.itxJson.endpoint;
|
|
211
|
-
doc.joinTime = tx.time;
|
|
212
|
-
doc.renaissanceTime = tx.time;
|
|
213
|
-
doc.leaveTime = '';
|
|
214
|
-
|
|
215
|
-
await indexdb.rollupValidator.update(address, doc);
|
|
216
|
-
debug('join rollup validator', address);
|
|
217
|
-
} catch (err) {
|
|
218
|
-
console.error('join rollup validator error', err);
|
|
219
|
-
}
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
const onLeaveRollup = async (tx, ctx, indexdb) => {
|
|
223
|
-
try {
|
|
224
|
-
const address = tx.tx.from;
|
|
225
|
-
const doc = await ensureRollupValidator(address, tx.tx.itxJson.rollup, ctx, indexdb);
|
|
226
|
-
|
|
227
|
-
doc.leaveTime = tx.time;
|
|
228
|
-
doc.renaissanceTime = tx.time;
|
|
229
|
-
doc.rollup = '';
|
|
230
|
-
|
|
231
|
-
await indexdb.rollupValidator.update(address, doc);
|
|
232
|
-
debug('leave rollup validator', address);
|
|
233
|
-
} catch (err) {
|
|
234
|
-
console.error('leave rollup validator error', err);
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
const onStake = async (tx, ctx, indexdb) => {
|
|
239
|
-
try {
|
|
240
|
-
const rollup = await indexdb.rollup.get(tx.tx.itxJson.receiver);
|
|
241
|
-
if (!rollup) {
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const address = tx.tx.from;
|
|
246
|
-
if (rollup.validators.find((x) => x.address === address) === undefined) {
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const stakeAddress = toStakeAddress(address, rollup.address);
|
|
251
|
-
const doc = await ensureRollupValidator(address, rollup.address, ctx, indexdb);
|
|
252
|
-
|
|
253
|
-
const receipt = ctx.txState.receipts.find((x) => x.address === stakeAddress);
|
|
254
|
-
const change = receipt.changes.find((x) => x.target === rollup.tokenAddress);
|
|
255
|
-
doc.totalStake = new BN(doc.totalStake).add(new BN(change.value).abs()).toString(10);
|
|
256
|
-
doc.renaissanceTime = tx.time;
|
|
257
|
-
|
|
258
|
-
await indexdb.rollupValidator.update(address, doc);
|
|
259
|
-
debug('stake rollup validator', address);
|
|
260
|
-
} catch (err) {
|
|
261
|
-
console.error('stake rollup validator error', err);
|
|
262
|
-
}
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
const onClaimStake = async (tx, ctx, indexdb) => {
|
|
266
|
-
try {
|
|
267
|
-
const stake = await indexdb.stake.get(tx.tx.itxJson.address);
|
|
268
|
-
const rollup = await indexdb.rollup.get(stake.receiver);
|
|
269
|
-
if (!rollup) {
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
const address = tx.tx.from;
|
|
274
|
-
const doc = await ensureRollupValidator(address, rollup.address, ctx, indexdb, false);
|
|
275
|
-
const receipt = ctx.txState.receipts.find((x) => x.address === stake.address);
|
|
276
|
-
const change = receipt.changes.find((x) => x.target === rollup.tokenAddress);
|
|
277
|
-
|
|
278
|
-
doc.renaissanceTime = tx.time;
|
|
279
|
-
doc.totalStake = new BN(doc.totalStake).sub(new BN(change.value).abs()).toString(10);
|
|
280
|
-
doc.revokedStake = new BN(doc.revokedStake).add(new BN(change.value).abs()).toString(10);
|
|
281
|
-
|
|
282
|
-
await indexdb.rollupValidator.update(address, doc);
|
|
283
|
-
debug('claim-stake rollup validator', address);
|
|
284
|
-
} catch (err) {
|
|
285
|
-
console.error('claim-stake rollup validator error', err);
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
const onAccountMigrate = async (_tx, resolver) => {
|
|
290
|
-
try {
|
|
291
|
-
await resolver.buildMigrationChain();
|
|
292
|
-
} catch (e) {
|
|
293
|
-
console.error('build migration chain error', e);
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
const onUpdateToken = (tokenDoc, _ctx, _indexdb, resolver) => {
|
|
298
|
-
if (resolver.tokenCache) {
|
|
299
|
-
resolver.tokenCache.set(tokenDoc.address, tokenDoc);
|
|
300
|
-
}
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
const onCreateTx = async (tx, ctx, resolver) => {
|
|
304
|
-
// Always update distribution even if tx failed cause there might be had gas
|
|
305
|
-
try {
|
|
306
|
-
await resolver.tokenDistribution.updateByTx(tx, ctx);
|
|
307
|
-
} catch (e) {
|
|
308
|
-
resolver.logger.error('Failed to update token distribution', { error: e, tx, ctx });
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (tx.code !== 'OK') {
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
const { indexdb } = resolver;
|
|
316
|
-
|
|
317
|
-
switch (tx.tx.itxJson.type_url) {
|
|
318
|
-
case 'fg:t:stake':
|
|
319
|
-
return onStake(tx, ctx, indexdb);
|
|
320
|
-
case 'fg:t:claim_stake':
|
|
321
|
-
return onClaimStake(tx, ctx, indexdb);
|
|
322
|
-
case 'fg:t:join_rollup':
|
|
323
|
-
return onJoinRollup(tx, ctx, indexdb);
|
|
324
|
-
case 'fg:t:leave_rollup':
|
|
325
|
-
return onLeaveRollup(tx, ctx, indexdb);
|
|
326
|
-
case 'fg:t:deposit_token_v2':
|
|
327
|
-
return onDepositTokenV2(tx, ctx, indexdb);
|
|
328
|
-
case 'fg:t:claim_block_reward':
|
|
329
|
-
return onClaimBlockReward(tx, ctx, indexdb);
|
|
330
|
-
case 'fg:t:withdraw_token_v2':
|
|
331
|
-
// totalWithdrawAmount does not include txFee
|
|
332
|
-
return updateRollupStats(ctx.rollupState.address, tx.tx.itxJson.token.value, 'totalWithdrawAmount', indexdb);
|
|
333
|
-
case 'fg:t:account_migrate':
|
|
334
|
-
return onAccountMigrate(tx, resolver);
|
|
335
|
-
default:
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
module.exports = { onCreateRollup, onCreateTx, onCreateRollupBlock, onUpdateToken };
|