@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.
Files changed (194) hide show
  1. package/LICENSE +96 -0
  2. package/README.md +1080 -0
  3. package/bin/cli.js +3 -0
  4. package/defaults/.env.anvil +4 -0
  5. package/defaults/.env.dexalot +7 -0
  6. package/defaults/.env.fuji +4 -0
  7. package/defaults/.env.kiteai +2 -0
  8. package/defaults/.env.mainnet +4 -0
  9. package/defaults/.env.template +10 -0
  10. package/dist/abis/AccessControl.d.ts +176 -0
  11. package/dist/abis/AccessControl.js +230 -0
  12. package/dist/abis/AccessControl.js.map +1 -0
  13. package/dist/abis/BalancerValidatorManager.d.ts +1121 -0
  14. package/dist/abis/BalancerValidatorManager.js +1469 -0
  15. package/dist/abis/BalancerValidatorManager.js.map +1 -0
  16. package/dist/abis/DefaultCollateral.d.ts +620 -0
  17. package/dist/abis/DefaultCollateral.js +811 -0
  18. package/dist/abis/DefaultCollateral.js.map +1 -0
  19. package/dist/abis/ERC20.d.ts +635 -0
  20. package/dist/abis/ERC20.js +831 -0
  21. package/dist/abis/ERC20.js.map +1 -0
  22. package/dist/abis/IWarpMessenger.d.ts +104 -0
  23. package/dist/abis/IWarpMessenger.js +139 -0
  24. package/dist/abis/IWarpMessenger.js.map +1 -0
  25. package/dist/abis/KiteStakingManager.d.ts +1459 -0
  26. package/dist/abis/KiteStakingManager.js +1886 -0
  27. package/dist/abis/KiteStakingManager.js.map +1 -0
  28. package/dist/abis/L1Middleware.d.ts +1712 -0
  29. package/dist/abis/L1Middleware.js +2242 -0
  30. package/dist/abis/L1Middleware.js.map +1 -0
  31. package/dist/abis/L1Registry.d.ts +415 -0
  32. package/dist/abis/L1Registry.js +544 -0
  33. package/dist/abis/L1Registry.js.map +1 -0
  34. package/dist/abis/L1RestakeDelegator.d.ts +865 -0
  35. package/dist/abis/L1RestakeDelegator.js +1118 -0
  36. package/dist/abis/L1RestakeDelegator.js.map +1 -0
  37. package/dist/abis/OperatorL1OptInService.d.ts +288 -0
  38. package/dist/abis/OperatorL1OptInService.js +374 -0
  39. package/dist/abis/OperatorL1OptInService.js.map +1 -0
  40. package/dist/abis/OperatorRegistry.d.ts +125 -0
  41. package/dist/abis/OperatorRegistry.js +166 -0
  42. package/dist/abis/OperatorRegistry.js.map +1 -0
  43. package/dist/abis/OperatorVaultOptInService.d.ts +288 -0
  44. package/dist/abis/OperatorVaultOptInService.js +374 -0
  45. package/dist/abis/OperatorVaultOptInService.js.map +1 -0
  46. package/dist/abis/Ownable.d.ts +59 -0
  47. package/dist/abis/Ownable.js +79 -0
  48. package/dist/abis/Ownable.js.map +1 -0
  49. package/dist/abis/PoASecurityModule.d.ts +225 -0
  50. package/dist/abis/PoASecurityModule.js +299 -0
  51. package/dist/abis/PoASecurityModule.js.map +1 -0
  52. package/dist/abis/RewardsNativeToken.d.ts +1334 -0
  53. package/dist/abis/RewardsNativeToken.js +1749 -0
  54. package/dist/abis/RewardsNativeToken.js.map +1 -0
  55. package/dist/abis/StakingVault.d.ts +2913 -0
  56. package/dist/abis/StakingVault.js +3780 -0
  57. package/dist/abis/StakingVault.js.map +1 -0
  58. package/dist/abis/StakingVaultOperations.d.ts +980 -0
  59. package/dist/abis/StakingVaultOperations.js +1270 -0
  60. package/dist/abis/StakingVaultOperations.js.map +1 -0
  61. package/dist/abis/UptimeTracker.d.ts +300 -0
  62. package/dist/abis/UptimeTracker.js +397 -0
  63. package/dist/abis/UptimeTracker.js.map +1 -0
  64. package/dist/abis/ValidatorManager.d.ts +842 -0
  65. package/dist/abis/ValidatorManager.js +1101 -0
  66. package/dist/abis/ValidatorManager.js.map +1 -0
  67. package/dist/abis/VaultFactory.d.ts +288 -0
  68. package/dist/abis/VaultFactory.js +378 -0
  69. package/dist/abis/VaultFactory.js.map +1 -0
  70. package/dist/abis/VaultManager.d.ts +519 -0
  71. package/dist/abis/VaultManager.js +678 -0
  72. package/dist/abis/VaultManager.js.map +1 -0
  73. package/dist/abis/VaultTokenized.d.ts +1626 -0
  74. package/dist/abis/VaultTokenized.js +2114 -0
  75. package/dist/abis/VaultTokenized.js.map +1 -0
  76. package/dist/abis/abi-selectors.json +700 -0
  77. package/dist/abis/index.d.ts +18356 -0
  78. package/dist/abis/index.js +58 -0
  79. package/dist/abis/index.js.map +1 -0
  80. package/dist/accessControl.d.ts +15 -0
  81. package/dist/accessControl.js +36 -0
  82. package/dist/accessControl.js.map +1 -0
  83. package/dist/balancer.d.ts +25 -0
  84. package/dist/balancer.js +42 -0
  85. package/dist/balancer.js.map +1 -0
  86. package/dist/cli.d.mts +1 -0
  87. package/dist/cli.d.ts +2 -0
  88. package/dist/cli.js +3183 -0
  89. package/dist/cli.js.map +1 -0
  90. package/dist/cli.mjs +31343 -0
  91. package/dist/cli.mjs.map +1 -0
  92. package/dist/client.d.ts +34 -0
  93. package/dist/client.js +76 -0
  94. package/dist/client.js.map +1 -0
  95. package/dist/config.d.ts +10 -0
  96. package/dist/config.js +63 -0
  97. package/dist/config.js.map +1 -0
  98. package/dist/delegator.d.ts +4 -0
  99. package/dist/delegator.js +16 -0
  100. package/dist/delegator.js.map +1 -0
  101. package/dist/index.d.mts +19770 -0
  102. package/dist/index.d.ts +7 -0
  103. package/dist/index.js +24 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/index.mjs +27451 -0
  106. package/dist/index.mjs.map +1 -0
  107. package/dist/keyStore.d.ts +3 -0
  108. package/dist/keyStore.js +105 -0
  109. package/dist/keyStore.js.map +1 -0
  110. package/dist/kiteStaking.d.ts +91 -0
  111. package/dist/kiteStaking.js +731 -0
  112. package/dist/kiteStaking.js.map +1 -0
  113. package/dist/l1.d.ts +5 -0
  114. package/dist/l1.js +22 -0
  115. package/dist/l1.js.map +1 -0
  116. package/dist/lib/autoCompletion.d.ts +3 -0
  117. package/dist/lib/autoCompletion.js +55 -0
  118. package/dist/lib/autoCompletion.js.map +1 -0
  119. package/dist/lib/cChainUtils.d.ts +42 -0
  120. package/dist/lib/cChainUtils.js +271 -0
  121. package/dist/lib/cChainUtils.js.map +1 -0
  122. package/dist/lib/castUtils.d.ts +18 -0
  123. package/dist/lib/castUtils.js +81 -0
  124. package/dist/lib/castUtils.js.map +1 -0
  125. package/dist/lib/chainList.d.ts +5 -0
  126. package/dist/lib/chainList.js +86 -0
  127. package/dist/lib/chainList.js.map +1 -0
  128. package/dist/lib/cliParser.d.ts +27 -0
  129. package/dist/lib/cliParser.js +167 -0
  130. package/dist/lib/cliParser.js.map +1 -0
  131. package/dist/lib/commandUtils.d.ts +13 -0
  132. package/dist/lib/commandUtils.js +38 -0
  133. package/dist/lib/commandUtils.js.map +1 -0
  134. package/dist/lib/coreWalletUtils.d.ts +3 -0
  135. package/dist/lib/coreWalletUtils.js +74 -0
  136. package/dist/lib/coreWalletUtils.js.map +1 -0
  137. package/dist/lib/justification.d.ts +90 -0
  138. package/dist/lib/justification.js +577 -0
  139. package/dist/lib/justification.js.map +1 -0
  140. package/dist/lib/ledgerUtils.d.ts +4 -0
  141. package/dist/lib/ledgerUtils.js +258 -0
  142. package/dist/lib/ledgerUtils.js.map +1 -0
  143. package/dist/lib/logger.d.ts +46 -0
  144. package/dist/lib/logger.js +226 -0
  145. package/dist/lib/logger.js.map +1 -0
  146. package/dist/lib/pChainUtils.d.ts +128 -0
  147. package/dist/lib/pChainUtils.js +436 -0
  148. package/dist/lib/pChainUtils.js.map +1 -0
  149. package/dist/lib/pass.d.ts +81 -0
  150. package/dist/lib/pass.js +353 -0
  151. package/dist/lib/pass.js.map +1 -0
  152. package/dist/lib/safeUtils.d.ts +25 -0
  153. package/dist/lib/safeUtils.js +93 -0
  154. package/dist/lib/safeUtils.js.map +1 -0
  155. package/dist/lib/transferUtils.d.ts +643 -0
  156. package/dist/lib/transferUtils.js +141 -0
  157. package/dist/lib/transferUtils.js.map +1 -0
  158. package/dist/lib/utils.d.ts +28 -0
  159. package/dist/lib/utils.js +166 -0
  160. package/dist/lib/utils.js.map +1 -0
  161. package/dist/lib/viemUtils.d.ts +80 -0
  162. package/dist/lib/viemUtils.js +317 -0
  163. package/dist/lib/viemUtils.js.map +1 -0
  164. package/dist/lib/warpUtils.d.ts +76 -0
  165. package/dist/lib/warpUtils.js +448 -0
  166. package/dist/lib/warpUtils.js.map +1 -0
  167. package/dist/middleware.d.ts +75 -0
  168. package/dist/middleware.js +430 -0
  169. package/dist/middleware.js.map +1 -0
  170. package/dist/operator.d.ts +4 -0
  171. package/dist/operator.js +22 -0
  172. package/dist/operator.js.map +1 -0
  173. package/dist/operatorOptIn.d.ts +8 -0
  174. package/dist/operatorOptIn.js +39 -0
  175. package/dist/operatorOptIn.js.map +1 -0
  176. package/dist/rewards.d.ts +116 -0
  177. package/dist/rewards.js +244 -0
  178. package/dist/rewards.js.map +1 -0
  179. package/dist/securityModule.d.ts +8 -0
  180. package/dist/securityModule.js +305 -0
  181. package/dist/securityModule.js.map +1 -0
  182. package/dist/stakingVault.d.ts +184 -0
  183. package/dist/stakingVault.js +1224 -0
  184. package/dist/stakingVault.js.map +1 -0
  185. package/dist/uptime.d.ts +54 -0
  186. package/dist/uptime.js +246 -0
  187. package/dist/uptime.js.map +1 -0
  188. package/dist/vault.d.ts +16 -0
  189. package/dist/vault.js +131 -0
  190. package/dist/vault.js.map +1 -0
  191. package/dist/vaultManager.d.ts +8 -0
  192. package/dist/vaultManager.js +40 -0
  193. package/dist/vaultManager.js.map +1 -0
  194. 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