@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,731 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateStakingConfig = updateStakingConfig;
|
|
4
|
+
exports.initiateValidatorRegistration = initiateValidatorRegistration;
|
|
5
|
+
exports.initiateDelegatorRegistration = initiateDelegatorRegistration;
|
|
6
|
+
exports.initiateDelegatorRemoval = initiateDelegatorRemoval;
|
|
7
|
+
exports.initiateValidatorRemoval = initiateValidatorRemoval;
|
|
8
|
+
exports.completeDelegatorRegistration = completeDelegatorRegistration;
|
|
9
|
+
exports.completeDelegatorRemoval = completeDelegatorRemoval;
|
|
10
|
+
exports.completeValidatorRegistration = completeValidatorRegistration;
|
|
11
|
+
exports.completeValidatorRemoval = completeValidatorRemoval;
|
|
12
|
+
exports.submitUptimeProof = submitUptimeProof;
|
|
13
|
+
exports.getKiteStakingManagerInfo = getKiteStakingManagerInfo;
|
|
14
|
+
exports.getValidatorFullInfo = getValidatorFullInfo;
|
|
15
|
+
exports.getDelegatorFullInfo = getDelegatorFullInfo;
|
|
16
|
+
const viem_1 = require("viem");
|
|
17
|
+
const config_1 = require("./config");
|
|
18
|
+
const utils_1 = require("./lib/utils");
|
|
19
|
+
const logger_1 = require("./lib/logger");
|
|
20
|
+
const console_log_colors_1 = require("console-log-colors");
|
|
21
|
+
const warpUtils_1 = require("./lib/warpUtils");
|
|
22
|
+
const pChainUtils_1 = require("./lib/pChainUtils");
|
|
23
|
+
const ts_belt_1 = require("@mobily/ts-belt");
|
|
24
|
+
const justification_1 = require("./lib/justification");
|
|
25
|
+
const avalanchejs_1 = require("@avalabs/avalanchejs");
|
|
26
|
+
const uptime_1 = require("./uptime");
|
|
27
|
+
async function updateStakingConfig(kiteStakingManager, minimumStakeAmount, maximumStakeAmount, minimumStakeDuration, minimumDelegationFeeBips, maximumStakeMultiplier) {
|
|
28
|
+
logger_1.logger.log("Updating staking config...");
|
|
29
|
+
const hash = await kiteStakingManager.safeWrite.updateStakingConfig([
|
|
30
|
+
minimumStakeAmount,
|
|
31
|
+
maximumStakeAmount,
|
|
32
|
+
minimumStakeDuration,
|
|
33
|
+
minimumDelegationFeeBips,
|
|
34
|
+
maximumStakeMultiplier
|
|
35
|
+
]);
|
|
36
|
+
logger_1.logger.log("updateStakingConfig executed successfully, tx hash:", hash);
|
|
37
|
+
return hash;
|
|
38
|
+
}
|
|
39
|
+
async function initiateValidatorRegistration(kiteStakingManager, nodeId, blsKey, remainingBalanceOwner, disableOwner, delegationFeeBips, minStakeDuration, rewardRecipient, initialStake) {
|
|
40
|
+
logger_1.logger.log("Initiating validator registration...");
|
|
41
|
+
// Parse NodeID to bytes32 format
|
|
42
|
+
const nodeIdHex32 = (0, utils_1.parseNodeID)(nodeId, false);
|
|
43
|
+
const hash = await kiteStakingManager.safeWrite.initiateValidatorRegistration([
|
|
44
|
+
nodeIdHex32,
|
|
45
|
+
blsKey,
|
|
46
|
+
{ threshold: remainingBalanceOwner[0], addresses: remainingBalanceOwner[1] },
|
|
47
|
+
{ threshold: disableOwner[0], addresses: disableOwner[1] },
|
|
48
|
+
delegationFeeBips,
|
|
49
|
+
minStakeDuration,
|
|
50
|
+
rewardRecipient
|
|
51
|
+
], {
|
|
52
|
+
value: initialStake,
|
|
53
|
+
chain: null
|
|
54
|
+
});
|
|
55
|
+
logger_1.logger.log("initiateValidatorRegistration executed successfully, tx hash:", hash);
|
|
56
|
+
return hash;
|
|
57
|
+
}
|
|
58
|
+
async function initiateDelegatorRegistration(kiteStakingManager, config, nodeId, rewardRecipient, stakeAmount) {
|
|
59
|
+
logger_1.logger.log("Initiating delegator registration...");
|
|
60
|
+
// Get ValidatorManager from settings
|
|
61
|
+
const settings = await kiteStakingManager.read.getStakingManagerSettings();
|
|
62
|
+
const validatorManager = await config.contracts.ValidatorManager(settings.manager);
|
|
63
|
+
// Parse NodeID to bytes format (20 bytes, no padding)
|
|
64
|
+
const nodeIdBytes = (0, utils_1.parseNodeID)(nodeId, false);
|
|
65
|
+
// Get validationID from ValidatorManager
|
|
66
|
+
const validationID = await validatorManager.read.getNodeValidationID([nodeIdBytes]);
|
|
67
|
+
const txHash = await kiteStakingManager.safeWrite.initiateDelegatorRegistration([
|
|
68
|
+
validationID,
|
|
69
|
+
rewardRecipient
|
|
70
|
+
], {
|
|
71
|
+
value: stakeAmount,
|
|
72
|
+
chain: null
|
|
73
|
+
});
|
|
74
|
+
logger_1.logger.log("initiateDelegatorRegistration executed successfully, tx hash:", txHash);
|
|
75
|
+
return txHash;
|
|
76
|
+
}
|
|
77
|
+
async function initiateDelegatorRemoval(kiteStakingManager, config, delegationID, includeUptimeProof, rpcUrl) {
|
|
78
|
+
logger_1.logger.log("Initiating delegator removal...");
|
|
79
|
+
const client = config.client;
|
|
80
|
+
// messageIndex is always 0 for KiteStakingManager
|
|
81
|
+
const messageIndex = 0;
|
|
82
|
+
// If uptime proof is required, fetch and pack it into access list
|
|
83
|
+
let accessList = undefined;
|
|
84
|
+
if (includeUptimeProof) {
|
|
85
|
+
if (!rpcUrl) {
|
|
86
|
+
logger_1.logger.error(console_log_colors_1.color.red("RPC URL is required when includeUptimeProof is true."));
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
// Get ValidatorManager from settings
|
|
90
|
+
const settings = await kiteStakingManager.read.getStakingManagerSettings();
|
|
91
|
+
const validatorManager = await config.contracts.ValidatorManager(settings.manager);
|
|
92
|
+
// Get delegator info to get validationID
|
|
93
|
+
const delegatorInfo = await kiteStakingManager.read.getDelegatorInfo([delegationID]);
|
|
94
|
+
const validationID = delegatorInfo.validationID;
|
|
95
|
+
// Get the validator info to get nodeID
|
|
96
|
+
const validator = await validatorManager.read.getValidator([validationID]);
|
|
97
|
+
const nodeId = (0, utils_1.encodeNodeID)(validator.nodeID);
|
|
98
|
+
// Get the uptime message
|
|
99
|
+
const warpNetworkID = client.network === 'fuji' ? 5 : 1;
|
|
100
|
+
const sourceChainID = avalanchejs_1.utils.base58check.encode((0, viem_1.hexToBytes)(settings.uptimeBlockchainID));
|
|
101
|
+
logger_1.logger.log("\nGetting validation uptime message...");
|
|
102
|
+
const signedUptimeMessage = await (0, uptime_1.getValidationUptimeMessage)(client, rpcUrl, nodeId, warpNetworkID, sourceChainID);
|
|
103
|
+
// Ensure signedUptimeMessage has 0x prefix
|
|
104
|
+
const signedUptimeMessageHex = signedUptimeMessage.startsWith('0x') ? signedUptimeMessage : `0x${signedUptimeMessage}`;
|
|
105
|
+
// Pack uptime message into access list
|
|
106
|
+
const signedUptimeMessageBytes = (0, viem_1.hexToBytes)(signedUptimeMessageHex);
|
|
107
|
+
const uptimeAccessList = (0, warpUtils_1.packWarpIntoAccessList)(signedUptimeMessageBytes);
|
|
108
|
+
accessList = [uptimeAccessList[0]];
|
|
109
|
+
}
|
|
110
|
+
const hash = await kiteStakingManager.safeWrite.initiateDelegatorRemoval([delegationID, includeUptimeProof, messageIndex], accessList ? {
|
|
111
|
+
account: client.account,
|
|
112
|
+
chain: null,
|
|
113
|
+
accessList
|
|
114
|
+
} : undefined);
|
|
115
|
+
logger_1.logger.log("initiateDelegatorRemoval executed successfully, tx hash:", hash);
|
|
116
|
+
return hash;
|
|
117
|
+
}
|
|
118
|
+
async function initiateValidatorRemoval(kiteStakingManager, config, nodeId, includeUptimeProof) {
|
|
119
|
+
logger_1.logger.log("Initiating validator removal...");
|
|
120
|
+
// Get ValidatorManager from settings
|
|
121
|
+
const settings = await kiteStakingManager.read.getStakingManagerSettings();
|
|
122
|
+
const validatorManager = await config.contracts.ValidatorManager(settings.manager);
|
|
123
|
+
// Parse NodeID to bytes format (20 bytes, no padding)
|
|
124
|
+
const nodeIdBytes = (0, utils_1.parseNodeID)(nodeId, false);
|
|
125
|
+
// Get validationID from ValidatorManager
|
|
126
|
+
const validationID = await validatorManager.read.getNodeValidationID([nodeIdBytes]);
|
|
127
|
+
// messageIndex is always 0 for KiteStakingManager
|
|
128
|
+
const messageIndex = 0;
|
|
129
|
+
const hash = await kiteStakingManager.safeWrite.initiateValidatorRemoval([
|
|
130
|
+
validationID,
|
|
131
|
+
includeUptimeProof,
|
|
132
|
+
messageIndex
|
|
133
|
+
]);
|
|
134
|
+
logger_1.logger.log("initiateValidatorRemoval executed successfully, tx hash:", hash);
|
|
135
|
+
return hash;
|
|
136
|
+
}
|
|
137
|
+
async function completeDelegatorRegistration(pchainClient, kiteStakingManager, config, initiateTxHash, rpcUrl) {
|
|
138
|
+
logger_1.logger.log("Completing delegator registration...");
|
|
139
|
+
const client = config.client;
|
|
140
|
+
// Wait for the initiate delegator registration transaction to be confirmed
|
|
141
|
+
const receipt = await client.waitForTransactionReceipt({ hash: initiateTxHash, confirmations: 1 });
|
|
142
|
+
if (receipt.status === 'reverted')
|
|
143
|
+
throw new Error(`Transaction ${initiateTxHash} reverted, pls resend the initiate delegator registration transaction`);
|
|
144
|
+
// Get ValidatorManager from settings
|
|
145
|
+
const settings = await kiteStakingManager.read.getStakingManagerSettings();
|
|
146
|
+
const validatorManager = await config.contracts.ValidatorManager(settings.manager);
|
|
147
|
+
// Parse InitiatedDelegatorRegistration event from KiteStakingManager
|
|
148
|
+
const initiatedDelegatorRegistration = (0, viem_1.parseEventLogs)({
|
|
149
|
+
abi: kiteStakingManager.abi,
|
|
150
|
+
logs: receipt.logs,
|
|
151
|
+
eventName: 'InitiatedDelegatorRegistration'
|
|
152
|
+
})[0];
|
|
153
|
+
if (!initiatedDelegatorRegistration) {
|
|
154
|
+
logger_1.logger.error(console_log_colors_1.color.red("No InitiatedDelegatorRegistration event found in the transaction logs, verify the transaction hash."));
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
const delegationID = initiatedDelegatorRegistration.args.delegationID;
|
|
158
|
+
const validationID = initiatedDelegatorRegistration.args.validationID;
|
|
159
|
+
const validatorWeight = initiatedDelegatorRegistration.args.validatorWeight;
|
|
160
|
+
const nonce = initiatedDelegatorRegistration.args.nonce;
|
|
161
|
+
const setWeightMessageID = initiatedDelegatorRegistration.args.setWeightMessageID;
|
|
162
|
+
// Get the validator info to get nodeID
|
|
163
|
+
const validator = await validatorManager.read.getValidator([validationID]);
|
|
164
|
+
const nodeId = (0, utils_1.encodeNodeID)(validator.nodeID);
|
|
165
|
+
// Get warp logs to find the weight message
|
|
166
|
+
const warpLogs = (0, viem_1.parseEventLogs)({
|
|
167
|
+
abi: config.abis.IWarpMessenger,
|
|
168
|
+
logs: receipt.logs,
|
|
169
|
+
});
|
|
170
|
+
const signingSubnetId = await (0, warpUtils_1.getSigningSubnetIdFromWarpMessage)(client, warpLogs[0].args.message);
|
|
171
|
+
const weightWarpLog = warpLogs.find((w) => w.args.messageID === setWeightMessageID);
|
|
172
|
+
if (!weightWarpLog) {
|
|
173
|
+
logger_1.logger.error(console_log_colors_1.color.red("No matching warp message found for setWeightMessageID, verify the transaction hash."));
|
|
174
|
+
process.exit(1);
|
|
175
|
+
}
|
|
176
|
+
// Get the unsigned L1ValidatorWeightMessage
|
|
177
|
+
const unsignedL1ValidatorWeightMessage = weightWarpLog.args.message;
|
|
178
|
+
// Aggregate signatures from validators for the weight message
|
|
179
|
+
logger_1.logger.log("\nCollecting signatures for the L1ValidatorWeightMessage from the Validator Manager chain...");
|
|
180
|
+
const signedL1ValidatorWeightMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedL1ValidatorWeightMessage, signingSubnetId });
|
|
181
|
+
logger_1.logger.log("Aggregated signatures for the L1ValidatorWeightMessage from the Validator Manager chain");
|
|
182
|
+
// Call setValidatorWeight on the P-Chain with the signed L1ValidatorWeightMessage
|
|
183
|
+
logger_1.logger.log("\nSetting validator weight on P-Chain...");
|
|
184
|
+
(0, ts_belt_1.pipe)(await (0, pChainUtils_1.setValidatorWeight)({
|
|
185
|
+
client: pchainClient,
|
|
186
|
+
validationID: validationID,
|
|
187
|
+
message: signedL1ValidatorWeightMessage
|
|
188
|
+
}), ts_belt_1.R.tap(pChainSetWeightTxId => logger_1.logger.log("SetL1ValidatorWeightTx executed on P-Chain:", pChainSetWeightTxId)), ts_belt_1.R.tapError(err => {
|
|
189
|
+
if (!err.includes('warp message contains stale nonce')) {
|
|
190
|
+
logger_1.logger.error(err);
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
logger_1.logger.warn(console_log_colors_1.color.yellow(`Warning: Skipping SetL1ValidatorWeightTx for validationID ${validationID} due to stale nonce (already issued)`));
|
|
194
|
+
}));
|
|
195
|
+
// Pack and sign the P-Chain warp message for weight update
|
|
196
|
+
const validationIDBytes = (0, viem_1.hexToBytes)(validationID);
|
|
197
|
+
const unsignedPChainWeightWarpMsg = (0, warpUtils_1.packL1ValidatorWeightMessage)(validationIDBytes, BigInt(nonce), BigInt(validatorWeight), client.network === 'fuji' ? 5 : 1, config_1.pChainChainID);
|
|
198
|
+
const unsignedPChainWeightWarpMsgHex = (0, viem_1.bytesToHex)(unsignedPChainWeightWarpMsg);
|
|
199
|
+
// Aggregate signatures from validators for the P-Chain weight message
|
|
200
|
+
logger_1.logger.log("\nAggregating signatures for the L1ValidatorWeightMessage from the P-Chain...");
|
|
201
|
+
const signedPChainWeightMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedPChainWeightWarpMsgHex, signingSubnetId });
|
|
202
|
+
logger_1.logger.log("Aggregated signatures for the L1ValidatorWeightMessage from the P-Chain");
|
|
203
|
+
// Get the uptime message
|
|
204
|
+
const warpNetworkID = client.network === 'fuji' ? 5 : 1;
|
|
205
|
+
const sourceChainID = avalanchejs_1.utils.base58check.encode((0, viem_1.hexToBytes)(settings.uptimeBlockchainID));
|
|
206
|
+
logger_1.logger.log("\nGetting validation uptime message...");
|
|
207
|
+
const signedUptimeMessage = await (0, uptime_1.getValidationUptimeMessage)(client, rpcUrl, nodeId, warpNetworkID, sourceChainID);
|
|
208
|
+
// Ensure signedUptimeMessage has 0x prefix
|
|
209
|
+
const signedUptimeMessageHex = signedUptimeMessage.startsWith('0x') ? signedUptimeMessage : `0x${signedUptimeMessage}`;
|
|
210
|
+
// Pack both messages into access list
|
|
211
|
+
// Convert both signed messages to bytes
|
|
212
|
+
const signedPChainWeightWarpMsgBytes = (0, viem_1.hexToBytes)(`0x${signedPChainWeightMessage}`);
|
|
213
|
+
const signedUptimeMessageBytes = (0, viem_1.hexToBytes)(signedUptimeMessageHex);
|
|
214
|
+
// Pack both messages into separate access list objects
|
|
215
|
+
const weightAccessList = (0, warpUtils_1.packWarpIntoAccessList)(signedPChainWeightWarpMsgBytes);
|
|
216
|
+
const uptimeAccessList = (0, warpUtils_1.packWarpIntoAccessList)(signedUptimeMessageBytes);
|
|
217
|
+
// Combine access lists as two separate objects in the array
|
|
218
|
+
const combinedAccessList = [
|
|
219
|
+
weightAccessList[0],
|
|
220
|
+
uptimeAccessList[0]
|
|
221
|
+
];
|
|
222
|
+
// messageIndex is always 0 for KiteStakingManager
|
|
223
|
+
const messageIndex = 0;
|
|
224
|
+
const uptimeMessageIndex = 1;
|
|
225
|
+
logger_1.logger.log("\nCalling function completeDelegatorRegistration...");
|
|
226
|
+
const hash = await kiteStakingManager.safeWrite.completeDelegatorRegistration([delegationID, messageIndex, uptimeMessageIndex], {
|
|
227
|
+
account: client.account,
|
|
228
|
+
chain: null,
|
|
229
|
+
accessList: combinedAccessList
|
|
230
|
+
});
|
|
231
|
+
logger_1.logger.log("completeDelegatorRegistration executed successfully, tx hash:", hash);
|
|
232
|
+
return hash;
|
|
233
|
+
}
|
|
234
|
+
async function completeDelegatorRemoval(pchainClient, kiteStakingManager, config, initiateRemovalTxHash, rpcUrl, waitValidatorVisible, delegationIDs, initiateTxHash) {
|
|
235
|
+
logger_1.logger.log("Completing delegator removal...");
|
|
236
|
+
const client = config.client;
|
|
237
|
+
// Wait for the initiate removal transaction to be confirmed
|
|
238
|
+
const receipt = await client.waitForTransactionReceipt({ hash: initiateRemovalTxHash, confirmations: 1 });
|
|
239
|
+
if (receipt.status === 'reverted')
|
|
240
|
+
throw new Error(`Transaction ${initiateRemovalTxHash} reverted, pls resend the removal transaction`);
|
|
241
|
+
// Get ValidatorManager from settings
|
|
242
|
+
const settings = await kiteStakingManager.read.getStakingManagerSettings();
|
|
243
|
+
const validatorManager = await config.contracts.ValidatorManager(settings.manager);
|
|
244
|
+
// Parse InitiatedDelegatorRemoval events from KiteStakingManager
|
|
245
|
+
const initiatedDelegatorRemovals = (0, viem_1.parseEventLogs)({
|
|
246
|
+
abi: kiteStakingManager.abi,
|
|
247
|
+
logs: receipt.logs,
|
|
248
|
+
eventName: 'InitiatedDelegatorRemoval'
|
|
249
|
+
});
|
|
250
|
+
if (initiatedDelegatorRemovals.length === 0) {
|
|
251
|
+
logger_1.logger.error(console_log_colors_1.color.red("No InitiatedDelegatorRemoval event found in the transaction logs, verify the transaction hash."));
|
|
252
|
+
process.exit(1);
|
|
253
|
+
}
|
|
254
|
+
// Filter by delegationIDs if provided
|
|
255
|
+
const filteredRemovals = delegationIDs
|
|
256
|
+
? initiatedDelegatorRemovals.filter((e) => {
|
|
257
|
+
const delegationID = e.args.delegationID;
|
|
258
|
+
return delegationIDs.includes(delegationID);
|
|
259
|
+
})
|
|
260
|
+
: initiatedDelegatorRemovals;
|
|
261
|
+
if (filteredRemovals.length === 0) {
|
|
262
|
+
logger_1.logger.error(console_log_colors_1.color.red("No matching InitiatedDelegatorRemoval event found for the provided delegationIDs, verify the transaction hash and delegationIDs."));
|
|
263
|
+
process.exit(1);
|
|
264
|
+
}
|
|
265
|
+
// Get warp logs
|
|
266
|
+
const warpLogs = (0, viem_1.parseEventLogs)({
|
|
267
|
+
abi: config.abis.IWarpMessenger,
|
|
268
|
+
logs: receipt.logs,
|
|
269
|
+
});
|
|
270
|
+
let lastHash;
|
|
271
|
+
for (const event of filteredRemovals) {
|
|
272
|
+
const delegationID = event.args.delegationID;
|
|
273
|
+
const validationID = event.args.validationID;
|
|
274
|
+
// Get the validator info to get nodeID
|
|
275
|
+
const validator = await validatorManager.read.getValidator([validationID]);
|
|
276
|
+
const nodeID = (0, utils_1.encodeNodeID)(validator.nodeID);
|
|
277
|
+
logger_1.logger.log(`Processing removal for delegation ${delegationID}, node ${nodeID}`);
|
|
278
|
+
// Get delegator info to find the registration block number
|
|
279
|
+
const delegatorInfo = await kiteStakingManager.read.getDelegatorInfo([delegationID]);
|
|
280
|
+
let addNodeBlockNumber = receipt.blockNumber;
|
|
281
|
+
if (initiateTxHash) {
|
|
282
|
+
const addNodeReceipt = await client.waitForTransactionReceipt({ hash: initiateTxHash, confirmations: 0 });
|
|
283
|
+
if (addNodeReceipt.status === 'reverted')
|
|
284
|
+
throw new Error(`Transaction ${initiateTxHash} reverted, pls use another initiate tx`);
|
|
285
|
+
// Check if this delegationID is in the registration event
|
|
286
|
+
const registrationEvents = (0, viem_1.parseEventLogs)({
|
|
287
|
+
abi: kiteStakingManager.abi,
|
|
288
|
+
logs: addNodeReceipt.logs,
|
|
289
|
+
eventName: 'InitiatedDelegatorRegistration'
|
|
290
|
+
});
|
|
291
|
+
if (registrationEvents.some((e) => e.args.delegationID === delegationID)) {
|
|
292
|
+
addNodeBlockNumber = addNodeReceipt.blockNumber;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
// Look for InitiatedValidatorWeightUpdate events from ValidatorManager (similar to completeWeightUpdate)
|
|
296
|
+
const initiatedValidatorWeightUpdates = (0, viem_1.parseEventLogs)({
|
|
297
|
+
abi: validatorManager.abi,
|
|
298
|
+
logs: receipt.logs,
|
|
299
|
+
eventName: 'InitiatedValidatorWeightUpdate'
|
|
300
|
+
}).filter((e) => e.args.validationID === validationID);
|
|
301
|
+
if (initiatedValidatorWeightUpdates.length === 0) {
|
|
302
|
+
logger_1.logger.error(console_log_colors_1.color.red(`No InitiatedValidatorWeightUpdate event found for validationID ${validationID}`));
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
const weightUpdateEvent = initiatedValidatorWeightUpdates[0];
|
|
306
|
+
const warpLog = warpLogs.find((w) => w.args.messageID === weightUpdateEvent.args.weightUpdateMessageID);
|
|
307
|
+
if (!warpLog) {
|
|
308
|
+
logger_1.logger.error(console_log_colors_1.color.red(`No matching warp log found for weightUpdateMessageID ${weightUpdateEvent.args.weightUpdateMessageID}`));
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
const unsignedL1ValidatorWeightMessage = warpLog.args.message;
|
|
312
|
+
const weight = weightUpdateEvent.args.weight;
|
|
313
|
+
const nonce = weightUpdateEvent.args.nonce;
|
|
314
|
+
const signingSubnetId = await (0, warpUtils_1.getSigningSubnetIdFromWarpMessage)(client, unsignedL1ValidatorWeightMessage);
|
|
315
|
+
// Aggregate signatures from validators for the weight message
|
|
316
|
+
logger_1.logger.log("\nCollecting signatures for the L1ValidatorWeightMessage from the Validator Manager chain...");
|
|
317
|
+
const signedL1ValidatorWeightMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedL1ValidatorWeightMessage, signingSubnetId });
|
|
318
|
+
logger_1.logger.log("Aggregated signatures for the L1ValidatorWeightMessage from the Validator Manager chain");
|
|
319
|
+
// Call setValidatorWeight on the P-Chain with the signed L1ValidatorWeightMessage
|
|
320
|
+
logger_1.logger.log("\nSetting validator weight on P-Chain...");
|
|
321
|
+
(0, ts_belt_1.pipe)(await (0, pChainUtils_1.setValidatorWeight)({
|
|
322
|
+
client: pchainClient,
|
|
323
|
+
validationID: validationID,
|
|
324
|
+
message: signedL1ValidatorWeightMessage
|
|
325
|
+
}), ts_belt_1.R.tap(pChainSetWeightTxId => logger_1.logger.log("SetL1ValidatorWeightTx executed on P-Chain:", pChainSetWeightTxId)), ts_belt_1.R.tapError(err => {
|
|
326
|
+
if (!err.includes('warp message contains stale nonce')) {
|
|
327
|
+
logger_1.logger.error(err);
|
|
328
|
+
process.exit(1);
|
|
329
|
+
}
|
|
330
|
+
logger_1.logger.warn(console_log_colors_1.color.yellow(`Warning: Skipping SetL1ValidatorWeightTx for validationID ${validationID} due to stale nonce (already issued)`));
|
|
331
|
+
}));
|
|
332
|
+
// Pack and sign the P-Chain warp message for weight update
|
|
333
|
+
const validationIDBytes = (0, viem_1.hexToBytes)(validationID);
|
|
334
|
+
const unsignedPChainWarpMsg = (0, warpUtils_1.packL1ValidatorWeightMessage)(validationIDBytes, BigInt(nonce), BigInt(weight), client.network === 'fuji' ? 5 : 1, config_1.pChainChainID);
|
|
335
|
+
const unsignedPChainWarpMsgHex = (0, viem_1.bytesToHex)(unsignedPChainWarpMsg);
|
|
336
|
+
// Aggregate signatures from validators for the P-Chain weight message
|
|
337
|
+
logger_1.logger.log("\nAggregating signatures for the L1ValidatorWeightMessage from the P-Chain...");
|
|
338
|
+
const signedPChainMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedPChainWarpMsgHex, signingSubnetId });
|
|
339
|
+
logger_1.logger.log("Aggregated signatures for the L1ValidatorWeightMessage from the P-Chain");
|
|
340
|
+
// Convert the signed warp message to bytes and pack into access list
|
|
341
|
+
const signedPChainWarpMsgBytes = (0, viem_1.hexToBytes)(`0x${signedPChainMessage}`);
|
|
342
|
+
const accessList = (0, warpUtils_1.packWarpIntoAccessList)(signedPChainWarpMsgBytes);
|
|
343
|
+
// messageIndex is always 0 for KiteStakingManager
|
|
344
|
+
const messageIndex = 0;
|
|
345
|
+
logger_1.logger.log("\nCalling function completeDelegatorRemoval...");
|
|
346
|
+
const hash = await kiteStakingManager.safeWrite.completeDelegatorRemoval([delegationID, messageIndex], {
|
|
347
|
+
account: client.account,
|
|
348
|
+
chain: null,
|
|
349
|
+
accessList
|
|
350
|
+
});
|
|
351
|
+
if (waitValidatorVisible) {
|
|
352
|
+
const subnetIDHex = await validatorManager.read.subnetID();
|
|
353
|
+
logger_1.logger.log("Waiting for the validator to be removed from the P-Chain (may take a while)...");
|
|
354
|
+
await (0, utils_1.retryWhileError)(async () => (await (0, pChainUtils_1.getCurrentValidators)(client, avalanchejs_1.utils.base58check.encode((0, viem_1.hexToBytes)(subnetIDHex)))).some((v) => v.nodeID === nodeID), 5000, 180000, (res) => res === false);
|
|
355
|
+
}
|
|
356
|
+
logger_1.logger.log("completeDelegatorRemoval executed successfully, tx hash:", hash);
|
|
357
|
+
lastHash = hash;
|
|
358
|
+
}
|
|
359
|
+
if (!lastHash) {
|
|
360
|
+
throw new Error("No delegator removals processed");
|
|
361
|
+
}
|
|
362
|
+
return lastHash;
|
|
363
|
+
}
|
|
364
|
+
async function completeValidatorRegistration(pchainClient, kiteStakingManager, config, blsProofOfPossession, initiateTxHash, initialBalance, waitValidatorVisible) {
|
|
365
|
+
logger_1.logger.log("Completing validator registration...");
|
|
366
|
+
const client = config.client;
|
|
367
|
+
// Wait for transaction receipt to extract warp message and validation ID
|
|
368
|
+
const receipt = await client.waitForTransactionReceipt({ hash: initiateTxHash });
|
|
369
|
+
// Parse InitiatedStakingValidatorRegistration event from KiteStakingManager
|
|
370
|
+
const initiatedStakingRegistration = (0, viem_1.parseEventLogs)({
|
|
371
|
+
abi: kiteStakingManager.abi,
|
|
372
|
+
logs: receipt.logs,
|
|
373
|
+
eventName: 'InitiatedStakingValidatorRegistration'
|
|
374
|
+
})[0];
|
|
375
|
+
if (!initiatedStakingRegistration) {
|
|
376
|
+
logger_1.logger.error(console_log_colors_1.color.red("No InitiatedStakingValidatorRegistration event found in the transaction logs, verify the transaction hash."));
|
|
377
|
+
process.exit(1);
|
|
378
|
+
}
|
|
379
|
+
// Get ValidatorManager from settings
|
|
380
|
+
const settings = await kiteStakingManager.read.getStakingManagerSettings();
|
|
381
|
+
const validatorManager = await config.contracts.ValidatorManager(settings.manager);
|
|
382
|
+
// Parse InitiatedValidatorRegistration event from ValidatorManager
|
|
383
|
+
const initiatedValidatorRegistration = (0, viem_1.parseEventLogs)({
|
|
384
|
+
abi: validatorManager.abi,
|
|
385
|
+
logs: receipt.logs,
|
|
386
|
+
eventName: 'InitiatedValidatorRegistration'
|
|
387
|
+
})[0];
|
|
388
|
+
if (!initiatedValidatorRegistration) {
|
|
389
|
+
logger_1.logger.error(console_log_colors_1.color.red("No InitiatedValidatorRegistration event found in the transaction logs, verify the transaction hash."));
|
|
390
|
+
process.exit(1);
|
|
391
|
+
}
|
|
392
|
+
// messageIndex is always 0 for KiteStakingManager
|
|
393
|
+
const messageIndex = 0;
|
|
394
|
+
const warpLogs = (0, viem_1.parseEventLogs)({
|
|
395
|
+
abi: config.abis.IWarpMessenger,
|
|
396
|
+
logs: receipt.logs,
|
|
397
|
+
})[0];
|
|
398
|
+
if (!warpLogs) {
|
|
399
|
+
logger_1.logger.error(console_log_colors_1.color.red("No IWarpMessenger event found in the transaction logs."));
|
|
400
|
+
process.exit(1);
|
|
401
|
+
}
|
|
402
|
+
const signingSubnetId = await (0, warpUtils_1.getSigningSubnetIdFromWarpMessage)(client, warpLogs.args.message);
|
|
403
|
+
const validationIDHex = initiatedValidatorRegistration.args.validationID;
|
|
404
|
+
const nodeId = (0, utils_1.encodeNodeID)(initiatedValidatorRegistration.args.nodeID); // Convert bytes20 to NodeID format
|
|
405
|
+
// Check if the node is still registered as a validator on the P-Chain
|
|
406
|
+
const subnetIDHex = await validatorManager.read.subnetID();
|
|
407
|
+
const subnetID = avalanchejs_1.utils.base58check.encode((0, viem_1.hexToBytes)(subnetIDHex));
|
|
408
|
+
const isValidator = (await (0, pChainUtils_1.getCurrentValidators)(client, subnetID)).some((v) => v.nodeID === nodeId);
|
|
409
|
+
if (isValidator) {
|
|
410
|
+
logger_1.logger.log(console_log_colors_1.color.yellow("Node is already registered as a validator on the P-Chain, skipping registerL1Validator call."));
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
// Get the unsigned warp message from the receipt
|
|
414
|
+
const RegisterL1ValidatorUnsignedWarpMsg = warpLogs.args.message;
|
|
415
|
+
// Collect signatures for the warp message
|
|
416
|
+
logger_1.logger.log("\nCollecting signatures for the L1ValidatorRegistrationMessage from the Validator Manager chain...");
|
|
417
|
+
const signedMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: RegisterL1ValidatorUnsignedWarpMsg, signingSubnetId });
|
|
418
|
+
// Register validator on P-Chain
|
|
419
|
+
logger_1.logger.log("\nRegistering validator on P-Chain...");
|
|
420
|
+
(0, ts_belt_1.pipe)(await (0, pChainUtils_1.registerL1Validator)({
|
|
421
|
+
client: pchainClient,
|
|
422
|
+
blsProofOfPossession: blsProofOfPossession,
|
|
423
|
+
signedMessage,
|
|
424
|
+
initialBalance: initialBalance
|
|
425
|
+
}), 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); }));
|
|
426
|
+
}
|
|
427
|
+
// Pack and sign the P-Chain warp message
|
|
428
|
+
const validationIDBytes = (0, viem_1.hexToBytes)(validationIDHex);
|
|
429
|
+
const unsignedPChainWarpMsg = (0, warpUtils_1.packL1ValidatorRegistration)(validationIDBytes, true, client.network === 'fuji' ? 5 : 1, config_1.pChainChainID);
|
|
430
|
+
const unsignedPChainWarpMsgHex = (0, viem_1.bytesToHex)(unsignedPChainWarpMsg);
|
|
431
|
+
// Aggregate signatures from validators
|
|
432
|
+
logger_1.logger.log("\nAggregating signatures for the L1ValidatorRegistrationMessage from the P-Chain...");
|
|
433
|
+
const signedPChainMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedPChainWarpMsgHex, signingSubnetId });
|
|
434
|
+
// Convert the signed warp message to bytes and pack into access list
|
|
435
|
+
const signedPChainWarpMsgBytes = (0, viem_1.hexToBytes)(`0x${signedPChainMessage}`);
|
|
436
|
+
const accessList = (0, warpUtils_1.packWarpIntoAccessList)(signedPChainWarpMsgBytes);
|
|
437
|
+
logger_1.logger.log("\nCalling function completeValidatorRegistration...");
|
|
438
|
+
const hash = await kiteStakingManager.safeWrite.completeValidatorRegistration([messageIndex], {
|
|
439
|
+
account: client.account,
|
|
440
|
+
chain: null,
|
|
441
|
+
accessList
|
|
442
|
+
});
|
|
443
|
+
// Wait until the validator is visible on the P-Chain
|
|
444
|
+
if (waitValidatorVisible) {
|
|
445
|
+
logger_1.logger.log("Waiting for the validator to be visible on the P-Chain (may take a while)...");
|
|
446
|
+
await (0, utils_1.retryWhileError)(async () => (await (0, pChainUtils_1.getCurrentValidators)(client, avalanchejs_1.utils.base58check.encode((0, viem_1.hexToBytes)(subnetIDHex)))).some((v) => v.nodeID === nodeId), 5000, 180000, (res) => res === true);
|
|
447
|
+
}
|
|
448
|
+
logger_1.logger.log("completeValidatorRegistration executed successfully, tx hash:", hash);
|
|
449
|
+
return hash;
|
|
450
|
+
}
|
|
451
|
+
async function completeValidatorRemoval(pchainClient, kiteStakingManager, config, initiateRemovalTxHash, waitValidatorVisible, nodeIDs, initiateTxHash) {
|
|
452
|
+
logger_1.logger.log("Completing validator removal...");
|
|
453
|
+
const client = config.client;
|
|
454
|
+
// Wait for the initiate removal transaction to be confirmed
|
|
455
|
+
const receipt = await client.waitForTransactionReceipt({ hash: initiateRemovalTxHash, confirmations: 1 });
|
|
456
|
+
if (receipt.status === 'reverted')
|
|
457
|
+
throw new Error(`Transaction ${initiateRemovalTxHash} reverted, pls resend the removal transaction`);
|
|
458
|
+
// Get ValidatorManager from settings
|
|
459
|
+
const settings = await kiteStakingManager.read.getStakingManagerSettings();
|
|
460
|
+
const validatorManager = await config.contracts.ValidatorManager(settings.manager);
|
|
461
|
+
// Parse InitiatedValidatorRemoval events from ValidatorManager
|
|
462
|
+
const initiatedValidatorRemovals = (0, viem_1.parseEventLogs)({
|
|
463
|
+
abi: validatorManager.abi,
|
|
464
|
+
logs: receipt.logs,
|
|
465
|
+
eventName: 'InitiatedValidatorRemoval'
|
|
466
|
+
});
|
|
467
|
+
if (initiatedValidatorRemovals.length === 0) {
|
|
468
|
+
logger_1.logger.error(console_log_colors_1.color.red("No InitiatedValidatorRemoval event found in the transaction logs, verify the transaction hash."));
|
|
469
|
+
process.exit(1);
|
|
470
|
+
}
|
|
471
|
+
// Filter by nodeIDs if provided
|
|
472
|
+
// Note: InitiatedValidatorRemoval event doesn't include nodeID, so we need to get it from the validator
|
|
473
|
+
const filteredRemovals = nodeIDs
|
|
474
|
+
? (await Promise.all(initiatedValidatorRemovals.map(async (e) => {
|
|
475
|
+
const validator = await validatorManager.read.getValidator([e.args.validationID]);
|
|
476
|
+
const nodeId = (0, utils_1.encodeNodeID)(validator.nodeID);
|
|
477
|
+
return { event: e, nodeId };
|
|
478
|
+
}))).filter(({ nodeId }) => nodeIDs.includes(nodeId)).map(({ event }) => event)
|
|
479
|
+
: initiatedValidatorRemovals;
|
|
480
|
+
if (filteredRemovals.length === 0) {
|
|
481
|
+
logger_1.logger.error(console_log_colors_1.color.red("No matching InitiatedValidatorRemoval event found for the provided NodeIDs, verify the transaction hash and NodeIDs."));
|
|
482
|
+
process.exit(1);
|
|
483
|
+
}
|
|
484
|
+
const warpLogs = (0, viem_1.parseEventLogs)({
|
|
485
|
+
abi: config.abis.IWarpMessenger,
|
|
486
|
+
logs: receipt.logs,
|
|
487
|
+
});
|
|
488
|
+
const subnetIDHex = await validatorManager.read.subnetID();
|
|
489
|
+
const subnetID = avalanchejs_1.utils.base58check.encode((0, viem_1.hexToBytes)(subnetIDHex));
|
|
490
|
+
const currentValidators = await (0, pChainUtils_1.getCurrentValidators)(client, subnetID);
|
|
491
|
+
for (const event of filteredRemovals) {
|
|
492
|
+
const eventIndex = filteredRemovals.indexOf(event);
|
|
493
|
+
const validationID = event.args.validationID;
|
|
494
|
+
// Get nodeID from validator - ValidatorManager InitiatedValidatorRemoval doesn't include nodeID
|
|
495
|
+
const validator = await validatorManager.read.getValidator([validationID]);
|
|
496
|
+
const nodeID = (0, utils_1.encodeNodeID)(validator.nodeID);
|
|
497
|
+
logger_1.logger.log(`Processing removal for node ${nodeID}`);
|
|
498
|
+
// Find the corresponding warp log
|
|
499
|
+
// ValidatorManager InitiatedValidatorRemoval event has validatorWeightMessageID field
|
|
500
|
+
const warpLog = warpLogs.find((w) => {
|
|
501
|
+
// Match by messageID - ValidatorManager event has validatorWeightMessageID
|
|
502
|
+
return w.args.messageID === event.args.validatorWeightMessageID;
|
|
503
|
+
});
|
|
504
|
+
if (!warpLog) {
|
|
505
|
+
logger_1.logger.error(console_log_colors_1.color.red(`No matching warp log found for validationID ${validationID}`));
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
const signingSubnetId = await (0, warpUtils_1.getSigningSubnetIdFromWarpMessage)(client, warpLog.args.message);
|
|
509
|
+
let addNodeBlockNumber = receipt.blockNumber;
|
|
510
|
+
if (initiateTxHash && initiateTxHash.length > eventIndex) {
|
|
511
|
+
const addNodeReceipt = await client.waitForTransactionReceipt({ hash: initiateTxHash[eventIndex], confirmations: 0 });
|
|
512
|
+
if (addNodeReceipt.status === 'reverted')
|
|
513
|
+
throw new Error(`Transaction ${initiateTxHash[eventIndex]} reverted, pls use another initiate tx`);
|
|
514
|
+
addNodeBlockNumber = addNodeReceipt.blockNumber;
|
|
515
|
+
}
|
|
516
|
+
// Check if the node is still registered as a validator on the P-Chain
|
|
517
|
+
const isValidator = currentValidators.some((v) => v.nodeID === nodeID);
|
|
518
|
+
if (!isValidator) {
|
|
519
|
+
logger_1.logger.log(console_log_colors_1.color.yellow("Node is not registered as a validator on the P-Chain."));
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
// Get the unsigned L1ValidatorWeightMessage with weight=0 generated by the ValidatorManager from the receipt
|
|
523
|
+
const unsignedL1ValidatorWeightMessage = warpLog.args.message;
|
|
524
|
+
// Aggregate signatures from validators
|
|
525
|
+
const signedL1ValidatorWeightMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedL1ValidatorWeightMessage, signingSubnetId });
|
|
526
|
+
logger_1.logger.log("Aggregated signatures for the L1ValidatorWeightMessage from the Validator Manager chain");
|
|
527
|
+
// Call setValidatorWeight on the P-Chain with the signed L1ValidatorWeightMessage
|
|
528
|
+
(0, ts_belt_1.pipe)(await (0, pChainUtils_1.setValidatorWeight)({
|
|
529
|
+
client: pchainClient,
|
|
530
|
+
validationID: validationID,
|
|
531
|
+
message: signedL1ValidatorWeightMessage
|
|
532
|
+
}), ts_belt_1.R.tapError((error) => {
|
|
533
|
+
throw new Error("SetL1ValidatorWeightTx failed on P-Chain: " + error + '\n');
|
|
534
|
+
}), ts_belt_1.R.tap((txId) => {
|
|
535
|
+
logger_1.logger.log("SetL1ValidatorWeightTx executed on P-Chain: " + txId);
|
|
536
|
+
}));
|
|
537
|
+
}
|
|
538
|
+
// Get justification for original register validator tx
|
|
539
|
+
const justification = await (0, justification_1.GetRegistrationJustification)(nodeID, validationID, subnetID, client, addNodeBlockNumber);
|
|
540
|
+
if (!justification) {
|
|
541
|
+
throw new Error("Justification not found for validator removal");
|
|
542
|
+
}
|
|
543
|
+
// Pack and sign the P-Chain warp message
|
|
544
|
+
const validationIDBytes = (0, viem_1.hexToBytes)(validationID);
|
|
545
|
+
const unsignedPChainWarpMsg = (0, warpUtils_1.packL1ValidatorRegistration)(validationIDBytes, false, client.network === 'fuji' ? 5 : 1, config_1.pChainChainID);
|
|
546
|
+
const unsignedPChainWarpMsgHex = (0, viem_1.bytesToHex)(unsignedPChainWarpMsg);
|
|
547
|
+
// Aggregate signatures from validators
|
|
548
|
+
const signedPChainMessage = await (0, warpUtils_1.collectSignatures)({ network: client.network, message: unsignedPChainWarpMsgHex, justification: (0, viem_1.bytesToHex)(justification), signingSubnetId });
|
|
549
|
+
logger_1.logger.log("Aggregated signatures for the L1ValidatorRegistrationMessage from the P-Chain");
|
|
550
|
+
// Convert the signed warp message to bytes and pack into access list
|
|
551
|
+
const signedPChainWarpMsgBytes = (0, viem_1.hexToBytes)(`0x${signedPChainMessage}`);
|
|
552
|
+
const accessList = (0, warpUtils_1.packWarpIntoAccessList)(signedPChainWarpMsgBytes);
|
|
553
|
+
// messageIndex is always 0 for KiteStakingManager
|
|
554
|
+
const messageIndex = 0;
|
|
555
|
+
// Execute completeValidatorRemoval transaction
|
|
556
|
+
logger_1.logger.log("Executing completeValidatorRemoval transaction...");
|
|
557
|
+
// Checking if the node was only in the vmc or also in the stakingManager
|
|
558
|
+
const completeHash = await kiteStakingManager.safeWrite.completeValidatorRemoval([messageIndex], {
|
|
559
|
+
account: client.account,
|
|
560
|
+
chain: null,
|
|
561
|
+
accessList
|
|
562
|
+
});
|
|
563
|
+
if (waitValidatorVisible) {
|
|
564
|
+
logger_1.logger.log("Waiting for the validator to be removed from the P-Chain (may take a while)...");
|
|
565
|
+
await (0, utils_1.retryWhileError)(async () => (await (0, pChainUtils_1.getCurrentValidators)(client, avalanchejs_1.utils.base58check.encode((0, viem_1.hexToBytes)(subnetIDHex)))).some((v) => v.nodeID === nodeID), 5000, 180000, (res) => res === false);
|
|
566
|
+
}
|
|
567
|
+
logger_1.logger.log("completeValidatorRemoval executed successfully, tx hash:", completeHash);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
async function submitUptimeProof(config, kiteStakingManager, rpcUrl, nodeId) {
|
|
571
|
+
const client = config.client;
|
|
572
|
+
const [uptimeBlockchainID, manager] = await kiteStakingManager.read.getStakingManagerSettings().then((settings) => [settings.uptimeBlockchainID, settings.manager]);
|
|
573
|
+
const warpNetworkID = client.network === 'fuji' ? 5 : 1;
|
|
574
|
+
const sourceChainID = avalanchejs_1.utils.base58check.encode((0, viem_1.hexToBytes)(uptimeBlockchainID));
|
|
575
|
+
logger_1.logger.log("\nGetting validation uptime message...");
|
|
576
|
+
const signedUptimeMessage = await (0, uptime_1.getValidationUptimeMessage)(client, rpcUrl, nodeId, warpNetworkID, sourceChainID);
|
|
577
|
+
// Ensure signedUptimeMessage has 0x prefix
|
|
578
|
+
const signedUptimeMessageHex = signedUptimeMessage.startsWith('0x') ? signedUptimeMessage : `0x${signedUptimeMessage}`;
|
|
579
|
+
// Pack both messages into separate access list objects
|
|
580
|
+
const uptimeAccessList = (0, warpUtils_1.packWarpIntoAccessList)((0, viem_1.hexToBytes)(signedUptimeMessageHex));
|
|
581
|
+
const validators = await (0, uptime_1.getCurrentValidatorsFromNode)(rpcUrl);
|
|
582
|
+
const validator = validators.find(v => v.nodeID === nodeId);
|
|
583
|
+
if (!validator)
|
|
584
|
+
throw new Error(`Validator with nodeID ${nodeId} not found in the current validator set`);
|
|
585
|
+
const txHash = await kiteStakingManager.write.submitUptimeProof([(0, utils_1.cb58ToHex)(validator.validationID), 0], { accessList: uptimeAccessList, chain: null });
|
|
586
|
+
logger_1.logger.log("submitUptimeProof done, tx hash:", txHash);
|
|
587
|
+
return txHash;
|
|
588
|
+
}
|
|
589
|
+
// ─── Info Aggregators ────────────────────────────────────────────────────────
|
|
590
|
+
const NANOS_PER_AVAX = 1000000000n;
|
|
591
|
+
function formatAvax(wei) {
|
|
592
|
+
const whole = wei / NANOS_PER_AVAX;
|
|
593
|
+
const frac = wei % NANOS_PER_AVAX;
|
|
594
|
+
return frac === 0n
|
|
595
|
+
? `${whole} AVAX`
|
|
596
|
+
: `${whole}.${frac.toString().padStart(9, '0').replace(/0+$/, '')} AVAX`;
|
|
597
|
+
}
|
|
598
|
+
function formatDuration(seconds) {
|
|
599
|
+
const s = Number(seconds);
|
|
600
|
+
if (s < 60)
|
|
601
|
+
return `${s}s`;
|
|
602
|
+
if (s < 3600)
|
|
603
|
+
return `${Math.floor(s / 60)}m ${s % 60}s`;
|
|
604
|
+
if (s < 86400)
|
|
605
|
+
return `${Math.floor(s / 3600)}h ${Math.floor((s % 3600) / 60)}m`;
|
|
606
|
+
return `${Math.floor(s / 86400)}d ${Math.floor((s % 86400) / 3600)}h`;
|
|
607
|
+
}
|
|
608
|
+
function formatTimestamp(ts) {
|
|
609
|
+
if (ts === 0n)
|
|
610
|
+
return 'never';
|
|
611
|
+
return new Date(Number(ts) * 1000).toISOString();
|
|
612
|
+
}
|
|
613
|
+
/** Aggregate all global-level information from KiteStakingManager */
|
|
614
|
+
async function getKiteStakingManagerInfo(kiteStakingManager) {
|
|
615
|
+
const [config, settings, rewardCalculator, rewardVault, owner, pendingOwner, bipsFactor, maxDelegationFeeBips, maxStakeMultiplierLimit,] = await Promise.all([
|
|
616
|
+
kiteStakingManager.read.getStakingConfig(),
|
|
617
|
+
kiteStakingManager.read.getStakingManagerSettings(),
|
|
618
|
+
kiteStakingManager.read.getRewardCalculator(),
|
|
619
|
+
kiteStakingManager.read.getRewardVault(),
|
|
620
|
+
kiteStakingManager.read.owner(),
|
|
621
|
+
kiteStakingManager.read.pendingOwner(),
|
|
622
|
+
kiteStakingManager.read.BIPS_CONVERSION_FACTOR(),
|
|
623
|
+
kiteStakingManager.read.MAXIMUM_DELEGATION_FEE_BIPS(),
|
|
624
|
+
kiteStakingManager.read.MAXIMUM_STAKE_MULTIPLIER_LIMIT(),
|
|
625
|
+
]);
|
|
626
|
+
return {
|
|
627
|
+
// Staking config
|
|
628
|
+
minimumStakeAmount: config[0].toString(),
|
|
629
|
+
maximumStakeAmount: config[1].toString(),
|
|
630
|
+
minimumStakeDuration: config[2].toString(),
|
|
631
|
+
minimumDelegationFeeBips: config[3].toString(),
|
|
632
|
+
maximumStakeMultiplier: config[4].toString(),
|
|
633
|
+
weightToValueFactor: config[5].toString(),
|
|
634
|
+
// Addresses
|
|
635
|
+
validatorManager: settings.manager,
|
|
636
|
+
rewardCalculator,
|
|
637
|
+
rewardVault,
|
|
638
|
+
uptimeBlockchainID: settings.uptimeBlockchainID,
|
|
639
|
+
// Ownership
|
|
640
|
+
owner,
|
|
641
|
+
pendingOwner,
|
|
642
|
+
// Protocol constants
|
|
643
|
+
BIPS_CONVERSION_FACTOR: bipsFactor,
|
|
644
|
+
MAXIMUM_DELEGATION_FEE_BIPS: maxDelegationFeeBips,
|
|
645
|
+
MAXIMUM_STAKE_MULTIPLIER_LIMIT: maxStakeMultiplierLimit,
|
|
646
|
+
// Human-readable summaries
|
|
647
|
+
formatted: {
|
|
648
|
+
minimumStakeAmount: formatAvax(config[0]),
|
|
649
|
+
maximumStakeAmount: formatAvax(config[1]),
|
|
650
|
+
minimumStakeDuration: formatDuration(config[2]),
|
|
651
|
+
minimumDelegationFeeBips: `${config[3] / 100}%`,
|
|
652
|
+
maximumStakeMultiplier: `${config[4]}x`,
|
|
653
|
+
},
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
/** Aggregate all information for a specific validator by validationID */
|
|
657
|
+
async function getValidatorFullInfo(kiteStakingManager, validationID) {
|
|
658
|
+
const [validator, pendingRewards, rewardInfo] = await Promise.all([
|
|
659
|
+
kiteStakingManager.read.getStakingValidator([validationID]),
|
|
660
|
+
kiteStakingManager.read.getValidatorPendingRewards([validationID]),
|
|
661
|
+
kiteStakingManager.read.getValidatorRewardInfo([validationID]),
|
|
662
|
+
]);
|
|
663
|
+
const [rewardRecipient, accruedRewards] = rewardInfo;
|
|
664
|
+
return {
|
|
665
|
+
validationID,
|
|
666
|
+
// PoS validator info
|
|
667
|
+
owner: validator.owner,
|
|
668
|
+
delegationFeeBips: validator.delegationFeeBips,
|
|
669
|
+
minStakeDuration: validator.minStakeDuration.toString(),
|
|
670
|
+
uptimeSeconds: validator.uptimeSeconds.toString(),
|
|
671
|
+
lastRewardClaimTime: validator.lastRewardClaimTime.toString(),
|
|
672
|
+
lastClaimUptimeSeconds: validator.lastClaimUptimeSeconds.toString(),
|
|
673
|
+
// Pending rewards
|
|
674
|
+
stakingReward: pendingRewards[0].toString(),
|
|
675
|
+
delegationFees: pendingRewards[1].toString(),
|
|
676
|
+
totalPendingReward: pendingRewards[2].toString(),
|
|
677
|
+
// Reward accounting
|
|
678
|
+
rewardRecipient,
|
|
679
|
+
accruedRewards: accruedRewards.toString(),
|
|
680
|
+
// Human-readable
|
|
681
|
+
formatted: {
|
|
682
|
+
delegationFeeBips: `${validator.delegationFeeBips / 100}%`,
|
|
683
|
+
minStakeDuration: formatDuration(validator.minStakeDuration),
|
|
684
|
+
uptime: formatDuration(validator.uptimeSeconds),
|
|
685
|
+
lastRewardClaimTime: formatTimestamp(validator.lastRewardClaimTime),
|
|
686
|
+
stakingReward: formatAvax(pendingRewards[0]),
|
|
687
|
+
delegationFees: formatAvax(pendingRewards[1]),
|
|
688
|
+
totalPendingReward: formatAvax(pendingRewards[2]),
|
|
689
|
+
accruedRewards: formatAvax(accruedRewards),
|
|
690
|
+
},
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
/** Aggregate all information for a specific delegator by delegationID */
|
|
694
|
+
async function getDelegatorFullInfo(kiteStakingManager, delegationID) {
|
|
695
|
+
const [delegator, pendingRewards, rewardInfo] = await Promise.all([
|
|
696
|
+
kiteStakingManager.read.getDelegatorInfo([delegationID]),
|
|
697
|
+
kiteStakingManager.read.getDelegatorPendingRewards([delegationID]),
|
|
698
|
+
kiteStakingManager.read.getDelegatorRewardInfo([delegationID]),
|
|
699
|
+
]);
|
|
700
|
+
const [rewardRecipient, accruedRewards] = rewardInfo;
|
|
701
|
+
return {
|
|
702
|
+
delegationID,
|
|
703
|
+
// Delegator info
|
|
704
|
+
status: delegator.status,
|
|
705
|
+
owner: delegator.owner,
|
|
706
|
+
validationID: delegator.validationID,
|
|
707
|
+
weight: delegator.weight.toString(),
|
|
708
|
+
startTime: delegator.startTime.toString(),
|
|
709
|
+
startingNonce: delegator.startingNonce.toString(),
|
|
710
|
+
endingNonce: delegator.endingNonce.toString(),
|
|
711
|
+
lastRewardClaimTime: delegator.lastRewardClaimTime.toString(),
|
|
712
|
+
lastClaimUptimeSeconds: delegator.lastClaimUptimeSeconds.toString(),
|
|
713
|
+
// Pending rewards
|
|
714
|
+
grossReward: pendingRewards[0].toString(),
|
|
715
|
+
validatorFee: pendingRewards[1].toString(),
|
|
716
|
+
netPendingReward: pendingRewards[2].toString(),
|
|
717
|
+
// Reward accounting
|
|
718
|
+
rewardRecipient,
|
|
719
|
+
accruedRewards: accruedRewards.toString(),
|
|
720
|
+
// Human-readable
|
|
721
|
+
formatted: {
|
|
722
|
+
startTime: formatTimestamp(delegator.startTime),
|
|
723
|
+
lastRewardClaimTime: formatTimestamp(delegator.lastRewardClaimTime),
|
|
724
|
+
grossReward: formatAvax(pendingRewards[0]),
|
|
725
|
+
validatorFee: formatAvax(pendingRewards[1]),
|
|
726
|
+
netPendingReward: formatAvax(pendingRewards[2]),
|
|
727
|
+
accruedRewards: formatAvax(accruedRewards),
|
|
728
|
+
},
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
//# sourceMappingURL=kiteStaking.js.map
|