@suzaku-network/suzaku-cli 1.0.2
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/LICENSE +96 -0
- package/README.md +1080 -0
- package/bin/cli.js +3 -0
- package/defaults/.env.anvil +4 -0
- package/defaults/.env.dexalot +7 -0
- package/defaults/.env.fuji +4 -0
- package/defaults/.env.kiteai +2 -0
- package/defaults/.env.mainnet +4 -0
- package/defaults/.env.template +10 -0
- package/dist/abis/AccessControl.d.ts +176 -0
- package/dist/abis/AccessControl.js +230 -0
- package/dist/abis/AccessControl.js.map +1 -0
- package/dist/abis/BalancerValidatorManager.d.ts +1121 -0
- package/dist/abis/BalancerValidatorManager.js +1469 -0
- package/dist/abis/BalancerValidatorManager.js.map +1 -0
- package/dist/abis/DefaultCollateral.d.ts +620 -0
- package/dist/abis/DefaultCollateral.js +811 -0
- package/dist/abis/DefaultCollateral.js.map +1 -0
- package/dist/abis/ERC20.d.ts +635 -0
- package/dist/abis/ERC20.js +831 -0
- package/dist/abis/ERC20.js.map +1 -0
- package/dist/abis/IWarpMessenger.d.ts +104 -0
- package/dist/abis/IWarpMessenger.js +139 -0
- package/dist/abis/IWarpMessenger.js.map +1 -0
- package/dist/abis/KiteStakingManager.d.ts +1459 -0
- package/dist/abis/KiteStakingManager.js +1886 -0
- package/dist/abis/KiteStakingManager.js.map +1 -0
- package/dist/abis/L1Middleware.d.ts +1712 -0
- package/dist/abis/L1Middleware.js +2242 -0
- package/dist/abis/L1Middleware.js.map +1 -0
- package/dist/abis/L1Registry.d.ts +415 -0
- package/dist/abis/L1Registry.js +544 -0
- package/dist/abis/L1Registry.js.map +1 -0
- package/dist/abis/L1RestakeDelegator.d.ts +865 -0
- package/dist/abis/L1RestakeDelegator.js +1118 -0
- package/dist/abis/L1RestakeDelegator.js.map +1 -0
- package/dist/abis/OperatorL1OptInService.d.ts +288 -0
- package/dist/abis/OperatorL1OptInService.js +374 -0
- package/dist/abis/OperatorL1OptInService.js.map +1 -0
- package/dist/abis/OperatorRegistry.d.ts +125 -0
- package/dist/abis/OperatorRegistry.js +166 -0
- package/dist/abis/OperatorRegistry.js.map +1 -0
- package/dist/abis/OperatorVaultOptInService.d.ts +288 -0
- package/dist/abis/OperatorVaultOptInService.js +374 -0
- package/dist/abis/OperatorVaultOptInService.js.map +1 -0
- package/dist/abis/Ownable.d.ts +59 -0
- package/dist/abis/Ownable.js +79 -0
- package/dist/abis/Ownable.js.map +1 -0
- package/dist/abis/PoASecurityModule.d.ts +225 -0
- package/dist/abis/PoASecurityModule.js +299 -0
- package/dist/abis/PoASecurityModule.js.map +1 -0
- package/dist/abis/RewardsNativeToken.d.ts +1334 -0
- package/dist/abis/RewardsNativeToken.js +1749 -0
- package/dist/abis/RewardsNativeToken.js.map +1 -0
- package/dist/abis/StakingVault.d.ts +2913 -0
- package/dist/abis/StakingVault.js +3780 -0
- package/dist/abis/StakingVault.js.map +1 -0
- package/dist/abis/StakingVaultOperations.d.ts +980 -0
- package/dist/abis/StakingVaultOperations.js +1270 -0
- package/dist/abis/StakingVaultOperations.js.map +1 -0
- package/dist/abis/UptimeTracker.d.ts +300 -0
- package/dist/abis/UptimeTracker.js +397 -0
- package/dist/abis/UptimeTracker.js.map +1 -0
- package/dist/abis/ValidatorManager.d.ts +842 -0
- package/dist/abis/ValidatorManager.js +1101 -0
- package/dist/abis/ValidatorManager.js.map +1 -0
- package/dist/abis/VaultFactory.d.ts +288 -0
- package/dist/abis/VaultFactory.js +378 -0
- package/dist/abis/VaultFactory.js.map +1 -0
- package/dist/abis/VaultManager.d.ts +519 -0
- package/dist/abis/VaultManager.js +678 -0
- package/dist/abis/VaultManager.js.map +1 -0
- package/dist/abis/VaultTokenized.d.ts +1626 -0
- package/dist/abis/VaultTokenized.js +2114 -0
- package/dist/abis/VaultTokenized.js.map +1 -0
- package/dist/abis/abi-selectors.json +700 -0
- package/dist/abis/index.d.ts +18356 -0
- package/dist/abis/index.js +58 -0
- package/dist/abis/index.js.map +1 -0
- package/dist/accessControl.d.ts +15 -0
- package/dist/accessControl.js +36 -0
- package/dist/accessControl.js.map +1 -0
- package/dist/balancer.d.ts +25 -0
- package/dist/balancer.js +42 -0
- package/dist/balancer.js.map +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +3183 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.mjs +31343 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/client.d.ts +34 -0
- package/dist/client.js +76 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +63 -0
- package/dist/config.js.map +1 -0
- package/dist/delegator.d.ts +4 -0
- package/dist/delegator.js +16 -0
- package/dist/delegator.js.map +1 -0
- package/dist/index.d.mts +19770 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +27451 -0
- package/dist/index.mjs.map +1 -0
- package/dist/keyStore.d.ts +3 -0
- package/dist/keyStore.js +105 -0
- package/dist/keyStore.js.map +1 -0
- package/dist/kiteStaking.d.ts +91 -0
- package/dist/kiteStaking.js +731 -0
- package/dist/kiteStaking.js.map +1 -0
- package/dist/l1.d.ts +5 -0
- package/dist/l1.js +22 -0
- package/dist/l1.js.map +1 -0
- package/dist/lib/autoCompletion.d.ts +3 -0
- package/dist/lib/autoCompletion.js +55 -0
- package/dist/lib/autoCompletion.js.map +1 -0
- package/dist/lib/cChainUtils.d.ts +42 -0
- package/dist/lib/cChainUtils.js +271 -0
- package/dist/lib/cChainUtils.js.map +1 -0
- package/dist/lib/castUtils.d.ts +18 -0
- package/dist/lib/castUtils.js +81 -0
- package/dist/lib/castUtils.js.map +1 -0
- package/dist/lib/chainList.d.ts +5 -0
- package/dist/lib/chainList.js +86 -0
- package/dist/lib/chainList.js.map +1 -0
- package/dist/lib/cliParser.d.ts +27 -0
- package/dist/lib/cliParser.js +167 -0
- package/dist/lib/cliParser.js.map +1 -0
- package/dist/lib/commandUtils.d.ts +13 -0
- package/dist/lib/commandUtils.js +38 -0
- package/dist/lib/commandUtils.js.map +1 -0
- package/dist/lib/coreWalletUtils.d.ts +3 -0
- package/dist/lib/coreWalletUtils.js +74 -0
- package/dist/lib/coreWalletUtils.js.map +1 -0
- package/dist/lib/justification.d.ts +90 -0
- package/dist/lib/justification.js +577 -0
- package/dist/lib/justification.js.map +1 -0
- package/dist/lib/ledgerUtils.d.ts +4 -0
- package/dist/lib/ledgerUtils.js +258 -0
- package/dist/lib/ledgerUtils.js.map +1 -0
- package/dist/lib/logger.d.ts +46 -0
- package/dist/lib/logger.js +226 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/pChainUtils.d.ts +128 -0
- package/dist/lib/pChainUtils.js +436 -0
- package/dist/lib/pChainUtils.js.map +1 -0
- package/dist/lib/pass.d.ts +81 -0
- package/dist/lib/pass.js +353 -0
- package/dist/lib/pass.js.map +1 -0
- package/dist/lib/safeUtils.d.ts +25 -0
- package/dist/lib/safeUtils.js +93 -0
- package/dist/lib/safeUtils.js.map +1 -0
- package/dist/lib/transferUtils.d.ts +643 -0
- package/dist/lib/transferUtils.js +141 -0
- package/dist/lib/transferUtils.js.map +1 -0
- package/dist/lib/utils.d.ts +28 -0
- package/dist/lib/utils.js +166 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/viemUtils.d.ts +80 -0
- package/dist/lib/viemUtils.js +317 -0
- package/dist/lib/viemUtils.js.map +1 -0
- package/dist/lib/warpUtils.d.ts +76 -0
- package/dist/lib/warpUtils.js +448 -0
- package/dist/lib/warpUtils.js.map +1 -0
- package/dist/middleware.d.ts +75 -0
- package/dist/middleware.js +430 -0
- package/dist/middleware.js.map +1 -0
- package/dist/operator.d.ts +4 -0
- package/dist/operator.js +22 -0
- package/dist/operator.js.map +1 -0
- package/dist/operatorOptIn.d.ts +8 -0
- package/dist/operatorOptIn.js +39 -0
- package/dist/operatorOptIn.js.map +1 -0
- package/dist/rewards.d.ts +116 -0
- package/dist/rewards.js +244 -0
- package/dist/rewards.js.map +1 -0
- package/dist/securityModule.d.ts +8 -0
- package/dist/securityModule.js +305 -0
- package/dist/securityModule.js.map +1 -0
- package/dist/stakingVault.d.ts +184 -0
- package/dist/stakingVault.js +1224 -0
- package/dist/stakingVault.js.map +1 -0
- package/dist/uptime.d.ts +54 -0
- package/dist/uptime.js +246 -0
- package/dist/uptime.js.map +1 -0
- package/dist/vault.d.ts +16 -0
- package/dist/vault.js +131 -0
- package/dist/vault.js.map +1 -0
- package/dist/vaultManager.d.ts +8 -0
- package/dist/vaultManager.js +40 -0
- package/dist/vaultManager.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,1224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getValidatorManagerAddress = getValidatorManagerAddress;
|
|
4
|
+
exports.depositStakingVault = depositStakingVault;
|
|
5
|
+
exports.requestWithdrawalStakingVault = requestWithdrawalStakingVault;
|
|
6
|
+
exports.claimWithdrawalStakingVault = claimWithdrawalStakingVault;
|
|
7
|
+
exports.processEpochStakingVault = processEpochStakingVault;
|
|
8
|
+
exports.initiateValidatorRegistrationStakingVault = initiateValidatorRegistrationStakingVault;
|
|
9
|
+
exports.addOperatorStakingVault = addOperatorStakingVault;
|
|
10
|
+
exports.completeValidatorRegistrationStakingVault = completeValidatorRegistrationStakingVault;
|
|
11
|
+
exports.initiateValidatorRemovalStakingVault = initiateValidatorRemovalStakingVault;
|
|
12
|
+
exports.forceRemoveValidatorStakingVault = forceRemoveValidatorStakingVault;
|
|
13
|
+
exports.completeValidatorRemovalStakingVault = completeValidatorRemovalStakingVault;
|
|
14
|
+
exports.initiateDelegatorRegistrationStakingVault = initiateDelegatorRegistrationStakingVault;
|
|
15
|
+
exports.completeDelegatorRegistrationStakingVault = completeDelegatorRegistrationStakingVault;
|
|
16
|
+
exports.initiateDelegatorRemovalStakingVault = initiateDelegatorRemovalStakingVault;
|
|
17
|
+
exports.forceRemoveDelegatorStakingVault = forceRemoveDelegatorStakingVault;
|
|
18
|
+
exports.completeDelegatorRemovalStakingVault = completeDelegatorRemovalStakingVault;
|
|
19
|
+
exports.claimOperatorFees = claimOperatorFees;
|
|
20
|
+
exports.claimEscrowedWithdrawal = claimEscrowedWithdrawal;
|
|
21
|
+
exports.getGeneralInfo = getGeneralInfo;
|
|
22
|
+
exports.getFeesInfo = getFeesInfo;
|
|
23
|
+
exports.getOperatorsInfo = getOperatorsInfo;
|
|
24
|
+
exports.getValidatorsInfo = getValidatorsInfo;
|
|
25
|
+
exports.getDelegatorsInfo = getDelegatorsInfo;
|
|
26
|
+
exports.getWithdrawalsInfo = getWithdrawalsInfo;
|
|
27
|
+
exports.getEpochInfo = getEpochInfo;
|
|
28
|
+
const viem_1 = require("viem");
|
|
29
|
+
const logger_1 = require("./lib/logger");
|
|
30
|
+
const utils_1 = require("./lib/utils");
|
|
31
|
+
const console_log_colors_1 = require("console-log-colors");
|
|
32
|
+
const warpUtils_1 = require("./lib/warpUtils");
|
|
33
|
+
const uptime_1 = require("./uptime");
|
|
34
|
+
const pChainUtils_1 = require("./lib/pChainUtils");
|
|
35
|
+
const justification_1 = require("./lib/justification");
|
|
36
|
+
const ts_belt_1 = require("@mobily/ts-belt");
|
|
37
|
+
const avalanchejs_1 = require("@avalabs/avalanchejs");
|
|
38
|
+
const config_1 = require("./config");
|
|
39
|
+
async function getValidatorManagerAddress(config, stakingVault) {
|
|
40
|
+
const stakingManagerAddress = await stakingVault.read.getStakingManager();
|
|
41
|
+
const stakingManager = await config.contracts.KiteStakingManager(stakingManagerAddress);
|
|
42
|
+
const stakingManagerStorageLocation = await stakingManager.read.STAKING_MANAGER_STORAGE_LOCATION();
|
|
43
|
+
const validatorManagerAddress = (0, utils_1.bytes32ToAddress)((await config.client.getStorageAt({ address: stakingManagerAddress, slot: stakingManagerStorageLocation })));
|
|
44
|
+
return { validatorManagerAddress, stakingManager, stakingManagerStorageLocation };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Deposit native tokens (AVAX) into the StakingVault
|
|
48
|
+
* @param client - The wallet client
|
|
49
|
+
* @param stakingVault - The StakingVault contract instance
|
|
50
|
+
* @param amount - Amount to deposit in AVAX (will be converted to wei with 9 decimals)
|
|
51
|
+
* @param minShares - Minimum shares expected from the deposit (slippage protection)
|
|
52
|
+
*/
|
|
53
|
+
async function depositStakingVault(client, stakingVault, amount, minShares) {
|
|
54
|
+
logger_1.logger.log("Depositing to StakingVault...");
|
|
55
|
+
// Convert amount to wei
|
|
56
|
+
const amountWei = (0, viem_1.parseUnits)(amount, 18);
|
|
57
|
+
logger_1.logger.log("\n=== Deposit Details ===");
|
|
58
|
+
logger_1.logger.log("Amount:", amount, "AVAX");
|
|
59
|
+
logger_1.logger.log("Amount in wei:", amountWei.toString());
|
|
60
|
+
logger_1.logger.log("Minimum shares expected:", minShares.toString());
|
|
61
|
+
logger_1.logger.log("Vault address:", stakingVault.address);
|
|
62
|
+
// Call deposit with value (payable function)
|
|
63
|
+
const hash = await stakingVault.safeWrite.deposit([minShares], {
|
|
64
|
+
value: amountWei,
|
|
65
|
+
chain: null
|
|
66
|
+
});
|
|
67
|
+
logger_1.logger.log("Deposit tx hash:", hash);
|
|
68
|
+
// Wait for deposit confirmation
|
|
69
|
+
logger_1.logger.log("Waiting for deposit confirmation...");
|
|
70
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
71
|
+
logger_1.logger.log("Deposit confirmed in block:", receipt.blockNumber);
|
|
72
|
+
// Parse the deposit event to get the actual shares received
|
|
73
|
+
try {
|
|
74
|
+
const depositEvents = (0, viem_1.parseEventLogs)({
|
|
75
|
+
abi: stakingVault.abi,
|
|
76
|
+
eventName: 'StakingVault__Deposited',
|
|
77
|
+
logs: receipt.logs,
|
|
78
|
+
});
|
|
79
|
+
if (depositEvents.length > 0) {
|
|
80
|
+
const event = depositEvents[0];
|
|
81
|
+
logger_1.logger.log("✅ Deposit completed successfully!");
|
|
82
|
+
logger_1.logger.log("Shares received:", event.args?.shares?.toString() || 'N/A');
|
|
83
|
+
logger_1.logger.log("Stake amount:", event.args?.stakeAmount?.toString() || 'N/A');
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
logger_1.logger.log("✅ Deposit completed successfully!");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
logger_1.logger.log("✅ Deposit completed successfully!");
|
|
91
|
+
logger_1.logger.log("Note: Could not parse deposit event");
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Request withdrawal from the StakingVault
|
|
96
|
+
* @param client - The wallet client
|
|
97
|
+
* @param stakingVault - The StakingVault contract instance
|
|
98
|
+
* @param shares - Amount of shares to withdraw (in wei, 18 decimals)
|
|
99
|
+
*/
|
|
100
|
+
async function requestWithdrawalStakingVault(client, stakingVault, shares) {
|
|
101
|
+
logger_1.logger.log("Requesting withdrawal from StakingVault...");
|
|
102
|
+
// Convert shares to wei (18 decimals)
|
|
103
|
+
const sharesWei = (0, viem_1.parseUnits)(shares, 18);
|
|
104
|
+
logger_1.logger.log("\n=== Withdrawal Request Details ===");
|
|
105
|
+
logger_1.logger.log("Shares:", shares);
|
|
106
|
+
logger_1.logger.log("Shares in wei:", sharesWei.toString());
|
|
107
|
+
logger_1.logger.log("Vault address:", stakingVault.address);
|
|
108
|
+
// Call requestWithdrawal
|
|
109
|
+
const hash = await stakingVault.safeWrite.requestWithdrawal([sharesWei]);
|
|
110
|
+
logger_1.logger.log("Request withdrawal tx hash:", hash);
|
|
111
|
+
// Wait for transaction confirmation
|
|
112
|
+
logger_1.logger.log("Waiting for transaction confirmation...");
|
|
113
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
114
|
+
logger_1.logger.log("Transaction confirmed in block:", receipt.blockNumber);
|
|
115
|
+
// Parse the withdrawal requested event to get the requestId
|
|
116
|
+
try {
|
|
117
|
+
const withdrawalRequestedEvents = (0, viem_1.parseEventLogs)({
|
|
118
|
+
abi: stakingVault.abi,
|
|
119
|
+
eventName: 'StakingVault__WithdrawalRequested',
|
|
120
|
+
logs: receipt.logs,
|
|
121
|
+
});
|
|
122
|
+
if (withdrawalRequestedEvents.length > 0) {
|
|
123
|
+
const event = withdrawalRequestedEvents[0];
|
|
124
|
+
logger_1.logger.log("✅ Withdrawal requested successfully!");
|
|
125
|
+
logger_1.logger.log("Request ID:", event.args?.requestId?.toString() || 'N/A');
|
|
126
|
+
logger_1.logger.log("Shares:", event.args?.shares?.toString() || 'N/A');
|
|
127
|
+
logger_1.logger.log("Stake amount:", event.args?.stakeAmount?.toString() || 'N/A');
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
logger_1.logger.log("✅ Withdrawal requested successfully!");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
logger_1.logger.log("✅ Withdrawal requested successfully!");
|
|
135
|
+
logger_1.logger.log("Note: Could not parse withdrawal requested event");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Claim withdrawal from the StakingVault
|
|
140
|
+
* @param client - The wallet client
|
|
141
|
+
* @param stakingVault - The StakingVault contract instance
|
|
142
|
+
* @param requestId - The withdrawal request ID to claim
|
|
143
|
+
*/
|
|
144
|
+
async function claimWithdrawalStakingVault(client, stakingVault, requestId) {
|
|
145
|
+
logger_1.logger.log("Claiming withdrawal from StakingVault...");
|
|
146
|
+
logger_1.logger.log("\n=== Withdrawal Claim Details ===");
|
|
147
|
+
logger_1.logger.log("Request ID:", requestId.toString());
|
|
148
|
+
logger_1.logger.log("Vault address:", stakingVault.address);
|
|
149
|
+
// Call claimWithdrawal
|
|
150
|
+
const hash = await stakingVault.safeWrite.claimWithdrawal([requestId]);
|
|
151
|
+
logger_1.logger.log("Claim withdrawal tx hash:", hash);
|
|
152
|
+
// Wait for transaction confirmation
|
|
153
|
+
logger_1.logger.log("Waiting for transaction confirmation...");
|
|
154
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
155
|
+
logger_1.logger.log("Transaction confirmed in block:", receipt.blockNumber);
|
|
156
|
+
// Parse the withdrawal claimed event
|
|
157
|
+
try {
|
|
158
|
+
const withdrawalClaimedEvents = (0, viem_1.parseEventLogs)({
|
|
159
|
+
abi: stakingVault.abi,
|
|
160
|
+
eventName: 'StakingVault__WithdrawalClaimed',
|
|
161
|
+
logs: receipt.logs,
|
|
162
|
+
});
|
|
163
|
+
if (withdrawalClaimedEvents.length > 0) {
|
|
164
|
+
const event = withdrawalClaimedEvents[0];
|
|
165
|
+
logger_1.logger.log("✅ Withdrawal claimed successfully!");
|
|
166
|
+
logger_1.logger.log("Request ID:", event.args?.requestId?.toString() || 'N/A');
|
|
167
|
+
logger_1.logger.log("Stake amount claimed:", event.args?.stakeAmount?.toString() || 'N/A');
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
logger_1.logger.log("✅ Withdrawal claimed successfully!");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
logger_1.logger.log("✅ Withdrawal claimed successfully!");
|
|
175
|
+
logger_1.logger.log("Note: Could not parse withdrawal claimed event");
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Process epoch in the StakingVault
|
|
180
|
+
* @param client - The wallet client
|
|
181
|
+
* @param stakingVault - The StakingVault contract instance
|
|
182
|
+
*/
|
|
183
|
+
async function processEpochStakingVault(client, stakingVault) {
|
|
184
|
+
logger_1.logger.log("Processing epoch in StakingVault...");
|
|
185
|
+
logger_1.logger.log("\n=== Process Epoch Details ===");
|
|
186
|
+
logger_1.logger.log("Vault address:", stakingVault.address);
|
|
187
|
+
// Call processEpoch
|
|
188
|
+
const hash = await stakingVault.safeWrite.processEpoch([]);
|
|
189
|
+
logger_1.logger.log("Process epoch tx hash:", hash);
|
|
190
|
+
// Wait for transaction confirmation
|
|
191
|
+
logger_1.logger.log("Waiting for transaction confirmation...");
|
|
192
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
193
|
+
logger_1.logger.log("Transaction confirmed in block:", receipt.blockNumber);
|
|
194
|
+
// Parse the epoch processed event
|
|
195
|
+
try {
|
|
196
|
+
const epochProcessedEvents = (0, viem_1.parseEventLogs)({
|
|
197
|
+
abi: stakingVault.abi,
|
|
198
|
+
eventName: 'StakingVault__EpochProcessed',
|
|
199
|
+
logs: receipt.logs,
|
|
200
|
+
});
|
|
201
|
+
if (epochProcessedEvents.length > 0) {
|
|
202
|
+
const event = epochProcessedEvents[0];
|
|
203
|
+
logger_1.logger.log("✅ Epoch processed successfully!");
|
|
204
|
+
logger_1.logger.log("Epoch:", event.args?.epoch?.toString() || 'N/A');
|
|
205
|
+
logger_1.logger.log("Withdrawals fulfilled:", event.args?.withdrawalsFulfilled?.toString() || 'N/A');
|
|
206
|
+
logger_1.logger.log("Stake released:", event.args?.stakeReleased?.toString() || 'N/A');
|
|
207
|
+
logger_1.logger.log("Requests remaining:", event.args?.requestsRemaining?.toString() || 'N/A');
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
logger_1.logger.log("✅ Epoch processed successfully!");
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
logger_1.logger.log("✅ Epoch processed successfully!");
|
|
215
|
+
logger_1.logger.log("Note: Could not parse epoch processed event");
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Initiate validator registration in the StakingVault
|
|
220
|
+
* @param client - The wallet client
|
|
221
|
+
* @param config - The config object
|
|
222
|
+
* @param stakingVault - The StakingVault contract instance
|
|
223
|
+
* @param nodeId - The node ID
|
|
224
|
+
* @param blsKey - The BLS public key
|
|
225
|
+
* @param remainingBalanceOwner - P-Chain remaining balance owner struct
|
|
226
|
+
* @param disableOwner - P-Chain disable owner struct
|
|
227
|
+
* @param stakeAmount - The stake amount in AVAX (will be converted to wei with 18 decimals)
|
|
228
|
+
*/
|
|
229
|
+
async function initiateValidatorRegistrationStakingVault(client, stakingVault, nodeId, blsKey, remainingBalanceOwner, disableOwner, stakeAmount) {
|
|
230
|
+
logger_1.logger.log("Initiating validator registration in StakingVault...");
|
|
231
|
+
// Convert stake amount to wei (18 decimals)
|
|
232
|
+
const stakeAmountWei = (0, viem_1.parseUnits)(stakeAmount, 18);
|
|
233
|
+
// Parse NodeID to bytes format (20 bytes, no padding)
|
|
234
|
+
const nodeIdBytes = (0, utils_1.parseNodeID)(nodeId, false);
|
|
235
|
+
logger_1.logger.log("\n=== Validator Registration Details ===");
|
|
236
|
+
logger_1.logger.log("Node ID:", nodeId);
|
|
237
|
+
logger_1.logger.log("BLS Key:", blsKey);
|
|
238
|
+
logger_1.logger.log("Stake amount:", stakeAmount, "AVAX");
|
|
239
|
+
logger_1.logger.log("Stake amount in wei:", stakeAmountWei.toString());
|
|
240
|
+
logger_1.logger.log("Remaining balance owner threshold:", remainingBalanceOwner[0]);
|
|
241
|
+
logger_1.logger.log("Remaining balance owner addresses:", remainingBalanceOwner[1]);
|
|
242
|
+
logger_1.logger.log("Disable owner threshold:", disableOwner[0]);
|
|
243
|
+
logger_1.logger.log("Disable owner addresses:", disableOwner[1]);
|
|
244
|
+
logger_1.logger.log("Vault address:", stakingVault.address);
|
|
245
|
+
// Call initiateValidatorRegistration
|
|
246
|
+
const hash = await stakingVault.safeWrite.initiateValidatorRegistration([
|
|
247
|
+
nodeIdBytes,
|
|
248
|
+
blsKey,
|
|
249
|
+
{ threshold: remainingBalanceOwner[0], addresses: remainingBalanceOwner[1] },
|
|
250
|
+
{ threshold: disableOwner[0], addresses: disableOwner[1] },
|
|
251
|
+
stakeAmountWei
|
|
252
|
+
]);
|
|
253
|
+
logger_1.logger.log("Initiate validator registration tx hash:", hash);
|
|
254
|
+
// Wait for transaction confirmation
|
|
255
|
+
logger_1.logger.log("Waiting for transaction confirmation...");
|
|
256
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
257
|
+
logger_1.logger.log("Transaction confirmed in block:", receipt.blockNumber);
|
|
258
|
+
// Parse the validator registration initiated event
|
|
259
|
+
try {
|
|
260
|
+
const validatorRegisteredEvents = (0, viem_1.parseEventLogs)({
|
|
261
|
+
abi: stakingVault.abi,
|
|
262
|
+
eventName: 'StakingVault__ValidatorRegistrationInitiated',
|
|
263
|
+
logs: receipt.logs,
|
|
264
|
+
});
|
|
265
|
+
if (validatorRegisteredEvents.length > 0) {
|
|
266
|
+
const event = validatorRegisteredEvents[0];
|
|
267
|
+
logger_1.logger.log("✅ Validator registration initiated successfully!");
|
|
268
|
+
logger_1.logger.log("Validation ID:", event.args?.validationID || 'N/A');
|
|
269
|
+
logger_1.logger.log("Operator:", event.args?.operator || 'N/A');
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
logger_1.logger.log("✅ Validator registration initiated successfully!");
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
logger_1.logger.log("✅ Validator registration initiated successfully!");
|
|
277
|
+
logger_1.logger.log("Note: Could not parse validator registration initiated event");
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Add an operator to the StakingVault
|
|
282
|
+
* @param client - The wallet client
|
|
283
|
+
* @param config - The config object
|
|
284
|
+
* @param stakingVault - The StakingVault contract instance
|
|
285
|
+
* @param operator - The operator address
|
|
286
|
+
* @param allocationBips - The allocation in basis points (1 bips = 0.01%)
|
|
287
|
+
* @param feeRecipient - The fee recipient address
|
|
288
|
+
*/
|
|
289
|
+
async function addOperatorStakingVault(client, stakingVault, operator, allocationBips, feeRecipient) {
|
|
290
|
+
logger_1.logger.log("Adding operator to StakingVault...");
|
|
291
|
+
logger_1.logger.log("\n=== Add Operator Details ===");
|
|
292
|
+
logger_1.logger.log("Operator address:", operator);
|
|
293
|
+
logger_1.logger.log("Allocation (bips):", allocationBips.toString());
|
|
294
|
+
logger_1.logger.log("Fee recipient:", feeRecipient);
|
|
295
|
+
logger_1.logger.log("Vault address:", stakingVault.address);
|
|
296
|
+
// Call addOperator
|
|
297
|
+
const hash = await stakingVault.safeWrite.addOperator([
|
|
298
|
+
operator,
|
|
299
|
+
allocationBips,
|
|
300
|
+
feeRecipient
|
|
301
|
+
]);
|
|
302
|
+
logger_1.logger.log("Add operator tx hash:", hash);
|
|
303
|
+
// Wait for transaction confirmation
|
|
304
|
+
logger_1.logger.log("Waiting for transaction confirmation...");
|
|
305
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
306
|
+
logger_1.logger.log("Transaction confirmed in block:", receipt.blockNumber);
|
|
307
|
+
// Parse the operator added event
|
|
308
|
+
try {
|
|
309
|
+
const operatorAddedEvents = (0, viem_1.parseEventLogs)({
|
|
310
|
+
abi: stakingVault.abi,
|
|
311
|
+
eventName: 'StakingVault__OperatorAdded',
|
|
312
|
+
logs: receipt.logs,
|
|
313
|
+
});
|
|
314
|
+
if (operatorAddedEvents.length > 0) {
|
|
315
|
+
const event = operatorAddedEvents[0];
|
|
316
|
+
logger_1.logger.log("✅ Operator added successfully!");
|
|
317
|
+
logger_1.logger.log("Operator:", event.args?.operator || 'N/A');
|
|
318
|
+
logger_1.logger.log("Allocation (bips):", event.args?.allocationBips?.toString() || 'N/A');
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
logger_1.logger.log("✅ Operator added successfully!");
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
catch (error) {
|
|
325
|
+
logger_1.logger.log("✅ Operator added successfully!");
|
|
326
|
+
logger_1.logger.log("Note: Could not parse operator added event");
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Complete validator registration in the StakingVault
|
|
331
|
+
* @param client - The wallet client
|
|
332
|
+
* @param pchainClient - The P-Chain wallet client
|
|
333
|
+
* @param config - The config object
|
|
334
|
+
* @param stakingVault - The StakingVault contract
|
|
335
|
+
* @param validatorManager - The ValidatorManager contract
|
|
336
|
+
* @param blsProofOfPossession - The BLS proof of possession
|
|
337
|
+
* @param initiateTxHash - The initiateValidatorRegistration transaction hash
|
|
338
|
+
* @param initialBalance - The initial balance for the validator (in nAVAX, 9 decimals)
|
|
339
|
+
* @param waitValidatorVisible - Whether to wait for the validator to be visible on P-Chain
|
|
340
|
+
*/
|
|
341
|
+
async function completeValidatorRegistrationStakingVault(pchainClient, config, stakingVault, validatorManager, blsProofOfPossession, initiateTxHash, initialBalance, waitValidatorVisible) {
|
|
342
|
+
logger_1.logger.log("Completing validator registration in StakingVault...");
|
|
343
|
+
const client = config.client;
|
|
344
|
+
// Wait for transaction receipt to extract warp message and validation ID
|
|
345
|
+
const receipt = await client.waitForTransactionReceipt({ hash: initiateTxHash });
|
|
346
|
+
// Parse StakingVault__ValidatorRegistrationInitiated event from StakingVaultOperations
|
|
347
|
+
const validatorRegisteredEvents = (0, viem_1.parseEventLogs)({
|
|
348
|
+
abi: stakingVault.abi,
|
|
349
|
+
logs: receipt.logs,
|
|
350
|
+
eventName: 'StakingVault__ValidatorRegistrationInitiated'
|
|
351
|
+
});
|
|
352
|
+
if (!validatorRegisteredEvents || validatorRegisteredEvents.length === 0) {
|
|
353
|
+
logger_1.logger.error(console_log_colors_1.color.red("No StakingVault__ValidatorRegistrationInitiated event found in the transaction logs, verify the transaction hash."));
|
|
354
|
+
process.exit(1);
|
|
355
|
+
}
|
|
356
|
+
const validatorRegisteredEvent = validatorRegisteredEvents[0];
|
|
357
|
+
const validationIDHex = validatorRegisteredEvent.args?.validationID;
|
|
358
|
+
if (!validationIDHex) {
|
|
359
|
+
logger_1.logger.error(console_log_colors_1.color.red("No validationID found in StakingVault__ValidatorRegistrationInitiated event."));
|
|
360
|
+
process.exit(1);
|
|
361
|
+
}
|
|
362
|
+
// Get ValidatorManager to get nodeID and subnetID
|
|
363
|
+
// Get validator info from ValidatorManager
|
|
364
|
+
const validator = await validatorManager.read.getValidator([validationIDHex]);
|
|
365
|
+
const nodeId = (0, utils_1.encodeNodeID)(validator.nodeID);
|
|
366
|
+
const subnetIDHex = await validatorManager.read.subnetID();
|
|
367
|
+
// messageIndex is always 0 for StakingVaultOperations
|
|
368
|
+
const messageIndex = 0;
|
|
369
|
+
// Parse IWarpMessenger event to get the unsigned warp message
|
|
370
|
+
const warpLogs = (0, viem_1.parseEventLogs)({
|
|
371
|
+
abi: config.abis.IWarpMessenger,
|
|
372
|
+
logs: receipt.logs,
|
|
373
|
+
});
|
|
374
|
+
if (!warpLogs || warpLogs.length === 0) {
|
|
375
|
+
logger_1.logger.error(console_log_colors_1.color.red("No IWarpMessenger event found in the transaction logs."));
|
|
376
|
+
process.exit(1);
|
|
377
|
+
}
|
|
378
|
+
const warpLog = warpLogs[0];
|
|
379
|
+
const signingSubnetId = await (0, warpUtils_1.getSigningSubnetIdFromWarpMessage)(client, warpLog.args.message);
|
|
380
|
+
// Check if the node is already registered as a validator on the P-Chain
|
|
381
|
+
const subnetIDStr = avalanchejs_1.utils.base58check.encode((0, viem_1.hexToBytes)(subnetIDHex));
|
|
382
|
+
const isValidator = (await (0, pChainUtils_1.getCurrentValidators)(client, subnetIDStr)).some((v) => v.nodeID === nodeId);
|
|
383
|
+
if (isValidator) {
|
|
384
|
+
logger_1.logger.log(console_log_colors_1.color.yellow("Node is already registered as a validator on the P-Chain, skipping registerL1Validator call."));
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
// Get the unsigned warp message from the receipt
|
|
388
|
+
const RegisterL1ValidatorUnsignedWarpMsg = warpLog.args.message;
|
|
389
|
+
// Collect signatures for the warp message
|
|
390
|
+
logger_1.logger.log("\nCollecting signatures for the L1ValidatorRegistrationMessage from the Validator Manager chain...");
|
|
391
|
+
const signedMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: RegisterL1ValidatorUnsignedWarpMsg, signingSubnetId });
|
|
392
|
+
// Register validator on P-Chain
|
|
393
|
+
logger_1.logger.log("\nRegistering validator on P-Chain...");
|
|
394
|
+
(0, ts_belt_1.pipe)(await (0, pChainUtils_1.registerL1Validator)({
|
|
395
|
+
client: pchainClient,
|
|
396
|
+
blsProofOfPossession: blsProofOfPossession,
|
|
397
|
+
signedMessage,
|
|
398
|
+
initialBalance: initialBalance
|
|
399
|
+
}), ts_belt_1.R.tap(pChainTxId => logger_1.logger.log("RegisterL1ValidatorTx executed on P-Chain:", pChainTxId)), ts_belt_1.R.tapError(err => { logger_1.logger.error(err); process.exit(1); }));
|
|
400
|
+
}
|
|
401
|
+
// Pack and sign the P-Chain warp message
|
|
402
|
+
const validationIDBytes = (0, viem_1.hexToBytes)(validationIDHex);
|
|
403
|
+
const unsignedPChainWarpMsg = (0, warpUtils_1.packL1ValidatorRegistration)(validationIDBytes, true, client.network === 'fuji' ? 5 : 1, config_1.pChainChainID);
|
|
404
|
+
const unsignedPChainWarpMsgHex = (0, viem_1.bytesToHex)(unsignedPChainWarpMsg);
|
|
405
|
+
// Aggregate signatures from validators
|
|
406
|
+
logger_1.logger.log("\nAggregating signatures for the L1ValidatorRegistrationMessage from the P-Chain...");
|
|
407
|
+
const signedPChainMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedPChainWarpMsgHex, signingSubnetId });
|
|
408
|
+
// Convert the signed warp message to bytes and pack into access list
|
|
409
|
+
const signedPChainWarpMsgBytes = (0, viem_1.hexToBytes)(`0x${signedPChainMessage}`);
|
|
410
|
+
const accessList = (0, warpUtils_1.packWarpIntoAccessList)(signedPChainWarpMsgBytes);
|
|
411
|
+
logger_1.logger.log("\nCalling function completeValidatorRegistration on the staking vault...");
|
|
412
|
+
const hash = await stakingVault.safeWrite.completeValidatorRegistration([messageIndex], {
|
|
413
|
+
chain: null,
|
|
414
|
+
accessList
|
|
415
|
+
});
|
|
416
|
+
// Wait until the validator is visible on the P-Chain
|
|
417
|
+
if (waitValidatorVisible) {
|
|
418
|
+
logger_1.logger.log("Waiting for the validator to be visible on the P-Chain (may take a while)...");
|
|
419
|
+
await (0, utils_1.retryWhileError)(async () => (await (0, pChainUtils_1.getCurrentValidators)(client, subnetIDStr)).some((v) => v.nodeID === nodeId), 5000, 180000, (res) => res === true);
|
|
420
|
+
}
|
|
421
|
+
logger_1.logger.log("completeValidatorRegistration executed successfully, tx hash:", hash);
|
|
422
|
+
return hash;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Initiate validator removal in the StakingVault
|
|
426
|
+
* @param client - The wallet client
|
|
427
|
+
* @param config - The config object
|
|
428
|
+
* @param stakingVault - The StakingVault contract instance
|
|
429
|
+
* @param validatorManager - The ValidatorManager contract instance
|
|
430
|
+
* @param nodeId - The node ID of the validator to remove
|
|
431
|
+
*/
|
|
432
|
+
async function initiateValidatorRemovalStakingVault(client, stakingVault, validatorManager, nodeId) {
|
|
433
|
+
logger_1.logger.log("Initiating validator removal in StakingVault...");
|
|
434
|
+
// Parse NodeID to bytes format (20 bytes, no padding)
|
|
435
|
+
const nodeIdBytes = (0, utils_1.parseNodeID)(nodeId, false);
|
|
436
|
+
// Get validationID from ValidatorManager
|
|
437
|
+
const validationID = await validatorManager.read.getNodeValidationID([nodeIdBytes]);
|
|
438
|
+
logger_1.logger.log("\n=== Validator Removal Initiation Details ===");
|
|
439
|
+
logger_1.logger.log("Node ID:", nodeId);
|
|
440
|
+
logger_1.logger.log("Validation ID:", validationID);
|
|
441
|
+
logger_1.logger.log("Vault address:", stakingVault.address);
|
|
442
|
+
// Call initiateValidatorRemoval
|
|
443
|
+
const hash = await stakingVault.safeWrite.initiateValidatorRemoval([
|
|
444
|
+
validationID
|
|
445
|
+
]);
|
|
446
|
+
logger_1.logger.log("Initiate validator removal tx hash:", hash);
|
|
447
|
+
// Wait for transaction confirmation
|
|
448
|
+
logger_1.logger.log("Waiting for transaction confirmation...");
|
|
449
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
450
|
+
logger_1.logger.log("Transaction confirmed in block:", receipt.blockNumber);
|
|
451
|
+
// Parse the validator removal initiated event
|
|
452
|
+
try {
|
|
453
|
+
const validatorRemovalInitiatedEvents = (0, viem_1.parseEventLogs)({
|
|
454
|
+
abi: stakingVault.abi,
|
|
455
|
+
eventName: 'StakingVault__ValidatorRemovalInitiated',
|
|
456
|
+
logs: receipt.logs,
|
|
457
|
+
});
|
|
458
|
+
if (validatorRemovalInitiatedEvents.length > 0) {
|
|
459
|
+
const event = validatorRemovalInitiatedEvents[0];
|
|
460
|
+
logger_1.logger.log("✅ Validator removal initiated successfully!");
|
|
461
|
+
logger_1.logger.log("Validation ID:", event.args?.validationID || 'N/A');
|
|
462
|
+
logger_1.logger.log("Operator:", event.args?.operator || 'N/A');
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
logger_1.logger.log("✅ Validator removal initiated successfully!");
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
catch (error) {
|
|
469
|
+
logger_1.logger.log("✅ Validator removal initiated successfully!");
|
|
470
|
+
logger_1.logger.log("Note: Could not parse validator removal initiated event");
|
|
471
|
+
}
|
|
472
|
+
return hash;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Force remove a validator from the StakingVault (admin/emergency operation).
|
|
476
|
+
* @param client - The wallet client
|
|
477
|
+
* @param stakingVault - The StakingVault contract instance
|
|
478
|
+
* @param validatorManager - The ValidatorManager contract instance
|
|
479
|
+
* @param nodeId - The node ID of the validator to force remove
|
|
480
|
+
*/
|
|
481
|
+
async function forceRemoveValidatorStakingVault(client, stakingVault, validatorManager, nodeId) {
|
|
482
|
+
logger_1.logger.log("Force removing validator from StakingVault...");
|
|
483
|
+
// Parse NodeID to bytes format (20 bytes, no padding)
|
|
484
|
+
const nodeIdBytes = (0, utils_1.parseNodeID)(nodeId, false);
|
|
485
|
+
// Get validationID from ValidatorManager
|
|
486
|
+
const validationID = await validatorManager.read.getNodeValidationID([nodeIdBytes]);
|
|
487
|
+
logger_1.logger.log("\n=== Force Remove Validator Details ===");
|
|
488
|
+
logger_1.logger.log("Node ID:", nodeId);
|
|
489
|
+
logger_1.logger.log("Validation ID:", validationID);
|
|
490
|
+
logger_1.logger.log("Vault address:", stakingVault.address);
|
|
491
|
+
const hash = await stakingVault.safeWrite.forceRemoveValidator([validationID]);
|
|
492
|
+
logger_1.logger.log("Force remove validator tx hash:", hash);
|
|
493
|
+
logger_1.logger.log("Waiting for transaction confirmation...");
|
|
494
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
495
|
+
logger_1.logger.log("Transaction confirmed in block:", receipt.blockNumber);
|
|
496
|
+
logger_1.logger.log("✅ Validator force-removed successfully!");
|
|
497
|
+
return hash;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Complete validator removal in the StakingVault
|
|
501
|
+
* @param client - The wallet client
|
|
502
|
+
* @param pchainClient - The P-Chain wallet client
|
|
503
|
+
* @param config - The config object
|
|
504
|
+
* @param stakingVault - The StakingVault contract instance
|
|
505
|
+
* @param validatorManager - The ValidatorManager contract instance
|
|
506
|
+
* @param initiateRemovalTxHash - The initiateValidatorRemoval transaction hash
|
|
507
|
+
* @param waitValidatorVisible - Whether to wait for the validator to be removed from P-Chain
|
|
508
|
+
* @param nodeIDs - Optional node IDs to filter removals
|
|
509
|
+
* @param initiateTxHash - Optional initiate validator registration transaction hash for justification
|
|
510
|
+
*/
|
|
511
|
+
async function completeValidatorRemovalStakingVault(pchainClient, config, stakingVault, validatorManager, initiateRemovalTxHash, waitValidatorVisible, nodeIDs, initiateTxHash) {
|
|
512
|
+
logger_1.logger.log("Completing validator removal in StakingVault...");
|
|
513
|
+
const client = config.client;
|
|
514
|
+
// Wait for the initiate removal transaction to be confirmed
|
|
515
|
+
const receipt = await client.waitForTransactionReceipt({ hash: initiateRemovalTxHash, confirmations: 1 });
|
|
516
|
+
if (receipt.status === 'reverted')
|
|
517
|
+
throw new Error(`Transaction ${initiateRemovalTxHash} reverted, pls resend the removal transaction`);
|
|
518
|
+
// Parse StakingVault__ValidatorRemovalInitiated events from StakingVaultOperations
|
|
519
|
+
const validatorRemovalInitiatedEvents = (0, viem_1.parseEventLogs)({
|
|
520
|
+
abi: stakingVault.abi,
|
|
521
|
+
logs: receipt.logs,
|
|
522
|
+
eventName: 'StakingVault__ValidatorRemovalInitiated'
|
|
523
|
+
});
|
|
524
|
+
if (validatorRemovalInitiatedEvents.length === 0) {
|
|
525
|
+
logger_1.logger.error(console_log_colors_1.color.red("No StakingVault__ValidatorRemovalInitiated event found in the transaction logs, verify the transaction hash."));
|
|
526
|
+
process.exit(1);
|
|
527
|
+
}
|
|
528
|
+
// Filter by nodeIDs if provided
|
|
529
|
+
const filteredRemovals = nodeIDs
|
|
530
|
+
? (await Promise.all(validatorRemovalInitiatedEvents.map(async (e) => {
|
|
531
|
+
const validationID = e.args?.validationID;
|
|
532
|
+
if (!validationID)
|
|
533
|
+
return null;
|
|
534
|
+
const validator = await validatorManager.read.getValidator([validationID]);
|
|
535
|
+
const nodeId = (0, utils_1.encodeNodeID)(validator.nodeID);
|
|
536
|
+
return { event: e, nodeId };
|
|
537
|
+
}))).filter((item) => item !== null && nodeIDs.includes(item.nodeId)).map(({ event }) => event)
|
|
538
|
+
: validatorRemovalInitiatedEvents;
|
|
539
|
+
if (filteredRemovals.length === 0) {
|
|
540
|
+
logger_1.logger.error(console_log_colors_1.color.red("No matching StakingVault__ValidatorRemovalInitiated event found for the provided NodeIDs, verify the transaction hash and NodeIDs."));
|
|
541
|
+
process.exit(1);
|
|
542
|
+
}
|
|
543
|
+
const warpLogs = (0, viem_1.parseEventLogs)({
|
|
544
|
+
abi: config.abis.IWarpMessenger,
|
|
545
|
+
logs: receipt.logs,
|
|
546
|
+
});
|
|
547
|
+
const subnetIDHex = await validatorManager.read.subnetID();
|
|
548
|
+
const subnetID = avalanchejs_1.utils.base58check.encode((0, viem_1.hexToBytes)(subnetIDHex));
|
|
549
|
+
const currentValidators = await (0, pChainUtils_1.getCurrentValidators)(client, subnetID);
|
|
550
|
+
// Find InitiatedValidatorRemoval events from ValidatorManager to get weight message info
|
|
551
|
+
const validatorManagerRemovalEvents = (0, viem_1.parseEventLogs)({
|
|
552
|
+
abi: validatorManager.abi,
|
|
553
|
+
logs: receipt.logs,
|
|
554
|
+
eventName: 'InitiatedValidatorRemoval'
|
|
555
|
+
});
|
|
556
|
+
for (const event of filteredRemovals) {
|
|
557
|
+
const validationID = event.args?.validationID;
|
|
558
|
+
if (!validationID) {
|
|
559
|
+
logger_1.logger.error(console_log_colors_1.color.red("No validationID found in StakingVault__ValidatorRemovalInitiated event."));
|
|
560
|
+
continue;
|
|
561
|
+
}
|
|
562
|
+
// Get nodeID from validator
|
|
563
|
+
const validator = await validatorManager.read.getValidator([validationID]);
|
|
564
|
+
const nodeID = (0, utils_1.encodeNodeID)(validator.nodeID);
|
|
565
|
+
logger_1.logger.log(`Processing removal for node ${nodeID}`);
|
|
566
|
+
// Find the corresponding ValidatorManager InitiatedValidatorRemoval event
|
|
567
|
+
const validatorManagerEvent = validatorManagerRemovalEvents.find((e) => e.args?.validationID === validationID);
|
|
568
|
+
if (!validatorManagerEvent) {
|
|
569
|
+
logger_1.logger.error(console_log_colors_1.color.red(`No matching ValidatorManager InitiatedValidatorRemoval event found for validationID ${validationID}`));
|
|
570
|
+
continue;
|
|
571
|
+
}
|
|
572
|
+
// Find the corresponding warp log
|
|
573
|
+
const warpLog = warpLogs.find((w) => {
|
|
574
|
+
return w.args.messageID === validatorManagerEvent.args.validatorWeightMessageID;
|
|
575
|
+
});
|
|
576
|
+
if (!warpLog) {
|
|
577
|
+
logger_1.logger.error(console_log_colors_1.color.red(`No matching warp log found for validationID ${validationID}`));
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
const signingSubnetId = await (0, warpUtils_1.getSigningSubnetIdFromWarpMessage)(client, warpLog.args.message);
|
|
581
|
+
let addNodeBlockNumber = receipt.blockNumber;
|
|
582
|
+
if (initiateTxHash) {
|
|
583
|
+
const addNodeReceipt = await client.waitForTransactionReceipt({ hash: initiateTxHash, confirmations: 0 });
|
|
584
|
+
if (addNodeReceipt.status === 'reverted')
|
|
585
|
+
throw new Error(`Transaction ${initiateTxHash} reverted, pls use another initiate tx`);
|
|
586
|
+
addNodeBlockNumber = addNodeReceipt.blockNumber;
|
|
587
|
+
}
|
|
588
|
+
// Check if the node is still registered as a validator on the P-Chain
|
|
589
|
+
const isValidator = currentValidators.some((v) => v.nodeID === nodeID);
|
|
590
|
+
if (!isValidator) {
|
|
591
|
+
logger_1.logger.log(console_log_colors_1.color.yellow("Node is not registered as a validator on the P-Chain."));
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
// Get the unsigned L1ValidatorWeightMessage with weight=0 generated by the ValidatorManager from the receipt
|
|
595
|
+
const unsignedL1ValidatorWeightMessage = warpLog.args.message;
|
|
596
|
+
// Aggregate signatures from validators
|
|
597
|
+
logger_1.logger.log("\nCollecting signatures for the L1ValidatorWeightMessage from the Validator Manager chain...");
|
|
598
|
+
const signedL1ValidatorWeightMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedL1ValidatorWeightMessage, signingSubnetId });
|
|
599
|
+
logger_1.logger.log("Aggregated signatures for the L1ValidatorWeightMessage from the Validator Manager chain");
|
|
600
|
+
// Call setValidatorWeight on the P-Chain with the signed L1ValidatorWeightMessage
|
|
601
|
+
logger_1.logger.log("\nSetting validator weight on P-Chain...");
|
|
602
|
+
(0, ts_belt_1.pipe)(await (0, pChainUtils_1.setValidatorWeight)({
|
|
603
|
+
client: pchainClient,
|
|
604
|
+
validationID: validationID,
|
|
605
|
+
message: signedL1ValidatorWeightMessage
|
|
606
|
+
}), ts_belt_1.R.tapError((error) => {
|
|
607
|
+
throw new Error("SetL1ValidatorWeightTx failed on P-Chain: " + error + '\n');
|
|
608
|
+
}), ts_belt_1.R.tap((txId) => {
|
|
609
|
+
logger_1.logger.log("SetL1ValidatorWeightTx executed on P-Chain: " + txId);
|
|
610
|
+
}));
|
|
611
|
+
}
|
|
612
|
+
// Get justification for original register validator tx
|
|
613
|
+
const justification = await (0, justification_1.GetRegistrationJustification)(nodeID, validationID, config_1.pChainChainID, client, addNodeBlockNumber);
|
|
614
|
+
if (!justification) {
|
|
615
|
+
throw new Error("Justification not found for validator removal");
|
|
616
|
+
}
|
|
617
|
+
// Pack and sign the P-Chain warp message
|
|
618
|
+
const validationIDBytes = (0, viem_1.hexToBytes)(validationID);
|
|
619
|
+
const unsignedPChainWarpMsg = (0, warpUtils_1.packL1ValidatorRegistration)(validationIDBytes, false, client.network === 'fuji' ? 5 : 1, config_1.pChainChainID);
|
|
620
|
+
const unsignedPChainWarpMsgHex = (0, viem_1.bytesToHex)(unsignedPChainWarpMsg);
|
|
621
|
+
// Aggregate signatures from validators
|
|
622
|
+
logger_1.logger.log("\nAggregating signatures for the L1ValidatorRegistrationMessage from the P-Chain...");
|
|
623
|
+
const signedPChainMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedPChainWarpMsgHex, justification: (0, viem_1.bytesToHex)(justification), signingSubnetId });
|
|
624
|
+
logger_1.logger.log("Aggregated signatures for the L1ValidatorRegistrationMessage from the P-Chain");
|
|
625
|
+
// Convert the signed warp message to bytes and pack into access list
|
|
626
|
+
const signedPChainWarpMsgBytes = (0, viem_1.hexToBytes)(`0x${signedPChainMessage}`);
|
|
627
|
+
const accessList = (0, warpUtils_1.packWarpIntoAccessList)(signedPChainWarpMsgBytes);
|
|
628
|
+
// messageIndex is always 0 for StakingVaultOperations
|
|
629
|
+
const messageIndex = 0;
|
|
630
|
+
// Execute completeValidatorRemoval transaction
|
|
631
|
+
logger_1.logger.log("Executing completeValidatorRemoval transaction...");
|
|
632
|
+
const completeHash = await stakingVault.safeWrite.completeValidatorRemoval([messageIndex], {
|
|
633
|
+
account: client.account,
|
|
634
|
+
chain: null,
|
|
635
|
+
accessList
|
|
636
|
+
});
|
|
637
|
+
if (waitValidatorVisible) {
|
|
638
|
+
logger_1.logger.log("Waiting for the validator to be removed from the P-Chain (may take a while)...");
|
|
639
|
+
await (0, utils_1.retryWhileError)(async () => (await (0, pChainUtils_1.getCurrentValidators)(client, subnetID)).some((v) => v.nodeID === nodeID), 5000, 180000, (res) => res === false);
|
|
640
|
+
}
|
|
641
|
+
logger_1.logger.log("completeValidatorRemoval executed successfully, tx hash:", completeHash);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Initiate delegator registration in the StakingVault
|
|
646
|
+
* @param client - The wallet client
|
|
647
|
+
* @param config - The config object
|
|
648
|
+
* @param stakingVault - The StakingVault contract instance
|
|
649
|
+
* @param validatorManager - The ValidatorManager contract instance
|
|
650
|
+
* @param nodeId - The node ID of the validator to delegate to
|
|
651
|
+
* @param amount - The stake amount in AVAX (will be converted to wei with 18 decimals)
|
|
652
|
+
*/
|
|
653
|
+
async function initiateDelegatorRegistrationStakingVault(client, stakingVault, validatorManager, nodeId, amount) {
|
|
654
|
+
logger_1.logger.log("Initiating delegator registration in StakingVault...");
|
|
655
|
+
// Convert amount to wei (18 decimals)
|
|
656
|
+
const amountWei = (0, viem_1.parseUnits)(amount, 18);
|
|
657
|
+
// Parse NodeID to bytes format (20 bytes, no padding)
|
|
658
|
+
const nodeIdBytes = (0, utils_1.parseNodeID)(nodeId, false);
|
|
659
|
+
// Get validationID from ValidatorManager
|
|
660
|
+
const validationID = await validatorManager.read.getNodeValidationID([nodeIdBytes]);
|
|
661
|
+
logger_1.logger.log("\n=== Delegator Registration Details ===");
|
|
662
|
+
logger_1.logger.log("Node ID:", nodeId);
|
|
663
|
+
logger_1.logger.log("Validation ID:", validationID);
|
|
664
|
+
logger_1.logger.log("Amount:", amount, "AVAX");
|
|
665
|
+
logger_1.logger.log("Amount in wei:", amountWei.toString());
|
|
666
|
+
logger_1.logger.log("Vault address:", stakingVault.address);
|
|
667
|
+
// Call initiateDelegatorRegistration
|
|
668
|
+
const hash = await stakingVault.safeWrite.initiateDelegatorRegistration([
|
|
669
|
+
validationID,
|
|
670
|
+
amountWei
|
|
671
|
+
]);
|
|
672
|
+
logger_1.logger.log("Initiate delegator registration tx hash:", hash);
|
|
673
|
+
// Wait for transaction confirmation
|
|
674
|
+
logger_1.logger.log("Waiting for transaction confirmation...");
|
|
675
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
676
|
+
logger_1.logger.log("Transaction confirmed in block:", receipt.blockNumber);
|
|
677
|
+
// Parse the delegator registration initiated event
|
|
678
|
+
try {
|
|
679
|
+
const delegatorRegisteredEvents = (0, viem_1.parseEventLogs)({
|
|
680
|
+
abi: stakingVault.abi,
|
|
681
|
+
eventName: 'StakingVault__DelegatorRegistrationInitiated',
|
|
682
|
+
logs: receipt.logs,
|
|
683
|
+
});
|
|
684
|
+
if (delegatorRegisteredEvents.length > 0) {
|
|
685
|
+
const event = delegatorRegisteredEvents[0];
|
|
686
|
+
logger_1.logger.log("✅ Delegator registration initiated successfully!");
|
|
687
|
+
logger_1.logger.log("Delegation ID:", event.args?.delegationID || 'N/A');
|
|
688
|
+
logger_1.logger.log("Validation ID:", event.args?.validationID || 'N/A');
|
|
689
|
+
logger_1.logger.log("Operator:", event.args?.operator || 'N/A');
|
|
690
|
+
logger_1.logger.log("Amount:", event.args?.amount?.toString() || 'N/A');
|
|
691
|
+
}
|
|
692
|
+
else {
|
|
693
|
+
logger_1.logger.log("✅ Delegator registration initiated successfully!");
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
catch (error) {
|
|
697
|
+
logger_1.logger.log("✅ Delegator registration initiated successfully!");
|
|
698
|
+
logger_1.logger.log("Note: Could not parse delegator registration initiated event");
|
|
699
|
+
}
|
|
700
|
+
return hash;
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* Complete delegator registration in the StakingVault
|
|
704
|
+
* @param client - The wallet client
|
|
705
|
+
* @param pchainClient - The P-Chain wallet client
|
|
706
|
+
* @param config - The config object
|
|
707
|
+
* @param stakingVault - The StakingVault contract instance
|
|
708
|
+
* @param validatorManager - The ValidatorManager contract instance
|
|
709
|
+
* @param initiateTxHash - The initiateDelegatorRegistration transaction hash
|
|
710
|
+
* @param rpcUrl - RPC URL for getting validator uptime
|
|
711
|
+
* @param uptimeBlockchainID - The uptime blockchain ID (Hex) for the source chain ID
|
|
712
|
+
*/
|
|
713
|
+
async function completeDelegatorRegistrationStakingVault(pchainClient, config, stakingVault, validatorManager, initiateTxHash, rpcUrl, uptimeBlockchainID) {
|
|
714
|
+
logger_1.logger.log("Completing delegator registration in StakingVault...");
|
|
715
|
+
const client = config.client;
|
|
716
|
+
// Wait for the initiate delegator registration transaction to be confirmed
|
|
717
|
+
const receipt = await client.waitForTransactionReceipt({ hash: initiateTxHash, confirmations: 1 });
|
|
718
|
+
if (receipt.status === 'reverted')
|
|
719
|
+
throw new Error(`Transaction ${initiateTxHash} reverted, pls resend the initiate delegator registration transaction`);
|
|
720
|
+
// Parse StakingVault__DelegatorRegistrationInitiated event from StakingVaultOperations
|
|
721
|
+
const delegatorRegisteredEvents = (0, viem_1.parseEventLogs)({
|
|
722
|
+
abi: stakingVault.abi,
|
|
723
|
+
logs: receipt.logs,
|
|
724
|
+
eventName: 'StakingVault__DelegatorRegistrationInitiated'
|
|
725
|
+
});
|
|
726
|
+
if (!delegatorRegisteredEvents || delegatorRegisteredEvents.length === 0) {
|
|
727
|
+
logger_1.logger.error(console_log_colors_1.color.red("No StakingVault__DelegatorRegistrationInitiated event found in the transaction logs, verify the transaction hash."));
|
|
728
|
+
process.exit(1);
|
|
729
|
+
}
|
|
730
|
+
const delegatorRegisteredEvent = delegatorRegisteredEvents[0];
|
|
731
|
+
const delegationID = delegatorRegisteredEvent.args?.delegationID;
|
|
732
|
+
const validationID = delegatorRegisteredEvent.args?.validationID;
|
|
733
|
+
if (!delegationID || !validationID) {
|
|
734
|
+
logger_1.logger.error(console_log_colors_1.color.red("No delegationID or validationID found in StakingVault__DelegatorRegistrationInitiated event."));
|
|
735
|
+
process.exit(1);
|
|
736
|
+
}
|
|
737
|
+
// Get the validator info to get nodeID
|
|
738
|
+
const validator = await validatorManager.read.getValidator([validationID]);
|
|
739
|
+
const nodeId = (0, utils_1.encodeNodeID)(validator.nodeID);
|
|
740
|
+
// Find InitiatedValidatorWeightUpdate events from ValidatorManager to get weight and nonce
|
|
741
|
+
const weightUpdateEvents = (0, viem_1.parseEventLogs)({
|
|
742
|
+
abi: validatorManager.abi,
|
|
743
|
+
logs: receipt.logs,
|
|
744
|
+
eventName: 'InitiatedValidatorWeightUpdate'
|
|
745
|
+
});
|
|
746
|
+
// Find the weight update event for this validationID
|
|
747
|
+
const weightUpdateEvent = weightUpdateEvents.find((e) => e.args?.validationID === validationID);
|
|
748
|
+
if (!weightUpdateEvent) {
|
|
749
|
+
logger_1.logger.error(console_log_colors_1.color.red("No InitiatedValidatorWeightUpdate event found for validationID, verify the transaction hash."));
|
|
750
|
+
process.exit(1);
|
|
751
|
+
}
|
|
752
|
+
const validatorWeight = weightUpdateEvent.args?.weight;
|
|
753
|
+
const nonce = weightUpdateEvent.args?.nonce;
|
|
754
|
+
const setWeightMessageID = weightUpdateEvent.args?.weightUpdateMessageID;
|
|
755
|
+
// Get warp logs to find the weight message
|
|
756
|
+
const warpLogs = (0, viem_1.parseEventLogs)({
|
|
757
|
+
abi: config.abis.IWarpMessenger,
|
|
758
|
+
logs: receipt.logs,
|
|
759
|
+
});
|
|
760
|
+
const weightWarpLog = warpLogs.find((w) => w.args.messageID === setWeightMessageID);
|
|
761
|
+
if (!weightWarpLog) {
|
|
762
|
+
logger_1.logger.error(console_log_colors_1.color.red("No matching warp message found for setWeightMessageID, verify the transaction hash."));
|
|
763
|
+
process.exit(1);
|
|
764
|
+
}
|
|
765
|
+
const signingSubnetId = await (0, warpUtils_1.getSigningSubnetIdFromWarpMessage)(client, weightWarpLog.args.message);
|
|
766
|
+
// Get the unsigned L1ValidatorWeightMessage
|
|
767
|
+
const unsignedL1ValidatorWeightMessage = weightWarpLog.args.message;
|
|
768
|
+
// Aggregate signatures from validators for the weight message
|
|
769
|
+
logger_1.logger.log("\nCollecting signatures for the L1ValidatorWeightMessage from the Validator Manager chain...");
|
|
770
|
+
const signedL1ValidatorWeightMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedL1ValidatorWeightMessage, signingSubnetId });
|
|
771
|
+
logger_1.logger.log("Aggregated signatures for the L1ValidatorWeightMessage from the Validator Manager chain");
|
|
772
|
+
// Call setValidatorWeight on the P-Chain with the signed L1ValidatorWeightMessage
|
|
773
|
+
logger_1.logger.log("\nSetting validator weight on P-Chain...");
|
|
774
|
+
(0, ts_belt_1.pipe)(await (0, pChainUtils_1.setValidatorWeight)({
|
|
775
|
+
client: pchainClient,
|
|
776
|
+
validationID: validationID,
|
|
777
|
+
message: signedL1ValidatorWeightMessage
|
|
778
|
+
}), ts_belt_1.R.tap(pChainSetWeightTxId => logger_1.logger.log("SetL1ValidatorWeightTx executed on P-Chain:", pChainSetWeightTxId)), ts_belt_1.R.tapError(err => {
|
|
779
|
+
if (!err.includes('warp message contains stale nonce')) {
|
|
780
|
+
logger_1.logger.error(err);
|
|
781
|
+
process.exit(1);
|
|
782
|
+
}
|
|
783
|
+
logger_1.logger.warn(console_log_colors_1.color.yellow(`Warning: Skipping SetL1ValidatorWeightTx for validationID ${validationID} due to stale nonce (already issued)`));
|
|
784
|
+
}));
|
|
785
|
+
// Pack and sign the P-Chain warp message for weight update
|
|
786
|
+
const validationIDBytes = (0, viem_1.hexToBytes)(validationID);
|
|
787
|
+
const unsignedPChainWeightWarpMsg = (0, warpUtils_1.packL1ValidatorWeightMessage)(validationIDBytes, BigInt(nonce), BigInt(validatorWeight), client.network === 'fuji' ? 5 : 1, config_1.pChainChainID);
|
|
788
|
+
const unsignedPChainWeightWarpMsgHex = (0, viem_1.bytesToHex)(unsignedPChainWeightWarpMsg);
|
|
789
|
+
const sourceChainID = avalanchejs_1.utils.base58check.encode((0, viem_1.hexToBytes)(uptimeBlockchainID));
|
|
790
|
+
// Aggregate signatures from validators for the P-Chain weight message
|
|
791
|
+
logger_1.logger.log("\nAggregating signatures for the L1ValidatorWeightMessage from the P-Chain...");
|
|
792
|
+
const signedPChainWeightMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedPChainWeightWarpMsgHex, signingSubnetId });
|
|
793
|
+
logger_1.logger.log("Aggregated signatures for the L1ValidatorWeightMessage from the P-Chain");
|
|
794
|
+
// Get the uptime message
|
|
795
|
+
// Use the uptimeBlockchainID passed as parameter (same as KiteStakingManager settings)
|
|
796
|
+
const warpNetworkID = client.network === 'fuji' ? 5 : 1;
|
|
797
|
+
logger_1.logger.log("\nGetting validation uptime message...");
|
|
798
|
+
const signedUptimeMessage = await (0, uptime_1.getValidationUptimeMessage)(client, `${rpcUrl}/ext/bc/${sourceChainID}`, nodeId, warpNetworkID, sourceChainID);
|
|
799
|
+
// Ensure signedUptimeMessage has 0x prefix
|
|
800
|
+
const signedUptimeMessageHex = signedUptimeMessage.startsWith('0x') ? signedUptimeMessage : `0x${signedUptimeMessage}`;
|
|
801
|
+
// Pack both messages into access list
|
|
802
|
+
// Convert both signed messages to bytes
|
|
803
|
+
const signedPChainWeightWarpMsgBytes = (0, viem_1.hexToBytes)(`0x${signedPChainWeightMessage}`);
|
|
804
|
+
const signedUptimeMessageBytes = (0, viem_1.hexToBytes)(signedUptimeMessageHex);
|
|
805
|
+
// Pack both messages into separate access list objects
|
|
806
|
+
const weightAccessList = (0, warpUtils_1.packWarpIntoAccessList)(signedPChainWeightWarpMsgBytes);
|
|
807
|
+
const uptimeAccessList = (0, warpUtils_1.packWarpIntoAccessList)(signedUptimeMessageBytes);
|
|
808
|
+
// Combine access lists as two separate objects in the array
|
|
809
|
+
const combinedAccessList = [
|
|
810
|
+
weightAccessList[0],
|
|
811
|
+
uptimeAccessList[0]
|
|
812
|
+
];
|
|
813
|
+
// messageIndex is always 0 for StakingVaultOperations
|
|
814
|
+
const messageIndex = 0;
|
|
815
|
+
const uptimeMessageIndex = 1;
|
|
816
|
+
logger_1.logger.log("\nCalling function completeDelegatorRegistration...");
|
|
817
|
+
const hash = await stakingVault.safeWrite.completeDelegatorRegistration([delegationID, messageIndex, uptimeMessageIndex], {
|
|
818
|
+
account: client.account,
|
|
819
|
+
chain: null,
|
|
820
|
+
accessList: combinedAccessList
|
|
821
|
+
});
|
|
822
|
+
logger_1.logger.log("completeDelegatorRegistration executed successfully, tx hash:", hash);
|
|
823
|
+
return hash;
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* Initiate delegator removal in the StakingVault
|
|
827
|
+
* @param client - The wallet client
|
|
828
|
+
* @param stakingVaultAddress - The StakingVault contract address
|
|
829
|
+
* @param delegationID - The delegation ID to remove
|
|
830
|
+
*/
|
|
831
|
+
async function initiateDelegatorRemovalStakingVault(client, stakingVault, delegationID) {
|
|
832
|
+
logger_1.logger.log("Initiating delegator removal in StakingVault...");
|
|
833
|
+
logger_1.logger.log("\n=== Delegator Removal Initiation Details ===");
|
|
834
|
+
logger_1.logger.log("Delegation ID:", delegationID);
|
|
835
|
+
logger_1.logger.log("Vault address:", stakingVault.address);
|
|
836
|
+
// Call initiateDelegatorRemoval (StakingVaultOperations version only takes delegationID)
|
|
837
|
+
const hash = await stakingVault.safeWrite.initiateDelegatorRemoval([
|
|
838
|
+
delegationID
|
|
839
|
+
]);
|
|
840
|
+
logger_1.logger.log("Initiate delegator removal tx hash:", hash);
|
|
841
|
+
// Wait for transaction confirmation
|
|
842
|
+
logger_1.logger.log("Waiting for transaction confirmation...");
|
|
843
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
844
|
+
logger_1.logger.log("Transaction confirmed in block:", receipt.blockNumber);
|
|
845
|
+
// Parse the delegator removal initiated event
|
|
846
|
+
try {
|
|
847
|
+
const delegatorRemovalInitiatedEvents = (0, viem_1.parseEventLogs)({
|
|
848
|
+
abi: stakingVault.abi,
|
|
849
|
+
eventName: 'StakingVault__DelegatorRemovalInitiated',
|
|
850
|
+
logs: receipt.logs,
|
|
851
|
+
});
|
|
852
|
+
if (delegatorRemovalInitiatedEvents.length > 0) {
|
|
853
|
+
const event = delegatorRemovalInitiatedEvents[0];
|
|
854
|
+
logger_1.logger.log("✅ Delegator removal initiated successfully!");
|
|
855
|
+
logger_1.logger.log("Delegation ID:", event.args?.delegationID || 'N/A');
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
logger_1.logger.log("✅ Delegator removal initiated successfully!");
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
catch (error) {
|
|
862
|
+
logger_1.logger.log("✅ Delegator removal initiated successfully!");
|
|
863
|
+
logger_1.logger.log("Note: Could not parse delegator removal initiated event");
|
|
864
|
+
}
|
|
865
|
+
return hash;
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* Force remove a delegator from the StakingVault (admin/emergency operation).
|
|
869
|
+
* @param client - The wallet client
|
|
870
|
+
* @param stakingVault - The StakingVault contract instance
|
|
871
|
+
* @param delegationID - The delegation ID to force remove
|
|
872
|
+
*/
|
|
873
|
+
async function forceRemoveDelegatorStakingVault(client, stakingVault, delegationID) {
|
|
874
|
+
logger_1.logger.log("Force removing delegator from StakingVault...");
|
|
875
|
+
logger_1.logger.log("\n=== Force Remove Delegator Details ===");
|
|
876
|
+
logger_1.logger.log("Delegation ID:", delegationID);
|
|
877
|
+
logger_1.logger.log("Vault address:", stakingVault.address);
|
|
878
|
+
const hash = await stakingVault.safeWrite.forceRemoveDelegator([delegationID]);
|
|
879
|
+
logger_1.logger.log("Force remove delegator tx hash:", hash);
|
|
880
|
+
logger_1.logger.log("Waiting for transaction confirmation...");
|
|
881
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
882
|
+
logger_1.logger.log("Transaction confirmed in block:", receipt.blockNumber);
|
|
883
|
+
logger_1.logger.log("✅ Delegator force-removed successfully!");
|
|
884
|
+
return hash;
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Complete delegator removal in the StakingVault
|
|
888
|
+
* @param client - The wallet client
|
|
889
|
+
* @param pchainClient - The P-Chain wallet client
|
|
890
|
+
* @param config - The config object
|
|
891
|
+
* @param stakingVault - The StakingVault contract instance
|
|
892
|
+
* @param validatorManager - The ValidatorManager contract instance
|
|
893
|
+
* @param initiateRemovalTxHash - The initiateDelegatorRemoval transaction hash
|
|
894
|
+
* @param waitValidatorVisible - Whether to wait for the validator to be removed from P-Chain
|
|
895
|
+
* @param delegationIDs - Optional delegation IDs to filter removals
|
|
896
|
+
* @param initiateTxHash - Optional initiate delegator registration transaction hash
|
|
897
|
+
*/
|
|
898
|
+
async function completeDelegatorRemovalStakingVault(pchainClient, config, stakingVault, validatorManager, initiateRemovalTxHash, delegationIDs, initiateTxHash) {
|
|
899
|
+
logger_1.logger.log("Completing delegator removal in StakingVault...");
|
|
900
|
+
const client = config.client;
|
|
901
|
+
// Wait for the initiate removal transaction to be confirmed
|
|
902
|
+
const receipt = await client.waitForTransactionReceipt({ hash: initiateRemovalTxHash, confirmations: 1 });
|
|
903
|
+
if (receipt.status === 'reverted')
|
|
904
|
+
throw new Error(`Transaction ${initiateRemovalTxHash} reverted, pls resend the removal transaction`);
|
|
905
|
+
// Parse StakingVault__DelegatorRemovalInitiated events from StakingVaultOperations
|
|
906
|
+
const delegatorRemovalInitiatedEvents = (0, viem_1.parseEventLogs)({
|
|
907
|
+
abi: stakingVault.abi,
|
|
908
|
+
logs: receipt.logs,
|
|
909
|
+
eventName: 'StakingVault__DelegatorRemovalInitiated'
|
|
910
|
+
});
|
|
911
|
+
if (delegatorRemovalInitiatedEvents.length === 0) {
|
|
912
|
+
logger_1.logger.error(console_log_colors_1.color.red("No StakingVault__DelegatorRemovalInitiated event found in the transaction logs, verify the transaction hash."));
|
|
913
|
+
process.exit(1);
|
|
914
|
+
}
|
|
915
|
+
// Filter by delegationIDs if provided
|
|
916
|
+
const filteredRemovals = delegationIDs
|
|
917
|
+
? delegatorRemovalInitiatedEvents.filter((e) => {
|
|
918
|
+
const delegationID = e.args?.delegationID;
|
|
919
|
+
return delegationID && delegationIDs.includes(delegationID);
|
|
920
|
+
})
|
|
921
|
+
: delegatorRemovalInitiatedEvents;
|
|
922
|
+
if (filteredRemovals.length === 0) {
|
|
923
|
+
logger_1.logger.error(console_log_colors_1.color.red("No matching StakingVault__DelegatorRemovalInitiated event found for the provided delegationIDs, verify the transaction hash and delegationIDs."));
|
|
924
|
+
process.exit(1);
|
|
925
|
+
}
|
|
926
|
+
// Get warp logs
|
|
927
|
+
const warpLogs = (0, viem_1.parseEventLogs)({
|
|
928
|
+
abi: config.abis.IWarpMessenger,
|
|
929
|
+
logs: receipt.logs,
|
|
930
|
+
});
|
|
931
|
+
let lastHash;
|
|
932
|
+
for (const event of filteredRemovals) {
|
|
933
|
+
const delegationID = event.args?.delegationID;
|
|
934
|
+
if (!delegationID) {
|
|
935
|
+
logger_1.logger.error(console_log_colors_1.color.red("No delegationID found in StakingVault__DelegatorRemovalInitiated event."));
|
|
936
|
+
continue;
|
|
937
|
+
}
|
|
938
|
+
// Get delegator info from StakingVault to get validationID
|
|
939
|
+
const delegatorInfo = await stakingVault.read.getDelegatorInfo([delegationID]);
|
|
940
|
+
const validationID = delegatorInfo.validationID;
|
|
941
|
+
// Get the validator info to get nodeID
|
|
942
|
+
const validator = await validatorManager.read.getValidator([validationID]);
|
|
943
|
+
const nodeID = (0, utils_1.encodeNodeID)(validator.nodeID);
|
|
944
|
+
logger_1.logger.log(`Processing removal for delegation ${delegationID}, node ${nodeID}`);
|
|
945
|
+
let addNodeBlockNumber = receipt.blockNumber;
|
|
946
|
+
if (initiateTxHash) {
|
|
947
|
+
const addNodeReceipt = await client.waitForTransactionReceipt({ hash: initiateTxHash, confirmations: 0 });
|
|
948
|
+
if (addNodeReceipt.status === 'reverted')
|
|
949
|
+
throw new Error(`Transaction ${initiateTxHash} reverted, pls use another initiate tx`);
|
|
950
|
+
// Check if this delegationID is in the registration event
|
|
951
|
+
const registrationEvents = (0, viem_1.parseEventLogs)({
|
|
952
|
+
abi: stakingVault.abi,
|
|
953
|
+
logs: addNodeReceipt.logs,
|
|
954
|
+
eventName: 'StakingVault__DelegatorRegistrationInitiated'
|
|
955
|
+
});
|
|
956
|
+
if (registrationEvents.some((e) => e.args?.delegationID === delegationID)) {
|
|
957
|
+
addNodeBlockNumber = addNodeReceipt.blockNumber;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
// Look for InitiatedValidatorWeightUpdate events from ValidatorManager (similar to completeWeightUpdate)
|
|
961
|
+
const initiatedValidatorWeightUpdates = (0, viem_1.parseEventLogs)({
|
|
962
|
+
abi: validatorManager.abi,
|
|
963
|
+
logs: receipt.logs,
|
|
964
|
+
eventName: 'InitiatedValidatorWeightUpdate'
|
|
965
|
+
}).filter((e) => e.args.validationID === validationID);
|
|
966
|
+
if (initiatedValidatorWeightUpdates.length === 0) {
|
|
967
|
+
logger_1.logger.error(console_log_colors_1.color.red(`No InitiatedValidatorWeightUpdate event found for validationID ${validationID}`));
|
|
968
|
+
continue;
|
|
969
|
+
}
|
|
970
|
+
const weightUpdateEvent = initiatedValidatorWeightUpdates[0];
|
|
971
|
+
const warpLog = warpLogs.find((w) => w.args.messageID === weightUpdateEvent.args.weightUpdateMessageID);
|
|
972
|
+
if (!warpLog) {
|
|
973
|
+
logger_1.logger.error(console_log_colors_1.color.red(`No matching warp log found for weightUpdateMessageID ${weightUpdateEvent.args.weightUpdateMessageID}`));
|
|
974
|
+
continue;
|
|
975
|
+
}
|
|
976
|
+
const signingSubnetId = await (0, warpUtils_1.getSigningSubnetIdFromWarpMessage)(client, warpLog.args.message);
|
|
977
|
+
const unsignedL1ValidatorWeightMessage = warpLog.args.message;
|
|
978
|
+
const weight = weightUpdateEvent.args.weight;
|
|
979
|
+
const nonce = weightUpdateEvent.args.nonce;
|
|
980
|
+
// Aggregate signatures from validators for the weight message
|
|
981
|
+
logger_1.logger.log("\nCollecting signatures for the L1ValidatorWeightMessage from the Validator Manager chain...");
|
|
982
|
+
const signedL1ValidatorWeightMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedL1ValidatorWeightMessage, signingSubnetId });
|
|
983
|
+
logger_1.logger.log("Aggregated signatures for the L1ValidatorWeightMessage from the Validator Manager chain");
|
|
984
|
+
// Call setValidatorWeight on the P-Chain with the signed L1ValidatorWeightMessage
|
|
985
|
+
logger_1.logger.log("\nSetting validator weight on P-Chain...");
|
|
986
|
+
(0, ts_belt_1.pipe)(await (0, pChainUtils_1.setValidatorWeight)({
|
|
987
|
+
client: pchainClient,
|
|
988
|
+
validationID: validationID,
|
|
989
|
+
message: signedL1ValidatorWeightMessage
|
|
990
|
+
}), ts_belt_1.R.tap(pChainSetWeightTxId => logger_1.logger.log("SetL1ValidatorWeightTx executed on P-Chain:", pChainSetWeightTxId)), ts_belt_1.R.tapError(err => {
|
|
991
|
+
if (!err.includes('warp message contains stale nonce')) {
|
|
992
|
+
logger_1.logger.error(err);
|
|
993
|
+
process.exit(1);
|
|
994
|
+
}
|
|
995
|
+
logger_1.logger.warn(console_log_colors_1.color.yellow(`Warning: Skipping SetL1ValidatorWeightTx for validationID ${validationID} due to stale nonce (already issued)`));
|
|
996
|
+
}));
|
|
997
|
+
// Pack and sign the P-Chain warp message for weight update
|
|
998
|
+
const validationIDBytes = (0, viem_1.hexToBytes)(validationID);
|
|
999
|
+
const unsignedPChainWarpMsg = (0, warpUtils_1.packL1ValidatorWeightMessage)(validationIDBytes, BigInt(nonce), BigInt(weight), client.network === 'fuji' ? 5 : 1, config_1.pChainChainID);
|
|
1000
|
+
const unsignedPChainWarpMsgHex = (0, viem_1.bytesToHex)(unsignedPChainWarpMsg);
|
|
1001
|
+
// Aggregate signatures from validators for the P-Chain weight message
|
|
1002
|
+
logger_1.logger.log("\nAggregating signatures for the L1ValidatorWeightMessage from the P-Chain...");
|
|
1003
|
+
const signedPChainMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedPChainWarpMsgHex, justification: unsignedPChainWarpMsgHex, signingSubnetId });
|
|
1004
|
+
logger_1.logger.log("Aggregated signatures for the L1ValidatorWeightMessage from the P-Chain");
|
|
1005
|
+
// Convert the signed warp message to bytes and pack into access list
|
|
1006
|
+
const signedPChainWarpMsgBytes = (0, viem_1.hexToBytes)(`0x${signedPChainMessage}`);
|
|
1007
|
+
const accessList = (0, warpUtils_1.packWarpIntoAccessList)(signedPChainWarpMsgBytes);
|
|
1008
|
+
// messageIndex is always 0 for StakingVaultOperations
|
|
1009
|
+
const messageIndex = 0;
|
|
1010
|
+
logger_1.logger.log("\nCalling function completeDelegatorRemoval...");
|
|
1011
|
+
const hash = await stakingVault.safeWrite.completeDelegatorRemoval([delegationID, messageIndex], {
|
|
1012
|
+
account: client.account,
|
|
1013
|
+
chain: null,
|
|
1014
|
+
accessList
|
|
1015
|
+
});
|
|
1016
|
+
logger_1.logger.log("completeDelegatorRemoval executed successfully, tx hash:", hash);
|
|
1017
|
+
lastHash = hash;
|
|
1018
|
+
}
|
|
1019
|
+
if (!lastHash) {
|
|
1020
|
+
throw new Error("No delegator removals processed");
|
|
1021
|
+
}
|
|
1022
|
+
return lastHash;
|
|
1023
|
+
}
|
|
1024
|
+
async function claimOperatorFees(stakingVault) {
|
|
1025
|
+
return stakingVault.safeWrite.claimOperatorFees([]);
|
|
1026
|
+
}
|
|
1027
|
+
async function claimEscrowedWithdrawal(stakingVault, recipient) {
|
|
1028
|
+
return stakingVault.safeWrite.claimEscrowedWithdrawal([recipient]);
|
|
1029
|
+
}
|
|
1030
|
+
function fmt(amount, decimals) {
|
|
1031
|
+
return (0, viem_1.formatUnits)(amount, decimals);
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
* General overview of the vault
|
|
1035
|
+
*/
|
|
1036
|
+
async function getGeneralInfo(stakingVault, client) {
|
|
1037
|
+
const [totalPooledStake, totalSupply, exchangeRate, availableStake, totalValidatorStake, totalDelegatedStake, pendingWithdrawals, claimableWithdrawals, inFlightExiting, currentEpoch, lastEpochProcessed, decimals, symbol, owner, paused,] = await stakingVault.multicall([
|
|
1038
|
+
'getTotalPooledStake', 'totalSupply', 'getExchangeRate', 'getAvailableStake',
|
|
1039
|
+
'getTotalValidatorStake', 'getTotalDelegatedStake', 'getPendingWithdrawals',
|
|
1040
|
+
'getClaimableWithdrawalStake', 'getInFlightExitingAmount', 'getCurrentEpoch',
|
|
1041
|
+
'getLastEpochProcessed', 'decimals', 'symbol', 'owner', 'paused',
|
|
1042
|
+
]);
|
|
1043
|
+
const contractBalance = await client.getBalance({ address: stakingVault.address });
|
|
1044
|
+
logger_1.logger.log(console_log_colors_1.color.bold(`\n═══ General Info ═══`));
|
|
1045
|
+
logger_1.logger.log(` Owner: ${owner}`);
|
|
1046
|
+
logger_1.logger.log(` Paused: ${paused}`);
|
|
1047
|
+
logger_1.logger.log(` Symbol: ${symbol}`);
|
|
1048
|
+
logger_1.logger.log(` Total Pooled Stake: ${fmt(totalPooledStake, decimals)} AVAX`);
|
|
1049
|
+
logger_1.logger.log(` Total Supply (LST): ${fmt(totalSupply, decimals)} ${symbol}`);
|
|
1050
|
+
logger_1.logger.log(` Exchange Rate: ${fmt(exchangeRate, decimals)}`);
|
|
1051
|
+
logger_1.logger.log(` Available Stake: ${fmt(availableStake, decimals)} AVAX`);
|
|
1052
|
+
logger_1.logger.log(` Total Validator Stake: ${fmt(totalValidatorStake, decimals)} AVAX`);
|
|
1053
|
+
logger_1.logger.log(` Total Delegated Stake: ${fmt(totalDelegatedStake, decimals)} AVAX`);
|
|
1054
|
+
logger_1.logger.log(` Pending Withdrawals: ${fmt(pendingWithdrawals, decimals)} AVAX`);
|
|
1055
|
+
logger_1.logger.log(` Claimable Withdrawals: ${fmt(claimableWithdrawals, decimals)} AVAX`);
|
|
1056
|
+
logger_1.logger.log(` In-Flight Exiting: ${fmt(inFlightExiting, decimals)} AVAX`);
|
|
1057
|
+
logger_1.logger.log(` Current Epoch: ${currentEpoch}`);
|
|
1058
|
+
logger_1.logger.log(` Last Epoch Processed: ${lastEpochProcessed}`);
|
|
1059
|
+
logger_1.logger.log(` Contract Balance: ${(0, viem_1.formatUnits)(contractBalance, 18)} AVAX`);
|
|
1060
|
+
}
|
|
1061
|
+
/**
|
|
1062
|
+
* Fees configuration
|
|
1063
|
+
*/
|
|
1064
|
+
async function getFeesInfo(stakingVault) {
|
|
1065
|
+
const [protocolFeeBips, protocolFeeRecipient, pendingProtocolFees, operatorFeeBips, totalAccruedOperatorFees, liquidityBufferBips, decimals,] = await stakingVault.multicall([
|
|
1066
|
+
'getProtocolFeeBips', 'getProtocolFeeRecipient', 'getPendingProtocolFees',
|
|
1067
|
+
'getOperatorFeeBips', 'getTotalAccruedOperatorFees', 'getLiquidityBufferBips', 'decimals',
|
|
1068
|
+
]);
|
|
1069
|
+
logger_1.logger.log(console_log_colors_1.color.bold(`\n═══ Fees Info ═══`));
|
|
1070
|
+
logger_1.logger.log(` Protocol Fee: ${protocolFeeBips} bips (${Number(protocolFeeBips) / 100}%)`);
|
|
1071
|
+
logger_1.logger.log(` Protocol Fee Recipient: ${protocolFeeRecipient}`);
|
|
1072
|
+
logger_1.logger.log(` Pending Protocol Fees: ${fmt(pendingProtocolFees, decimals)} AVAX`);
|
|
1073
|
+
logger_1.logger.log(` Operator Fee: ${operatorFeeBips} bips (${Number(operatorFeeBips) / 100}%)`);
|
|
1074
|
+
logger_1.logger.log(` Total Accrued Op. Fees: ${fmt(totalAccruedOperatorFees, decimals)} AVAX`);
|
|
1075
|
+
logger_1.logger.log(` Liquidity Buffer: ${liquidityBufferBips} bips (${Number(liquidityBufferBips) / 100}%)`);
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Operators overview
|
|
1079
|
+
*/
|
|
1080
|
+
async function getOperatorsInfo(stakingVault) {
|
|
1081
|
+
const [operatorList, maxOperators, maxValidatorsPerOp, decimals, symbol] = await stakingVault.multicall([
|
|
1082
|
+
'getOperatorList', 'getMaxOperators', 'getMaxValidatorsPerOperator', 'decimals', 'symbol',
|
|
1083
|
+
]);
|
|
1084
|
+
logger_1.logger.log(console_log_colors_1.color.bold(`\n═══ Operators Info ═══`));
|
|
1085
|
+
logger_1.logger.log(` Max Operators: ${maxOperators}`);
|
|
1086
|
+
logger_1.logger.log(` Max Validators/Operator: ${maxValidatorsPerOp}`);
|
|
1087
|
+
logger_1.logger.log(` Registered Operators: ${operatorList.length}`);
|
|
1088
|
+
let totalActive = 0;
|
|
1089
|
+
let totalAllocationBips = 0n;
|
|
1090
|
+
stakingVault.read.getOperatorCurrentEpochPendingAmount;
|
|
1091
|
+
for (const operator of operatorList) {
|
|
1092
|
+
const [info, exitDebt, validators, delegators] = await stakingVault.multicall([
|
|
1093
|
+
{ name: 'getOperatorInfo', args: [operator] },
|
|
1094
|
+
{ name: 'getOperatorExitDebt', args: [operator] },
|
|
1095
|
+
{ name: 'getOperatorValidators', args: [operator] },
|
|
1096
|
+
{ name: 'getOperatorDelegators', args: [operator] },
|
|
1097
|
+
]);
|
|
1098
|
+
if (info.active)
|
|
1099
|
+
totalActive++;
|
|
1100
|
+
totalAllocationBips += info.allocationBips;
|
|
1101
|
+
logger_1.logger.log(`\n ${console_log_colors_1.color.cyan(operator)}:`);
|
|
1102
|
+
logger_1.logger.log(` Active: ${info.active}`);
|
|
1103
|
+
logger_1.logger.log(` Allocation: ${info.allocationBips} bips (${Number(info.allocationBips) / 100}%)`);
|
|
1104
|
+
logger_1.logger.log(` Active Stake: ${fmt(info.activeStake, decimals)} AVAX`);
|
|
1105
|
+
logger_1.logger.log(` Accrued Fees: ${fmt(info.accruedFees, decimals)} AVAX`);
|
|
1106
|
+
logger_1.logger.log(` Fee Recipient: ${info.feeRecipient}`);
|
|
1107
|
+
logger_1.logger.log(` Exit Debt: ${fmt(exitDebt, decimals)} AVAX`);
|
|
1108
|
+
logger_1.logger.log(` Validators: ${validators.length}`);
|
|
1109
|
+
logger_1.logger.log(` Delegations: ${delegators.length}`);
|
|
1110
|
+
}
|
|
1111
|
+
logger_1.logger.log(`\n ── Summary ──`);
|
|
1112
|
+
logger_1.logger.log(` Active / Total: ${totalActive} / ${operatorList.length}`);
|
|
1113
|
+
logger_1.logger.log(` Total Allocation: ${totalAllocationBips} bips (${Number(totalAllocationBips) / 100}%)`);
|
|
1114
|
+
}
|
|
1115
|
+
/**
|
|
1116
|
+
* Validators details per operator
|
|
1117
|
+
*/
|
|
1118
|
+
async function getValidatorsInfo(stakingVault) {
|
|
1119
|
+
const [operatorList, totalValidatorStake, maxValidatorStake, decimals] = await stakingVault.multicall([
|
|
1120
|
+
'getOperatorList', 'getTotalValidatorStake', 'getMaximumValidatorStake', 'decimals',
|
|
1121
|
+
]);
|
|
1122
|
+
logger_1.logger.log(console_log_colors_1.color.bold(`\n═══ Validators Info ═══`));
|
|
1123
|
+
logger_1.logger.log(` Total Validator Stake: ${fmt(totalValidatorStake, decimals)} AVAX`);
|
|
1124
|
+
logger_1.logger.log(` Max Validator Stake: ${fmt(maxValidatorStake, decimals)} AVAX`);
|
|
1125
|
+
let totalValidators = 0;
|
|
1126
|
+
let totalPendingRemoval = 0;
|
|
1127
|
+
for (const operator of operatorList) {
|
|
1128
|
+
const [validatorIDs] = await stakingVault.multicall([
|
|
1129
|
+
{ name: 'getOperatorValidators', args: [operator] },
|
|
1130
|
+
]);
|
|
1131
|
+
if (validatorIDs.length === 0)
|
|
1132
|
+
continue;
|
|
1133
|
+
logger_1.logger.log(`\n Operator ${console_log_colors_1.color.cyan(operator)} (${validatorIDs.length} validators):`);
|
|
1134
|
+
// Batch all validator queries in a single multicall
|
|
1135
|
+
const queries = validatorIDs.flatMap(id => [
|
|
1136
|
+
{ name: 'getValidatorStakeAmount', args: [id] },
|
|
1137
|
+
{ name: 'isValidatorPendingRemoval', args: [id] },
|
|
1138
|
+
]);
|
|
1139
|
+
const results = await stakingVault.multicall(queries);
|
|
1140
|
+
for (let i = 0; i < validatorIDs.length; i++) {
|
|
1141
|
+
const stakeAmount = results[i * 2];
|
|
1142
|
+
const pendingRemoval = results[i * 2 + 1];
|
|
1143
|
+
totalValidators++;
|
|
1144
|
+
if (pendingRemoval)
|
|
1145
|
+
totalPendingRemoval++;
|
|
1146
|
+
logger_1.logger.log(` ${validatorIDs[i]}`);
|
|
1147
|
+
logger_1.logger.log(` Stake: ${fmt(stakeAmount, decimals)} AVAX`);
|
|
1148
|
+
logger_1.logger.log(` Pending Removal: ${pendingRemoval}`);
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
logger_1.logger.log(`\n ── Summary ──`);
|
|
1152
|
+
logger_1.logger.log(` Total Validators: ${totalValidators}`);
|
|
1153
|
+
logger_1.logger.log(` Pending Removal: ${totalPendingRemoval}`);
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* Delegations details per operator
|
|
1157
|
+
*/
|
|
1158
|
+
async function getDelegatorsInfo(stakingVault) {
|
|
1159
|
+
const [operatorList, totalDelegatedStake, maxDelegatorStake, decimals] = await stakingVault.multicall([
|
|
1160
|
+
'getOperatorList', 'getTotalDelegatedStake', 'getMaximumDelegatorStake', 'decimals',
|
|
1161
|
+
]);
|
|
1162
|
+
logger_1.logger.log(console_log_colors_1.color.bold(`\n═══ Delegators Info ═══`));
|
|
1163
|
+
logger_1.logger.log(` Total Delegated Stake: ${fmt(totalDelegatedStake, decimals)} AVAX`);
|
|
1164
|
+
logger_1.logger.log(` Max Delegator Stake: ${fmt(maxDelegatorStake, decimals)} AVAX`);
|
|
1165
|
+
let totalDelegations = 0;
|
|
1166
|
+
for (const operator of operatorList) {
|
|
1167
|
+
const [delegatorIDs] = await stakingVault.multicall([
|
|
1168
|
+
{ name: 'getOperatorDelegators', args: [operator] },
|
|
1169
|
+
]);
|
|
1170
|
+
if (delegatorIDs.length === 0)
|
|
1171
|
+
continue;
|
|
1172
|
+
logger_1.logger.log(`\n Operator ${console_log_colors_1.color.cyan(operator)} (${delegatorIDs.length} delegations):`);
|
|
1173
|
+
// Batch all delegator queries
|
|
1174
|
+
const queries = delegatorIDs.map(id => ({
|
|
1175
|
+
name: 'getDelegatorInfo',
|
|
1176
|
+
args: [id],
|
|
1177
|
+
}));
|
|
1178
|
+
const results = await stakingVault.multicall(queries);
|
|
1179
|
+
for (let i = 0; i < delegatorIDs.length; i++) {
|
|
1180
|
+
const info = results[i];
|
|
1181
|
+
totalDelegations++;
|
|
1182
|
+
logger_1.logger.log(` ${delegatorIDs[i]}`);
|
|
1183
|
+
logger_1.logger.log(` Target Validator: ${info.validationID}`);
|
|
1184
|
+
logger_1.logger.log(` Vault-Owned Validator: ${info.isVaultOwnedValidator}`);
|
|
1185
|
+
logger_1.logger.log(` Operator: ${info.operator}`);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
logger_1.logger.log(`\n ── Summary ──`);
|
|
1189
|
+
logger_1.logger.log(` Total Delegations: ${totalDelegations}`);
|
|
1190
|
+
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Withdrawal queue info
|
|
1193
|
+
*/
|
|
1194
|
+
async function getWithdrawalsInfo(stakingVault) {
|
|
1195
|
+
const [queueLength, queueHead, pendingWithdrawals, claimableWithdrawals, totalExitDebt, currentEpoch, lastEpochProcessed, epochDuration, decimals,] = await stakingVault.multicall([
|
|
1196
|
+
'getWithdrawalQueueLength', 'getQueueHead', 'getPendingWithdrawals', 'getClaimableWithdrawalStake',
|
|
1197
|
+
'getTotalExitDebt', 'getCurrentEpoch', 'getLastEpochProcessed', 'getEpochDuration', 'decimals',
|
|
1198
|
+
]);
|
|
1199
|
+
logger_1.logger.log(console_log_colors_1.color.bold(`\n═══ Withdrawals Info ═══`));
|
|
1200
|
+
logger_1.logger.log(` Queue Length: ${queueLength}`);
|
|
1201
|
+
logger_1.logger.log(` Queue Head: ${queueHead}`);
|
|
1202
|
+
logger_1.logger.log(` Pending Withdrawals: ${fmt(pendingWithdrawals, decimals)} AVAX`);
|
|
1203
|
+
logger_1.logger.log(` Claimable Withdrawals: ${fmt(claimableWithdrawals, decimals)} AVAX`);
|
|
1204
|
+
logger_1.logger.log(` Total Exit Debt: ${fmt(totalExitDebt, decimals)} AVAX`);
|
|
1205
|
+
logger_1.logger.log(` Current Epoch: ${currentEpoch}`);
|
|
1206
|
+
logger_1.logger.log(` Last Epoch Processed: ${lastEpochProcessed}`);
|
|
1207
|
+
logger_1.logger.log(` Epoch Duration: ${epochDuration}s`);
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Epoch info
|
|
1211
|
+
*/
|
|
1212
|
+
async function getEpochInfo(stakingVault) {
|
|
1213
|
+
const [currentEpoch, epochDuration, lastEpochProcessed, minStakeDuration] = await stakingVault.multicall([
|
|
1214
|
+
'getCurrentEpoch', 'getEpochDuration', 'getLastEpochProcessed', 'getMinimumStakeDuration',
|
|
1215
|
+
]);
|
|
1216
|
+
const epochsBehind = currentEpoch - lastEpochProcessed;
|
|
1217
|
+
logger_1.logger.log(console_log_colors_1.color.bold(`\n═══ Epoch Info ═══`));
|
|
1218
|
+
logger_1.logger.log(` Current Epoch: ${currentEpoch}`);
|
|
1219
|
+
logger_1.logger.log(` Epoch Duration: ${epochDuration}s`);
|
|
1220
|
+
logger_1.logger.log(` Last Epoch Processed: ${lastEpochProcessed}`);
|
|
1221
|
+
logger_1.logger.log(` Epochs Behind: ${epochsBehind}`);
|
|
1222
|
+
logger_1.logger.log(` Min Stake Duration: ${minStakeDuration}s`);
|
|
1223
|
+
}
|
|
1224
|
+
//# sourceMappingURL=stakingVault.js.map
|