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