@substrate/api-sidecar 20.11.0 → 20.13.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/build/package.json +14 -14
- package/build/src/chains-config/assetHubKusamaControllers.js +1 -0
- package/build/src/chains-config/assetHubKusamaControllers.js.map +1 -1
- package/build/src/chains-config/assetHubNextWestendControllers.js +1 -0
- package/build/src/chains-config/assetHubNextWestendControllers.js.map +1 -1
- package/build/src/chains-config/assetHubPolkadotControllers.js +1 -0
- package/build/src/chains-config/assetHubPolkadotControllers.js.map +1 -1
- package/build/src/chains-config/assetHubWestendControllers.js +1 -0
- package/build/src/chains-config/assetHubWestendControllers.js.map +1 -1
- package/build/src/controllers/accounts/AccountsForeignAssetsController.d.ts +50 -0
- package/build/src/controllers/accounts/AccountsForeignAssetsController.js +110 -0
- package/build/src/controllers/accounts/AccountsForeignAssetsController.js.map +1 -0
- package/build/src/controllers/accounts/AccountsVestingInfoController.d.ts +18 -3
- package/build/src/controllers/accounts/AccountsVestingInfoController.js +24 -6
- package/build/src/controllers/accounts/AccountsVestingInfoController.js.map +1 -1
- package/build/src/controllers/accounts/index.d.ts +1 -0
- package/build/src/controllers/accounts/index.js +3 -1
- package/build/src/controllers/accounts/index.js.map +1 -1
- package/build/src/controllers/blocks/BlocksController.js +2 -0
- package/build/src/controllers/blocks/BlocksController.js.map +1 -1
- package/build/src/controllers/controllerInjection.spec.js +10 -10
- package/build/src/controllers/controllerInjection.spec.js.map +1 -1
- package/build/src/controllers/index.d.ts +2 -1
- package/build/src/controllers/index.js +1 -0
- package/build/src/controllers/index.js.map +1 -1
- package/build/src/controllers/rc/accounts/RcAccountsVestingInfoController.d.ts +12 -1
- package/build/src/controllers/rc/accounts/RcAccountsVestingInfoController.js +15 -3
- package/build/src/controllers/rc/accounts/RcAccountsVestingInfoController.js.map +1 -1
- package/build/src/controllers/rc/blocks/RcBlocksController.js +2 -0
- package/build/src/controllers/rc/blocks/RcBlocksController.js.map +1 -1
- package/build/src/services/accounts/AccountsForeignAssetsService.d.ts +45 -0
- package/build/src/services/accounts/AccountsForeignAssetsService.js +181 -0
- package/build/src/services/accounts/AccountsForeignAssetsService.js.map +1 -0
- package/build/src/services/accounts/AccountsVestingInfoService.d.ts +42 -1
- package/build/src/services/accounts/AccountsVestingInfoService.js +236 -5
- package/build/src/services/accounts/AccountsVestingInfoService.js.map +1 -1
- package/build/src/services/accounts/index.d.ts +1 -0
- package/build/src/services/accounts/index.js +1 -0
- package/build/src/services/accounts/index.js.map +1 -1
- package/build/src/services/consts.js +8 -0
- package/build/src/services/consts.js.map +1 -1
- package/build/src/services/paras/ParasInclusionService.d.ts +3 -11
- package/build/src/services/paras/ParasInclusionService.js +7 -60
- package/build/src/services/paras/ParasInclusionService.js.map +1 -1
- package/build/src/types/responses/AccountAssets.d.ts +33 -0
- package/build/src/types/responses/AccountVestingInfo.d.ts +56 -1
- package/build/src/util/relay/getRelayParentNumber.d.ts +80 -0
- package/build/src/util/relay/getRelayParentNumber.js +170 -0
- package/build/src/util/relay/getRelayParentNumber.js.map +1 -0
- package/build/src/util/relay/getRelayParentNumber.spec.d.ts +1 -0
- package/build/src/util/relay/getRelayParentNumber.spec.js +201 -0
- package/build/src/util/relay/getRelayParentNumber.spec.js.map +1 -0
- package/build/src/util/vesting/vestingCalculations.d.ts +87 -0
- package/build/src/util/vesting/vestingCalculations.js +141 -0
- package/build/src/util/vesting/vestingCalculations.js.map +1 -0
- package/build/src/util/vesting/vestingCalculations.spec.d.ts +1 -0
- package/build/src/util/vesting/vestingCalculations.spec.js +335 -0
- package/build/src/util/vesting/vestingCalculations.spec.js.map +1 -0
- package/package.json +14 -14
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ApiPromise } from '@polkadot/api';
|
|
2
|
+
import { BlockHash } from '@polkadot/types/interfaces';
|
|
3
|
+
import BN from 'bn.js';
|
|
4
|
+
/**
|
|
5
|
+
* Result of searching for a parachain block's inclusion on the relay chain.
|
|
6
|
+
*/
|
|
7
|
+
export interface IInclusionSearchResult {
|
|
8
|
+
/** The relay chain block number where the parachain block was included */
|
|
9
|
+
inclusionBlockNumber: number | null;
|
|
10
|
+
/** The relay parent number from setValidationData */
|
|
11
|
+
relayParentNumber: number;
|
|
12
|
+
/** Whether the inclusion was found */
|
|
13
|
+
found: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Extract the relay chain parent block number from a parachain block.
|
|
17
|
+
*
|
|
18
|
+
* Parachain blocks contain a `parachainSystem.setValidationData` extrinsic that
|
|
19
|
+
* includes the relay chain block number that was the parent when the parachain
|
|
20
|
+
* block was created.
|
|
21
|
+
*
|
|
22
|
+
* Note: This is the relay PARENT, not the inclusion block. For the actual
|
|
23
|
+
* inclusion block, use `getInclusionBlockNumber` or `searchForInclusionBlock`.
|
|
24
|
+
*
|
|
25
|
+
* @param api - The ApiPromise instance connected to the parachain
|
|
26
|
+
* @param blockHash - The hash of the parachain block to extract relay parent from
|
|
27
|
+
* @returns The relay chain parent block number as a BN
|
|
28
|
+
* @throws Error if the block doesn't contain setValidationData extrinsic
|
|
29
|
+
*/
|
|
30
|
+
export declare const getRelayParentNumber: (api: ApiPromise, blockHash: BlockHash) => Promise<BN>;
|
|
31
|
+
/**
|
|
32
|
+
* Extract relay parent number as a plain number (for use with search functions).
|
|
33
|
+
*
|
|
34
|
+
* @param api - The ApiPromise instance connected to the parachain
|
|
35
|
+
* @param blockHash - The hash of the parachain block
|
|
36
|
+
* @returns The relay chain parent block number as a number
|
|
37
|
+
*/
|
|
38
|
+
export declare const getRelayParentNumberRaw: (api: ApiPromise, blockHash: BlockHash) => Promise<number>;
|
|
39
|
+
/**
|
|
40
|
+
* Check if a block contains the setValidationData extrinsic.
|
|
41
|
+
*
|
|
42
|
+
* This can be used to determine if a block is from a parachain (has validation data)
|
|
43
|
+
* or a relay chain (does not have validation data).
|
|
44
|
+
*
|
|
45
|
+
* @param api - The ApiPromise instance
|
|
46
|
+
* @param blockHash - The hash of the block to check
|
|
47
|
+
* @returns true if the block contains setValidationData, false otherwise
|
|
48
|
+
*/
|
|
49
|
+
export declare const hasRelayParentData: (api: ApiPromise, blockHash: BlockHash) => Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Search relay chain blocks for the inclusion of a specific parachain block.
|
|
52
|
+
*
|
|
53
|
+
* This searches relay chain blocks starting from `relayParentNumber + 1` looking
|
|
54
|
+
* for a `paraInclusion.CandidateIncluded` event that matches the given parachain
|
|
55
|
+
* block number and paraId.
|
|
56
|
+
*
|
|
57
|
+
* @param rcApi - The ApiPromise instance connected to the relay chain
|
|
58
|
+
* @param paraId - The parachain ID (e.g., 1000 for Asset Hub)
|
|
59
|
+
* @param parachainBlockNumber - The parachain block number to search for
|
|
60
|
+
* @param relayParentNumber - The relay parent number from setValidationData
|
|
61
|
+
* @param maxDepth - Maximum number of relay blocks to search (default: 10)
|
|
62
|
+
* @returns The relay chain block number where inclusion was found, or null if not found
|
|
63
|
+
*/
|
|
64
|
+
export declare const searchForInclusionBlock: (rcApi: ApiPromise, paraId: number, parachainBlockNumber: string, relayParentNumber: number, maxDepth?: number) => Promise<number | null>;
|
|
65
|
+
/**
|
|
66
|
+
* Get the relay chain block number where a parachain block was included.
|
|
67
|
+
*
|
|
68
|
+
* This is the main function for finding the accurate relay chain block number
|
|
69
|
+
* corresponding to a parachain block. It:
|
|
70
|
+
* 1. Extracts the relayParentNumber from the parachain block's setValidationData
|
|
71
|
+
* 2. Searches relay chain blocks for the actual inclusion event
|
|
72
|
+
*
|
|
73
|
+
* @param parachainApi - The ApiPromise instance connected to the parachain
|
|
74
|
+
* @param rcApi - The ApiPromise instance connected to the relay chain
|
|
75
|
+
* @param parachainBlockHash - The hash of the parachain block
|
|
76
|
+
* @param paraId - The parachain ID (e.g., 1000 for Asset Hub)
|
|
77
|
+
* @param maxDepth - Maximum number of relay blocks to search (default: 10)
|
|
78
|
+
* @returns The inclusion search result with inclusionBlockNumber, relayParentNumber, and found status
|
|
79
|
+
*/
|
|
80
|
+
export declare const getInclusionBlockNumber: (parachainApi: ApiPromise, rcApi: ApiPromise, parachainBlockHash: BlockHash, paraId: number, maxDepth?: number) => Promise<IInclusionSearchResult>;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2017-2025 Parity Technologies (UK) Ltd.
|
|
3
|
+
// This file is part of Substrate API Sidecar.
|
|
4
|
+
//
|
|
5
|
+
// Substrate API Sidecar is free software: you can redistribute it and/or modify
|
|
6
|
+
// it under the terms of the GNU General Public License as published by
|
|
7
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
// (at your option) any later version.
|
|
9
|
+
//
|
|
10
|
+
// This program is distributed in the hope that it will be useful,
|
|
11
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
// GNU General Public License for more details.
|
|
14
|
+
//
|
|
15
|
+
// You should have received a copy of the GNU General Public License
|
|
16
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.getInclusionBlockNumber = exports.searchForInclusionBlock = exports.hasRelayParentData = exports.getRelayParentNumberRaw = exports.getRelayParentNumber = void 0;
|
|
22
|
+
const bn_js_1 = __importDefault(require("bn.js"));
|
|
23
|
+
/** Default search depth for inclusion search */
|
|
24
|
+
const DEFAULT_SEARCH_DEPTH = 10;
|
|
25
|
+
/** Batch size for parallel searches */
|
|
26
|
+
const BATCH_SIZE = 5;
|
|
27
|
+
/**
|
|
28
|
+
* Extract the relay chain parent block number from a parachain block.
|
|
29
|
+
*
|
|
30
|
+
* Parachain blocks contain a `parachainSystem.setValidationData` extrinsic that
|
|
31
|
+
* includes the relay chain block number that was the parent when the parachain
|
|
32
|
+
* block was created.
|
|
33
|
+
*
|
|
34
|
+
* Note: This is the relay PARENT, not the inclusion block. For the actual
|
|
35
|
+
* inclusion block, use `getInclusionBlockNumber` or `searchForInclusionBlock`.
|
|
36
|
+
*
|
|
37
|
+
* @param api - The ApiPromise instance connected to the parachain
|
|
38
|
+
* @param blockHash - The hash of the parachain block to extract relay parent from
|
|
39
|
+
* @returns The relay chain parent block number as a BN
|
|
40
|
+
* @throws Error if the block doesn't contain setValidationData extrinsic
|
|
41
|
+
*/
|
|
42
|
+
const getRelayParentNumber = async (api, blockHash) => {
|
|
43
|
+
const [apiAt, { block }] = await Promise.all([api.at(blockHash), api.rpc.chain.getBlock(blockHash)]);
|
|
44
|
+
const setValidationData = block.extrinsics.find((ext) => {
|
|
45
|
+
return ext.method.method.toString() === 'setValidationData';
|
|
46
|
+
});
|
|
47
|
+
if (!setValidationData) {
|
|
48
|
+
throw new Error('Block does not contain setValidationData extrinsic. Cannot determine relay parent number.');
|
|
49
|
+
}
|
|
50
|
+
const callArgs = apiAt.registry.createType('Call', setValidationData.method);
|
|
51
|
+
const { relayParentNumber } = callArgs.toJSON().args.data.validationData;
|
|
52
|
+
return new bn_js_1.default(relayParentNumber);
|
|
53
|
+
};
|
|
54
|
+
exports.getRelayParentNumber = getRelayParentNumber;
|
|
55
|
+
/**
|
|
56
|
+
* Extract relay parent number as a plain number (for use with search functions).
|
|
57
|
+
*
|
|
58
|
+
* @param api - The ApiPromise instance connected to the parachain
|
|
59
|
+
* @param blockHash - The hash of the parachain block
|
|
60
|
+
* @returns The relay chain parent block number as a number
|
|
61
|
+
*/
|
|
62
|
+
const getRelayParentNumberRaw = async (api, blockHash) => {
|
|
63
|
+
const [apiAt, { block }] = await Promise.all([api.at(blockHash), api.rpc.chain.getBlock(blockHash)]);
|
|
64
|
+
const setValidationData = block.extrinsics.find((ext) => {
|
|
65
|
+
return ext.method.method.toString() === 'setValidationData';
|
|
66
|
+
});
|
|
67
|
+
if (!setValidationData) {
|
|
68
|
+
throw new Error('Block does not contain setValidationData extrinsic. Cannot determine relay parent number.');
|
|
69
|
+
}
|
|
70
|
+
const callArgs = apiAt.registry.createType('Call', setValidationData.method);
|
|
71
|
+
const { relayParentNumber } = callArgs.toJSON().args.data.validationData;
|
|
72
|
+
return relayParentNumber;
|
|
73
|
+
};
|
|
74
|
+
exports.getRelayParentNumberRaw = getRelayParentNumberRaw;
|
|
75
|
+
/**
|
|
76
|
+
* Check if a block contains the setValidationData extrinsic.
|
|
77
|
+
*
|
|
78
|
+
* This can be used to determine if a block is from a parachain (has validation data)
|
|
79
|
+
* or a relay chain (does not have validation data).
|
|
80
|
+
*
|
|
81
|
+
* @param api - The ApiPromise instance
|
|
82
|
+
* @param blockHash - The hash of the block to check
|
|
83
|
+
* @returns true if the block contains setValidationData, false otherwise
|
|
84
|
+
*/
|
|
85
|
+
const hasRelayParentData = async (api, blockHash) => {
|
|
86
|
+
const { block } = await api.rpc.chain.getBlock(blockHash);
|
|
87
|
+
return block.extrinsics.some((ext) => ext.method.method.toString() === 'setValidationData');
|
|
88
|
+
};
|
|
89
|
+
exports.hasRelayParentData = hasRelayParentData;
|
|
90
|
+
/**
|
|
91
|
+
* Search relay chain blocks for the inclusion of a specific parachain block.
|
|
92
|
+
*
|
|
93
|
+
* This searches relay chain blocks starting from `relayParentNumber + 1` looking
|
|
94
|
+
* for a `paraInclusion.CandidateIncluded` event that matches the given parachain
|
|
95
|
+
* block number and paraId.
|
|
96
|
+
*
|
|
97
|
+
* @param rcApi - The ApiPromise instance connected to the relay chain
|
|
98
|
+
* @param paraId - The parachain ID (e.g., 1000 for Asset Hub)
|
|
99
|
+
* @param parachainBlockNumber - The parachain block number to search for
|
|
100
|
+
* @param relayParentNumber - The relay parent number from setValidationData
|
|
101
|
+
* @param maxDepth - Maximum number of relay blocks to search (default: 10)
|
|
102
|
+
* @returns The relay chain block number where inclusion was found, or null if not found
|
|
103
|
+
*/
|
|
104
|
+
const searchForInclusionBlock = async (rcApi, paraId, parachainBlockNumber, relayParentNumber, maxDepth = DEFAULT_SEARCH_DEPTH) => {
|
|
105
|
+
// Search in batches for optimal performance
|
|
106
|
+
// Most inclusions happen within 2-4 blocks of relayParentNumber
|
|
107
|
+
for (let offset = 0; offset < maxDepth; offset += BATCH_SIZE) {
|
|
108
|
+
const batchSize = Math.min(BATCH_SIZE, maxDepth - offset);
|
|
109
|
+
const searchBlocks = Array.from({ length: batchSize }, (_, i) => relayParentNumber + offset + i + 1);
|
|
110
|
+
const searchPromises = searchBlocks.map(async (blockNum) => {
|
|
111
|
+
try {
|
|
112
|
+
const relayBlockHash = await rcApi.rpc.chain.getBlockHash(blockNum);
|
|
113
|
+
const rcApiAt = await rcApi.at(relayBlockHash);
|
|
114
|
+
const events = await rcApiAt.query.system.events();
|
|
115
|
+
const foundInclusion = events.find((record) => {
|
|
116
|
+
if (record.event.section === 'paraInclusion' && record.event.method === 'CandidateIncluded') {
|
|
117
|
+
const eventData = record.event.data[0].toJSON();
|
|
118
|
+
if (eventData.descriptor.paraId === paraId) {
|
|
119
|
+
const header = rcApiAt.registry.createType('Header', record.event.data[1]);
|
|
120
|
+
return header.number.toString() === parachainBlockNumber;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
});
|
|
125
|
+
return foundInclusion ? blockNum : null;
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
const results = await Promise.all(searchPromises);
|
|
132
|
+
const found = results.find((result) => result !== null);
|
|
133
|
+
if (found) {
|
|
134
|
+
return found; // Early termination when found in this batch
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return null; // Not found within search depth
|
|
138
|
+
};
|
|
139
|
+
exports.searchForInclusionBlock = searchForInclusionBlock;
|
|
140
|
+
/**
|
|
141
|
+
* Get the relay chain block number where a parachain block was included.
|
|
142
|
+
*
|
|
143
|
+
* This is the main function for finding the accurate relay chain block number
|
|
144
|
+
* corresponding to a parachain block. It:
|
|
145
|
+
* 1. Extracts the relayParentNumber from the parachain block's setValidationData
|
|
146
|
+
* 2. Searches relay chain blocks for the actual inclusion event
|
|
147
|
+
*
|
|
148
|
+
* @param parachainApi - The ApiPromise instance connected to the parachain
|
|
149
|
+
* @param rcApi - The ApiPromise instance connected to the relay chain
|
|
150
|
+
* @param parachainBlockHash - The hash of the parachain block
|
|
151
|
+
* @param paraId - The parachain ID (e.g., 1000 for Asset Hub)
|
|
152
|
+
* @param maxDepth - Maximum number of relay blocks to search (default: 10)
|
|
153
|
+
* @returns The inclusion search result with inclusionBlockNumber, relayParentNumber, and found status
|
|
154
|
+
*/
|
|
155
|
+
const getInclusionBlockNumber = async (parachainApi, rcApi, parachainBlockHash, paraId, maxDepth = DEFAULT_SEARCH_DEPTH) => {
|
|
156
|
+
// Get the parachain block header to get the block number
|
|
157
|
+
const header = await parachainApi.rpc.chain.getHeader(parachainBlockHash);
|
|
158
|
+
const parachainBlockNumber = header.number.unwrap().toString();
|
|
159
|
+
// Extract relay parent number from the parachain block
|
|
160
|
+
const relayParentNumber = await (0, exports.getRelayParentNumberRaw)(parachainApi, parachainBlockHash);
|
|
161
|
+
// Search for the actual inclusion block
|
|
162
|
+
const inclusionBlockNumber = await (0, exports.searchForInclusionBlock)(rcApi, paraId, parachainBlockNumber, relayParentNumber, maxDepth);
|
|
163
|
+
return {
|
|
164
|
+
inclusionBlockNumber,
|
|
165
|
+
relayParentNumber,
|
|
166
|
+
found: inclusionBlockNumber !== null,
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
exports.getInclusionBlockNumber = getInclusionBlockNumber;
|
|
170
|
+
//# sourceMappingURL=getRelayParentNumber.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getRelayParentNumber.js","sourceRoot":"","sources":["../../../../src/util/relay/getRelayParentNumber.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2017-2025 Parity Technologies (UK) Ltd.
|
|
3
|
+
// This file is part of Substrate API Sidecar.
|
|
4
|
+
//
|
|
5
|
+
// Substrate API Sidecar is free software: you can redistribute it and/or modify
|
|
6
|
+
// it under the terms of the GNU General Public License as published by
|
|
7
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
// (at your option) any later version.
|
|
9
|
+
//
|
|
10
|
+
// This program is distributed in the hope that it will be useful,
|
|
11
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
// GNU General Public License for more details.
|
|
14
|
+
//
|
|
15
|
+
// You should have received a copy of the GNU General Public License
|
|
16
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
const bn_js_1 = __importDefault(require("bn.js"));
|
|
22
|
+
const registries_1 = require("../../test-helpers/registries");
|
|
23
|
+
const getRelayParentNumber_1 = require("./getRelayParentNumber");
|
|
24
|
+
const mockBlockHash = registries_1.polkadotRegistry.createType('BlockHash', '0x7b713de604a99857f6c25eacc115a4f28d2611a23d9ddff99ab0e4f1c17a8578');
|
|
25
|
+
const mockRelayParentNumber = 28500000;
|
|
26
|
+
/**
|
|
27
|
+
* Create a mock extrinsic that simulates setValidationData
|
|
28
|
+
*/
|
|
29
|
+
const createMockSetValidationDataExtrinsic = () => ({
|
|
30
|
+
method: {
|
|
31
|
+
method: {
|
|
32
|
+
toString: () => 'setValidationData',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* Create a mock extrinsic that is NOT setValidationData
|
|
38
|
+
*/
|
|
39
|
+
const createMockOtherExtrinsic = (methodName) => ({
|
|
40
|
+
method: {
|
|
41
|
+
method: {
|
|
42
|
+
toString: () => methodName,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* Create a mock registry.createType that returns the expected structure
|
|
48
|
+
*/
|
|
49
|
+
const createMockCreateType = (relayParentNumber) => {
|
|
50
|
+
return (_typeName, _data) => ({
|
|
51
|
+
toJSON: () => ({
|
|
52
|
+
args: {
|
|
53
|
+
data: {
|
|
54
|
+
validationData: {
|
|
55
|
+
relayParentNumber,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
describe('getRelayParentNumber', () => {
|
|
63
|
+
describe('getRelayParentNumber', () => {
|
|
64
|
+
it('should extract relay parent number from a parachain block', async () => {
|
|
65
|
+
const mockApiAt = {
|
|
66
|
+
registry: {
|
|
67
|
+
createType: createMockCreateType(mockRelayParentNumber),
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
const mockAt = jest.fn().mockResolvedValue(mockApiAt);
|
|
71
|
+
const mockGetBlock = jest.fn().mockResolvedValue({
|
|
72
|
+
block: {
|
|
73
|
+
extrinsics: [
|
|
74
|
+
createMockOtherExtrinsic('timestamp'),
|
|
75
|
+
createMockSetValidationDataExtrinsic(),
|
|
76
|
+
createMockOtherExtrinsic('transfer'),
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
const mockApi = {
|
|
81
|
+
at: mockAt,
|
|
82
|
+
rpc: {
|
|
83
|
+
chain: {
|
|
84
|
+
getBlock: mockGetBlock,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
const result = await (0, getRelayParentNumber_1.getRelayParentNumber)(mockApi, mockBlockHash);
|
|
89
|
+
expect(result).toBeInstanceOf(bn_js_1.default);
|
|
90
|
+
expect(result.toNumber()).toBe(mockRelayParentNumber);
|
|
91
|
+
expect(mockAt).toHaveBeenCalledWith(mockBlockHash);
|
|
92
|
+
expect(mockGetBlock).toHaveBeenCalledWith(mockBlockHash);
|
|
93
|
+
});
|
|
94
|
+
it('should throw error when setValidationData extrinsic is not found', async () => {
|
|
95
|
+
const mockApi = {
|
|
96
|
+
at: jest.fn().mockResolvedValue({}),
|
|
97
|
+
rpc: {
|
|
98
|
+
chain: {
|
|
99
|
+
getBlock: jest.fn().mockResolvedValue({
|
|
100
|
+
block: {
|
|
101
|
+
extrinsics: [createMockOtherExtrinsic('timestamp'), createMockOtherExtrinsic('transfer')],
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
await expect((0, getRelayParentNumber_1.getRelayParentNumber)(mockApi, mockBlockHash)).rejects.toThrow('Block does not contain setValidationData extrinsic. Cannot determine relay parent number.');
|
|
108
|
+
});
|
|
109
|
+
it('should handle block with only setValidationData extrinsic', async () => {
|
|
110
|
+
const mockApiAt = {
|
|
111
|
+
registry: {
|
|
112
|
+
createType: createMockCreateType(12345678),
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
const mockApi = {
|
|
116
|
+
at: jest.fn().mockResolvedValue(mockApiAt),
|
|
117
|
+
rpc: {
|
|
118
|
+
chain: {
|
|
119
|
+
getBlock: jest.fn().mockResolvedValue({
|
|
120
|
+
block: {
|
|
121
|
+
extrinsics: [createMockSetValidationDataExtrinsic()],
|
|
122
|
+
},
|
|
123
|
+
}),
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
const result = await (0, getRelayParentNumber_1.getRelayParentNumber)(mockApi, mockBlockHash);
|
|
128
|
+
expect(result.toNumber()).toBe(12345678);
|
|
129
|
+
});
|
|
130
|
+
it('should handle large relay parent numbers', async () => {
|
|
131
|
+
const largeBlockNumber = 999999999;
|
|
132
|
+
const mockApiAt = {
|
|
133
|
+
registry: {
|
|
134
|
+
createType: createMockCreateType(largeBlockNumber),
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
const mockApi = {
|
|
138
|
+
at: jest.fn().mockResolvedValue(mockApiAt),
|
|
139
|
+
rpc: {
|
|
140
|
+
chain: {
|
|
141
|
+
getBlock: jest.fn().mockResolvedValue({
|
|
142
|
+
block: {
|
|
143
|
+
extrinsics: [createMockSetValidationDataExtrinsic()],
|
|
144
|
+
},
|
|
145
|
+
}),
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
const result = await (0, getRelayParentNumber_1.getRelayParentNumber)(mockApi, mockBlockHash);
|
|
150
|
+
expect(result.toNumber()).toBe(largeBlockNumber);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
describe('hasRelayParentData', () => {
|
|
154
|
+
it('should return true when block contains setValidationData', async () => {
|
|
155
|
+
const mockApi = {
|
|
156
|
+
rpc: {
|
|
157
|
+
chain: {
|
|
158
|
+
getBlock: jest.fn().mockResolvedValue({
|
|
159
|
+
block: {
|
|
160
|
+
extrinsics: [createMockOtherExtrinsic('timestamp'), createMockSetValidationDataExtrinsic()],
|
|
161
|
+
},
|
|
162
|
+
}),
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
const result = await (0, getRelayParentNumber_1.hasRelayParentData)(mockApi, mockBlockHash);
|
|
167
|
+
expect(result).toBe(true);
|
|
168
|
+
});
|
|
169
|
+
it('should return false when block does not contain setValidationData', async () => {
|
|
170
|
+
const mockApi = {
|
|
171
|
+
rpc: {
|
|
172
|
+
chain: {
|
|
173
|
+
getBlock: jest.fn().mockResolvedValue({
|
|
174
|
+
block: {
|
|
175
|
+
extrinsics: [createMockOtherExtrinsic('timestamp'), createMockOtherExtrinsic('transfer')],
|
|
176
|
+
},
|
|
177
|
+
}),
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
const result = await (0, getRelayParentNumber_1.hasRelayParentData)(mockApi, mockBlockHash);
|
|
182
|
+
expect(result).toBe(false);
|
|
183
|
+
});
|
|
184
|
+
it('should return false for empty extrinsics array', async () => {
|
|
185
|
+
const mockApi = {
|
|
186
|
+
rpc: {
|
|
187
|
+
chain: {
|
|
188
|
+
getBlock: jest.fn().mockResolvedValue({
|
|
189
|
+
block: {
|
|
190
|
+
extrinsics: [],
|
|
191
|
+
},
|
|
192
|
+
}),
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
const result = await (0, getRelayParentNumber_1.hasRelayParentData)(mockApi, mockBlockHash);
|
|
197
|
+
expect(result).toBe(false);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
//# sourceMappingURL=getRelayParentNumber.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getRelayParentNumber.spec.js","sourceRoot":"","sources":["../../../../src/util/relay/getRelayParentNumber.spec.ts"],"names":[],"mappings":";AAAA,oDAAoD;AACpD,8CAA8C;AAC9C,EAAE;AACF,gFAAgF;AAChF,uEAAuE;AACvE,oEAAoE;AACpE,sCAAsC;AACtC,EAAE;AACF,kEAAkE;AAClE,iEAAiE;AACjE,gEAAgE;AAChE,+CAA+C;AAC/C,EAAE;AACF,oEAAoE;AACpE,wEAAwE;;;;;AAGxE,kDAAuB;AAEvB,8DAAiE;AACjE,iEAAkF;AAElF,MAAM,aAAa,GAAG,6BAAgB,CAAC,UAAU,CAChD,WAAW,EACX,oEAAoE,CACpE,CAAC;AAEF,MAAM,qBAAqB,GAAG,QAAQ,CAAC;AAEvC;;GAEG;AACH,MAAM,oCAAoC,GAAG,GAAG,EAAE,CAAC,CAAC;IACnD,MAAM,EAAE;QACP,MAAM,EAAE;YACP,QAAQ,EAAE,GAAG,EAAE,CAAC,mBAAmB;SACnC;KACD;CACD,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,wBAAwB,GAAG,CAAC,UAAkB,EAAE,EAAE,CAAC,CAAC;IACzD,MAAM,EAAE;QACP,MAAM,EAAE;YACP,QAAQ,EAAE,GAAG,EAAE,CAAC,UAAU;SAC1B;KACD;CACD,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,oBAAoB,GAAG,CAAC,iBAAyB,EAAE,EAAE;IAC1D,OAAO,CAAC,SAAiB,EAAE,KAAc,EAAE,EAAE,CAAC,CAAC;QAC9C,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACd,IAAI,EAAE;gBACL,IAAI,EAAE;oBACL,cAAc,EAAE;wBACf,iBAAiB;qBACjB;iBACD;aACD;SACD,CAAC;KACF,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACrC,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;YAC1E,MAAM,SAAS,GAAG;gBACjB,QAAQ,EAAE;oBACT,UAAU,EAAE,oBAAoB,CAAC,qBAAqB,CAAC;iBACvD;aACD,CAAC;YAEF,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YACtD,MAAM,YAAY,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;gBAChD,KAAK,EAAE;oBACN,UAAU,EAAE;wBACX,wBAAwB,CAAC,WAAW,CAAC;wBACrC,oCAAoC,EAAE;wBACtC,wBAAwB,CAAC,UAAU,CAAC;qBACpC;iBACD;aACD,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG;gBACf,EAAE,EAAE,MAAM;gBACV,GAAG,EAAE;oBACJ,KAAK,EAAE;wBACN,QAAQ,EAAE,YAAY;qBACtB;iBACD;aACwB,CAAC;YAE3B,MAAM,MAAM,GAAG,MAAM,IAAA,2CAAoB,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAElE,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,eAAE,CAAC,CAAC;YAClC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;YACtD,MAAM,CAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;YACnD,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;YACjF,MAAM,OAAO,GAAG;gBACf,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACnC,GAAG,EAAE;oBACJ,KAAK,EAAE;wBACN,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;4BACrC,KAAK,EAAE;gCACN,UAAU,EAAE,CAAC,wBAAwB,CAAC,WAAW,CAAC,EAAE,wBAAwB,CAAC,UAAU,CAAC,CAAC;6BACzF;yBACD,CAAC;qBACF;iBACD;aACwB,CAAC;YAE3B,MAAM,MAAM,CAAC,IAAA,2CAAoB,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACzE,2FAA2F,CAC3F,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;YAC1E,MAAM,SAAS,GAAG;gBACjB,QAAQ,EAAE;oBACT,UAAU,EAAE,oBAAoB,CAAC,QAAQ,CAAC;iBAC1C;aACD,CAAC;YAEF,MAAM,OAAO,GAAG;gBACf,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;gBAC1C,GAAG,EAAE;oBACJ,KAAK,EAAE;wBACN,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;4BACrC,KAAK,EAAE;gCACN,UAAU,EAAE,CAAC,oCAAoC,EAAE,CAAC;6BACpD;yBACD,CAAC;qBACF;iBACD;aACwB,CAAC;YAE3B,MAAM,MAAM,GAAG,MAAM,IAAA,2CAAoB,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAElE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACzD,MAAM,gBAAgB,GAAG,SAAS,CAAC;YACnC,MAAM,SAAS,GAAG;gBACjB,QAAQ,EAAE;oBACT,UAAU,EAAE,oBAAoB,CAAC,gBAAgB,CAAC;iBAClD;aACD,CAAC;YAEF,MAAM,OAAO,GAAG;gBACf,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;gBAC1C,GAAG,EAAE;oBACJ,KAAK,EAAE;wBACN,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;4BACrC,KAAK,EAAE;gCACN,UAAU,EAAE,CAAC,oCAAoC,EAAE,CAAC;6BACpD;yBACD,CAAC;qBACF;iBACD;aACwB,CAAC;YAE3B,MAAM,MAAM,GAAG,MAAM,IAAA,2CAAoB,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAElE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QACnC,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACzE,MAAM,OAAO,GAAG;gBACf,GAAG,EAAE;oBACJ,KAAK,EAAE;wBACN,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;4BACrC,KAAK,EAAE;gCACN,UAAU,EAAE,CAAC,wBAAwB,CAAC,WAAW,CAAC,EAAE,oCAAoC,EAAE,CAAC;6BAC3F;yBACD,CAAC;qBACF;iBACD;aACwB,CAAC;YAE3B,MAAM,MAAM,GAAG,MAAM,IAAA,yCAAkB,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAEhE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;YAClF,MAAM,OAAO,GAAG;gBACf,GAAG,EAAE;oBACJ,KAAK,EAAE;wBACN,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;4BACrC,KAAK,EAAE;gCACN,UAAU,EAAE,CAAC,wBAAwB,CAAC,WAAW,CAAC,EAAE,wBAAwB,CAAC,UAAU,CAAC,CAAC;6BACzF;yBACD,CAAC;qBACF;iBACD;aACwB,CAAC;YAE3B,MAAM,MAAM,GAAG,MAAM,IAAA,yCAAkB,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAEhE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,OAAO,GAAG;gBACf,GAAG,EAAE;oBACJ,KAAK,EAAE;wBACN,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;4BACrC,KAAK,EAAE;gCACN,UAAU,EAAE,EAAE;6BACd;yBACD,CAAC;qBACF;iBACD;aACwB,CAAC;YAE3B,MAAM,MAAM,GAAG,MAAM,IAAA,yCAAkB,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAEhE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import BN from 'bn.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents a vesting schedule with the essential fields needed for calculations.
|
|
4
|
+
*/
|
|
5
|
+
export interface IVestingSchedule {
|
|
6
|
+
/** Total amount of tokens locked at the start of vesting */
|
|
7
|
+
locked: BN;
|
|
8
|
+
/** Number of tokens that unlock per block */
|
|
9
|
+
perBlock: BN;
|
|
10
|
+
/** Block number when vesting/unlocking begins */
|
|
11
|
+
startingBlock: BN;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Result of vesting calculation for a single schedule.
|
|
15
|
+
*/
|
|
16
|
+
export interface IVestingCalculationResult {
|
|
17
|
+
/** Amount that has vested based on time elapsed */
|
|
18
|
+
vested: BN;
|
|
19
|
+
/** Block number when vesting will be complete */
|
|
20
|
+
endBlock: BN;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Calculate the amount that has vested for a single vesting schedule.
|
|
24
|
+
*
|
|
25
|
+
* The calculation follows the formula used in the vesting pallet:
|
|
26
|
+
* - If currentBlock <= startingBlock: nothing is vested yet
|
|
27
|
+
* - Otherwise: vested = min(blocksPassed * perBlock, locked)
|
|
28
|
+
*
|
|
29
|
+
* Note: This is the theoretical vested amount based on time. The actual
|
|
30
|
+
* claimable amount depends on the on-chain lock state (see calculateVestedClaimable).
|
|
31
|
+
*
|
|
32
|
+
* @param currentBlock - The block number to calculate vested amount at
|
|
33
|
+
* @param schedule - The vesting schedule containing locked, perBlock, and startingBlock
|
|
34
|
+
* @returns The amount that has vested at the given block
|
|
35
|
+
*/
|
|
36
|
+
export declare const calculateVested: (currentBlock: BN, schedule: IVestingSchedule) => BN;
|
|
37
|
+
/**
|
|
38
|
+
* Calculate the block number when a vesting schedule will be fully vested.
|
|
39
|
+
*
|
|
40
|
+
* The end block is calculated as: startingBlock + (locked / perBlock)
|
|
41
|
+
*
|
|
42
|
+
* @param schedule - The vesting schedule
|
|
43
|
+
* @returns The block number when vesting completes
|
|
44
|
+
*/
|
|
45
|
+
export declare const calculateEndBlock: (schedule: IVestingSchedule) => BN;
|
|
46
|
+
/**
|
|
47
|
+
* Calculate the total vested amount across multiple vesting schedules.
|
|
48
|
+
*
|
|
49
|
+
* @param currentBlock - The block number to calculate vested amounts at
|
|
50
|
+
* @param schedules - Array of vesting schedules
|
|
51
|
+
* @returns The total amount that has vested across all schedules (vestedBalance)
|
|
52
|
+
*/
|
|
53
|
+
export declare const calculateTotalVested: (currentBlock: BN, schedules: IVestingSchedule[]) => BN;
|
|
54
|
+
/**
|
|
55
|
+
* Calculate the total locked amount across multiple vesting schedules.
|
|
56
|
+
*
|
|
57
|
+
* @param schedules - Array of vesting schedules
|
|
58
|
+
* @returns The total locked amount across all schedules (vestingTotal)
|
|
59
|
+
*/
|
|
60
|
+
export declare const calculateVestingTotal: (schedules: IVestingSchedule[]) => BN;
|
|
61
|
+
/**
|
|
62
|
+
* Calculate the actual claimable amount that can be unlocked.
|
|
63
|
+
*
|
|
64
|
+
* This follows the polkadot-js formula:
|
|
65
|
+
* vestedClaimable = vestingLocked - (vestingTotal - vestedBalance)
|
|
66
|
+
*
|
|
67
|
+
* Where:
|
|
68
|
+
* - vestingLocked: actual on-chain lock amount from balances.locks
|
|
69
|
+
* - vestingTotal: sum of all locked amounts from vesting schedules
|
|
70
|
+
* - vestedBalance: sum of all vested amounts from vesting schedules
|
|
71
|
+
*
|
|
72
|
+
* The difference accounts for previous claims that reduced the on-chain lock.
|
|
73
|
+
*
|
|
74
|
+
* @param vestingLocked - The actual on-chain vesting lock amount
|
|
75
|
+
* @param vestingTotal - Total locked across all vesting schedules
|
|
76
|
+
* @param vestedBalance - Total vested across all vesting schedules
|
|
77
|
+
* @returns The amount that can actually be claimed right now
|
|
78
|
+
*/
|
|
79
|
+
export declare const calculateVestedClaimable: (vestingLocked: BN, vestingTotal: BN, vestedBalance: BN) => BN;
|
|
80
|
+
/**
|
|
81
|
+
* Calculate vested amounts for multiple schedules, returning per-schedule results.
|
|
82
|
+
*
|
|
83
|
+
* @param currentBlock - The block number to calculate vested amounts at
|
|
84
|
+
* @param schedules - Array of vesting schedules
|
|
85
|
+
* @returns Array of calculation results with vested amount and end block for each schedule
|
|
86
|
+
*/
|
|
87
|
+
export declare const calculateVestingDetails: (currentBlock: BN, schedules: IVestingSchedule[]) => IVestingCalculationResult[];
|